From 7eb969bbc2f5aaf39705489d0a3e30c66e1fb999 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 4 Feb 2025 13:41:34 +0000 Subject: [PATCH 1/2] Apply lint rule @typescript-eslint/no-empty-object-type (#29159) * Apply lint rule @typescript-eslint/no-empty-object-type To avoid the footgun that is https://www.totaltypescript.com/the-empty-object-type-in-typescript Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .eslintrc.js | 10 ++++++-- playwright/pages/client.ts | 7 +++--- src/@types/diff-dom.d.ts | 1 + src/@types/matrix-js-sdk.d.ts | 5 ++-- src/@types/react.d.ts | 2 +- src/AddThreepid.ts | 1 + src/WorkerManager.ts | 2 +- src/autocomplete/QueryMatcher.ts | 4 ++-- .../structures/AutoHideScrollbar.tsx | 2 +- .../structures/NonUrgentToastContainer.tsx | 7 +++--- src/components/structures/ToastContainer.tsx | 5 ++-- .../auth/header/AuthHeaderProvider.tsx | 2 +- .../views/audio_messages/Waveform.tsx | 4 +--- .../auth/InteractiveAuthEntryComponents.tsx | 2 +- src/components/views/auth/Welcome.tsx | 5 ++-- .../views/elements/EditableItemList.tsx | 2 +- .../views/elements/StyledCheckbox.tsx | 4 +--- .../views/elements/StyledRadioButton.tsx | 4 +--- src/components/views/rooms/Autocomplete.tsx | 4 ++-- .../views/rooms/RoomBreadcrumbs.tsx | 8 +++---- .../rooms/wysiwyg_composer/hooks/utils.ts | 2 +- .../views/settings/CrossSigningPanel.tsx | 6 ++--- .../views/settings/CryptographyPanel.tsx | 7 +++--- .../views/settings/EventIndexPanel.tsx | 5 ++-- .../views/settings/FontScalingPanel.tsx | 7 +++--- .../views/settings/ImageSizePanel.tsx | 9 +++----- .../views/settings/Notifications.tsx | 11 ++++----- .../views/settings/SecureBackupPanel.tsx | 5 ++-- .../views/settings/SetIntegrationManager.tsx | 7 +++--- .../tabs/user/AppearanceUserSettingsTab.tsx | 7 +++--- .../tabs/user/HelpUserSettingsTab.tsx | 7 +++--- .../tabs/user/LabsUserSettingsTab.tsx | 5 ++-- .../tabs/user/MjolnirUserSettingsTab.tsx | 5 ++-- .../tabs/user/VoiceUserSettingsTab.tsx | 5 ++-- src/contexts/MatrixClientContext.tsx | 2 +- src/editor/autocomplete.ts | 4 ++-- src/hooks/useAccountData.ts | 4 ++-- src/stores/CallStore.ts | 4 ++-- src/stores/WidgetStore.ts | 6 ++--- .../RoomNotificationStateStore.ts | 6 ++--- src/stores/room-list/MessagePreviewStore.ts | 16 ++++++++----- src/stores/room-list/RoomListLayoutStore.ts | 5 ++-- src/stores/room-list/RoomListStore.ts | 8 ++----- src/stores/room-list/SlidingRoomListStore.ts | 8 ++----- src/stores/spaces/SpaceStore.ts | 5 ++-- src/stores/widgets/WidgetMessagingStore.ts | 3 ++- src/utils/MultiInviter.ts | 4 ++-- src/utils/PinningUtils.ts | 12 ++++++++-- src/utils/notifications.ts | 23 +++++++++++-------- src/utils/objects.ts | 16 ++++++------- src/vector/app.tsx | 3 ++- src/vector/init.tsx | 3 ++- src/vector/platform/IPCManager.ts | 2 +- .../tabs/user/LabsUserSettingsTab-test.tsx | 5 +--- .../tabs/user/SessionManagerTab-test.tsx | 5 ++-- test/unit-tests/hooks/useProfileInfo-test.tsx | 4 ++-- 56 files changed, 158 insertions(+), 159 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index f310384972b..892d7cdbb1e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -200,8 +200,13 @@ module.exports = { "@typescript-eslint/ban-ts-comment": "off", // We're okay with assertion errors when we ask for them "@typescript-eslint/no-non-null-assertion": "off", - // We do this sometimes to brand interfaces - "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-empty-object-type": [ + "error", + { + // We do this sometimes to brand interfaces + allowInterfaces: "with-single-extends", + }, + ], }, }, // temporary override for offending icon require files @@ -247,6 +252,7 @@ module.exports = { // We don't need super strict typing in test utilities "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-member-accessibility": "off", + "@typescript-eslint/no-empty-object-type": "off", // Jest/Playwright specific diff --git a/playwright/pages/client.ts b/playwright/pages/client.ts index 611a6cef190..d1ce3709d3f 100644 --- a/playwright/pages/client.ts +++ b/playwright/pages/client.ts @@ -25,6 +25,7 @@ import type { StateEvents, TimelineEvents, AccountDataEvents, + EmptyObject, } from "matrix-js-sdk/src/matrix"; import type { RoomMessageEventContent } from "matrix-js-sdk/src/types"; import { Credentials } from "../plugins/homeserver"; @@ -363,7 +364,7 @@ export class Client { event: JSHandle, receiptType?: ReceiptType, unthreaded?: boolean, - ): Promise<{}> { + ): Promise { const client = await this.prepareClient(); return client.evaluate( (client, { event, receiptType, unthreaded }) => { @@ -386,7 +387,7 @@ export class Client { * @return {Promise} Resolves: {} an empty object. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async setDisplayName(name: string): Promise<{}> { + public async setDisplayName(name: string): Promise { const client = await this.prepareClient(); return client.evaluate(async (cli: MatrixClient, name) => cli.setDisplayName(name), name); } @@ -397,7 +398,7 @@ export class Client { * @return {Promise} Resolves: {} an empty object. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async setAvatarUrl(url: string): Promise<{}> { + public async setAvatarUrl(url: string): Promise { const client = await this.prepareClient(); return client.evaluate(async (cli: MatrixClient, url) => cli.setAvatarUrl(url), url); } diff --git a/src/@types/diff-dom.d.ts b/src/@types/diff-dom.d.ts index 986a84dc0b1..12587446d0b 100644 --- a/src/@types/diff-dom.d.ts +++ b/src/@types/diff-dom.d.ts @@ -18,6 +18,7 @@ declare module "diff-dom" { newValue: HTMLElement | string; } + // eslint-disable-next-line @typescript-eslint/no-empty-object-type interface IOpts {} export class DiffDOM { diff --git a/src/@types/matrix-js-sdk.d.ts b/src/@types/matrix-js-sdk.d.ts index 6ffa09dd4f8..92b76c4c4da 100644 --- a/src/@types/matrix-js-sdk.d.ts +++ b/src/@types/matrix-js-sdk.d.ts @@ -11,6 +11,7 @@ import type { BLURHASH_FIELD } from "../utils/image-media"; import type { JitsiCallMemberEventType, JitsiCallMemberContent } from "../call-types"; import type { ILayoutStateEvent, WIDGET_LAYOUT_EVENT_TYPE } from "../stores/widgets/types"; import type { EncryptedFile } from "matrix-js-sdk/src/types"; +import type { EmptyObject } from "matrix-js-sdk/src/matrix"; import type { DeviceClientInformation } from "../utils/device/types.ts"; import type { UserWidget } from "../utils/WidgetUtils-types.ts"; @@ -35,7 +36,7 @@ declare module "matrix-js-sdk/src/types" { [JitsiCallMemberEventType]: JitsiCallMemberContent; // Unstable widgets state events - "im.vector.modular.widgets": IWidget | {}; + "im.vector.modular.widgets": IWidget | EmptyObject; [WIDGET_LAYOUT_EVENT_TYPE]: ILayoutStateEvent; // Element custom state events @@ -104,6 +105,6 @@ declare module "matrix-js-sdk/src/types" { // https://github.com/matrix-org/matrix-doc/pull/3246 waveform?: number[]; }; - "org.matrix.msc3245.voice"?: {}; + "org.matrix.msc3245.voice"?: EmptyObject; } } diff --git a/src/@types/react.d.ts b/src/@types/react.d.ts index 2573bc0ab94..b1f6352adbf 100644 --- a/src/@types/react.d.ts +++ b/src/@types/react.d.ts @@ -10,7 +10,7 @@ import React, { PropsWithChildren } from "react"; declare module "react" { // Fix forwardRef types for Generic components - https://stackoverflow.com/a/58473012 - function forwardRef( + function forwardRef( render: (props: PropsWithChildren

, ref: React.ForwardedRef) => React.ReactElement | null, ): (props: P & React.RefAttributes) => React.ReactElement | null; diff --git a/src/AddThreepid.ts b/src/AddThreepid.ts index 757ea181805..10c28bfc4ae 100644 --- a/src/AddThreepid.ts +++ b/src/AddThreepid.ts @@ -249,6 +249,7 @@ export default class AddThreepid { * @param {{type: string, session?: string}} auth UI auth object * @return {Promise} Response from /3pid/add call (in current spec, an empty object) */ + // eslint-disable-next-line @typescript-eslint/no-empty-object-type private makeAddThreepidOnlyRequest = (auth?: IAddThreePidOnlyBody["auth"] | null): Promise<{}> => { return this.matrixClient.addThreePidOnly({ sid: this.sessionId!, diff --git a/src/WorkerManager.ts b/src/WorkerManager.ts index 089463dc915..f34d8dbfd18 100644 --- a/src/WorkerManager.ts +++ b/src/WorkerManager.ts @@ -10,7 +10,7 @@ import { defer, IDeferred } from "matrix-js-sdk/src/utils"; import { WorkerPayload } from "./workers/worker"; -export class WorkerManager { +export class WorkerManager { private readonly worker: Worker; private seq = 0; private pendingDeferredMap = new Map>(); diff --git a/src/autocomplete/QueryMatcher.ts b/src/autocomplete/QueryMatcher.ts index 985ca3a516d..d23bac21283 100644 --- a/src/autocomplete/QueryMatcher.ts +++ b/src/autocomplete/QueryMatcher.ts @@ -14,7 +14,7 @@ import { removeHiddenChars } from "matrix-js-sdk/src/utils"; import { TimelineRenderingType } from "../contexts/RoomContext"; import { Leaves } from "../@types/common"; -interface IOptions { +interface IOptions { keys: Array>; funcs?: Array<(o: T) => string | string[]>; shouldMatchWordsOnly?: boolean; @@ -37,7 +37,7 @@ interface IOptions { * @param {function[]} options.funcs List of functions that when called with the * object as an arg will return a string to use as an index */ -export default class QueryMatcher { +export default class QueryMatcher { private _options: IOptions; private _items = new Map(); diff --git a/src/components/structures/AutoHideScrollbar.tsx b/src/components/structures/AutoHideScrollbar.tsx index 764a712d442..da27f25cdba 100644 --- a/src/components/structures/AutoHideScrollbar.tsx +++ b/src/components/structures/AutoHideScrollbar.tsx @@ -11,7 +11,7 @@ import classNames from "classnames"; import React, { HTMLAttributes, ReactHTML, ReactNode, WheelEvent } from "react"; type DynamicHtmlElementProps = - JSX.IntrinsicElements[T] extends HTMLAttributes<{}> ? DynamicElementProps : DynamicElementProps<"div">; + JSX.IntrinsicElements[T] extends HTMLAttributes ? DynamicElementProps : DynamicElementProps<"div">; type DynamicElementProps = Partial>; export type IProps = Omit, "onScroll"> & { diff --git a/src/components/structures/NonUrgentToastContainer.tsx b/src/components/structures/NonUrgentToastContainer.tsx index aa445a54982..eac92f8af66 100644 --- a/src/components/structures/NonUrgentToastContainer.tsx +++ b/src/components/structures/NonUrgentToastContainer.tsx @@ -7,19 +7,18 @@ Please see LICENSE files in the repository root for full details. */ import * as React from "react"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { ComponentClass } from "../../@types/common"; import NonUrgentToastStore from "../../stores/NonUrgentToastStore"; import { UPDATE_EVENT } from "../../stores/AsyncStore"; -interface IProps {} - interface IState { toasts: ComponentClass[]; } -export default class NonUrgentToastContainer extends React.PureComponent { - public constructor(props: IProps) { +export default class NonUrgentToastContainer extends React.PureComponent { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/structures/ToastContainer.tsx b/src/components/structures/ToastContainer.tsx index 02db99a0e05..862e4150aac 100644 --- a/src/components/structures/ToastContainer.tsx +++ b/src/components/structures/ToastContainer.tsx @@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details. import * as React from "react"; import classNames from "classnames"; import { Text } from "@vector-im/compound-web"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import ToastStore, { IToast } from "../../stores/ToastStore"; @@ -17,8 +18,8 @@ interface IState { countSeen: number; } -export default class ToastContainer extends React.Component<{}, IState> { - public constructor(props: {}) { +export default class ToastContainer extends React.Component { + public constructor(props: EmptyObject) { super(props); this.state = { toasts: ToastStore.sharedInstance().getToasts(), diff --git a/src/components/structures/auth/header/AuthHeaderProvider.tsx b/src/components/structures/auth/header/AuthHeaderProvider.tsx index 0189b692124..4c4eb620983 100644 --- a/src/components/structures/auth/header/AuthHeaderProvider.tsx +++ b/src/components/structures/auth/header/AuthHeaderProvider.tsx @@ -24,7 +24,7 @@ interface AuthHeaderAction { export type AuthHeaderReducer = Reducer[], AuthHeaderAction>; -export function AuthHeaderProvider({ children }: PropsWithChildren<{}>): JSX.Element { +export function AuthHeaderProvider({ children }: PropsWithChildren): JSX.Element { const [state, dispatch] = useReducer( (state: ComponentProps[], action: AuthHeaderAction) => { switch (action.type) { diff --git a/src/components/views/audio_messages/Waveform.tsx b/src/components/views/audio_messages/Waveform.tsx index 83d02b81fd0..21106224031 100644 --- a/src/components/views/audio_messages/Waveform.tsx +++ b/src/components/views/audio_messages/Waveform.tsx @@ -18,8 +18,6 @@ interface IProps { progress: number; // percent complete, 0-1, default 100% } -interface IState {} - /** * A simple waveform component. This renders bars (centered vertically) for each * height provided in the component properties. Updating the properties will update @@ -28,7 +26,7 @@ interface IState {} * For CSS purposes, a mx_Waveform_bar_100pct class is added when the bar should be * "filled", as a demonstration of the progress property. */ -export default class Waveform extends React.PureComponent { +export default class Waveform extends React.PureComponent { public static defaultProps = { progress: 1, }; diff --git a/src/components/views/auth/InteractiveAuthEntryComponents.tsx b/src/components/views/auth/InteractiveAuthEntryComponents.tsx index 68ea886554a..92440dc2037 100644 --- a/src/components/views/auth/InteractiveAuthEntryComponents.tsx +++ b/src/components/views/auth/InteractiveAuthEntryComponents.tsx @@ -894,7 +894,7 @@ export class SSOAuthEntry extends React.Component extends React.Component { +export class FallbackAuthEntry extends React.Component { protected popupWindow: Window | null; protected fallbackButton = createRef(); diff --git a/src/components/views/auth/Welcome.tsx b/src/components/views/auth/Welcome.tsx index 39d5f95a8d1..dc7eb4ad40b 100644 --- a/src/components/views/auth/Welcome.tsx +++ b/src/components/views/auth/Welcome.tsx @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. import React from "react"; import classNames from "classnames"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import SdkConfig from "../../../SdkConfig"; import AuthPage from "./AuthPage"; @@ -16,9 +17,7 @@ import LanguageSelector from "./LanguageSelector"; import EmbeddedPage from "../../structures/EmbeddedPage"; import { MATRIX_LOGO_HTML } from "../../structures/static-page-vars"; -interface IProps {} - -export default class Welcome extends React.PureComponent { +export default class Welcome extends React.PureComponent { public render(): React.ReactNode { const pagesConfig = SdkConfig.getObject("embedded_pages"); let pageUrl: string | undefined; diff --git a/src/components/views/elements/EditableItemList.tsx b/src/components/views/elements/EditableItemList.tsx index 134c6151947..f08b65e24fd 100644 --- a/src/components/views/elements/EditableItemList.tsx +++ b/src/components/views/elements/EditableItemList.tsx @@ -101,7 +101,7 @@ interface IProps { onNewItemChanged?(item: string): void; } -export default class EditableItemList

extends React.PureComponent { +export default class EditableItemList

extends React.PureComponent { protected onItemAdded = (e: ButtonEvent): void => { e.stopPropagation(); e.preventDefault(); diff --git a/src/components/views/elements/StyledCheckbox.tsx b/src/components/views/elements/StyledCheckbox.tsx index 8e1905924a1..24458593417 100644 --- a/src/components/views/elements/StyledCheckbox.tsx +++ b/src/components/views/elements/StyledCheckbox.tsx @@ -21,9 +21,7 @@ interface IProps extends React.InputHTMLAttributes { id?: string; } -interface IState {} - -export default class StyledCheckbox extends React.PureComponent { +export default class StyledCheckbox extends React.PureComponent { private id: string; public static readonly defaultProps = { diff --git a/src/components/views/elements/StyledRadioButton.tsx b/src/components/views/elements/StyledRadioButton.tsx index 01e4de1dad8..caf40c7f1ad 100644 --- a/src/components/views/elements/StyledRadioButton.tsx +++ b/src/components/views/elements/StyledRadioButton.tsx @@ -18,9 +18,7 @@ interface IProps extends React.InputHTMLAttributes { childrenInLabel?: boolean; } -interface IState {} - -export default class StyledRadioButton extends React.PureComponent { +export default class StyledRadioButton extends React.PureComponent { public static readonly defaultProps = { className: "", childrenInLabel: true, diff --git a/src/components/views/rooms/Autocomplete.tsx b/src/components/views/rooms/Autocomplete.tsx index f77f394d8cc..33d3435dfc7 100644 --- a/src/components/views/rooms/Autocomplete.tsx +++ b/src/components/views/rooms/Autocomplete.tsx @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import React, { createRef, KeyboardEvent, RefObject } from "react"; +import React, { createRef, RefObject } from "react"; import classNames from "classnames"; import { flatMap } from "lodash"; import { Room } from "matrix-js-sdk/src/matrix"; @@ -206,7 +206,7 @@ export default class Autocomplete extends React.PureComponent { this.setSelection(1 + index); } - public onEscape(e: KeyboardEvent): boolean | undefined { + public onEscape(e: KeyboardEvent | React.KeyboardEvent): boolean | undefined { const completionCount = this.countCompletions(); if (completionCount === 0) { // autocomplete is already empty, so don't preventDefault diff --git a/src/components/views/rooms/RoomBreadcrumbs.tsx b/src/components/views/rooms/RoomBreadcrumbs.tsx index 40290358f54..ce87718197b 100644 --- a/src/components/views/rooms/RoomBreadcrumbs.tsx +++ b/src/components/views/rooms/RoomBreadcrumbs.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React, { createRef } from "react"; -import { Room } from "matrix-js-sdk/src/matrix"; +import { EmptyObject, Room } from "matrix-js-sdk/src/matrix"; import { CSSTransition } from "react-transition-group"; import { BreadcrumbsStore } from "../../../stores/BreadcrumbsStore"; @@ -21,8 +21,6 @@ import { Action } from "../../../dispatcher/actions"; import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton"; -interface IProps {} - interface IState { // Both of these control the animation for the breadcrumbs. For details on the // actual animation, see the CSS. @@ -59,11 +57,11 @@ const RoomBreadcrumbTile: React.FC<{ room: Room; onClick: (ev: ButtonEvent) => v ); }; -export default class RoomBreadcrumbs extends React.PureComponent { +export default class RoomBreadcrumbs extends React.PureComponent { private unmounted = false; private toolbar = createRef(); - public constructor(props: IProps) { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/views/rooms/wysiwyg_composer/hooks/utils.ts b/src/components/views/rooms/wysiwyg_composer/hooks/utils.ts index 52a61ac0e3d..48b73d352b9 100644 --- a/src/components/views/rooms/wysiwyg_composer/hooks/utils.ts +++ b/src/components/views/rooms/wysiwyg_composer/hooks/utils.ts @@ -92,7 +92,7 @@ export function handleEventWithAutocomplete( handled = true; break; case KeyBindingAction.CancelAutocomplete: - autocompleteRef.current.onEscape(event as {} as React.KeyboardEvent); + autocompleteRef.current.onEscape(event); handled = true; break; default: diff --git a/src/components/views/settings/CrossSigningPanel.tsx b/src/components/views/settings/CrossSigningPanel.tsx index 9ec9e9f6c18..5b7a39aad29 100644 --- a/src/components/views/settings/CrossSigningPanel.tsx +++ b/src/components/views/settings/CrossSigningPanel.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { ClientEvent, MatrixEvent } from "matrix-js-sdk/src/matrix"; +import { ClientEvent, EmptyObject, MatrixEvent } from "matrix-js-sdk/src/matrix"; import { logger } from "matrix-js-sdk/src/logger"; import { CryptoEvent } from "matrix-js-sdk/src/crypto-api"; @@ -33,10 +33,10 @@ interface IState { crossSigningReady?: boolean; } -export default class CrossSigningPanel extends React.PureComponent<{}, IState> { +export default class CrossSigningPanel extends React.PureComponent { private unmounted = false; - public constructor(props: {}) { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/views/settings/CryptographyPanel.tsx b/src/components/views/settings/CryptographyPanel.tsx index beb08ab1e92..d0cabf7af98 100644 --- a/src/components/views/settings/CryptographyPanel.tsx +++ b/src/components/views/settings/CryptographyPanel.tsx @@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details. import React, { lazy } from "react"; import { logger } from "matrix-js-sdk/src/logger"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../languageHandler"; import Modal from "../../../Modal"; @@ -19,8 +20,6 @@ import { SettingLevel } from "../../../settings/SettingLevel"; import { SettingsSubsection, SettingsSubsectionText } from "./shared/SettingsSubsection"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; -interface IProps {} - interface IState { /** The device's base64-encoded Ed25519 identity key, or: * @@ -30,11 +29,11 @@ interface IState { deviceIdentityKey: string | undefined | null; } -export default class CryptographyPanel extends React.Component { +export default class CryptographyPanel extends React.Component { public static contextType = MatrixClientContext; declare public context: React.ContextType; - public constructor(props: IProps, context: React.ContextType) { + public constructor(props: EmptyObject, context: React.ContextType) { super(props); if (!context.getCrypto()) { diff --git a/src/components/views/settings/EventIndexPanel.tsx b/src/components/views/settings/EventIndexPanel.tsx index 41845eb94ea..c314f72f38f 100644 --- a/src/components/views/settings/EventIndexPanel.tsx +++ b/src/components/views/settings/EventIndexPanel.tsx @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React, { lazy } from "react"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../languageHandler"; import SdkConfig from "../../../SdkConfig"; @@ -28,8 +29,8 @@ interface IState { eventIndexingEnabled: boolean; } -export default class EventIndexPanel extends React.Component<{}, IState> { - public constructor(props: {}) { +export default class EventIndexPanel extends React.Component { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/views/settings/FontScalingPanel.tsx b/src/components/views/settings/FontScalingPanel.tsx index e1a7f4902fe..f2f1d6a93bd 100644 --- a/src/components/views/settings/FontScalingPanel.tsx +++ b/src/components/views/settings/FontScalingPanel.tsx @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import EventTilePreview from "../elements/EventTilePreview"; import SettingsStore from "../../../settings/SettingsStore"; @@ -18,8 +19,6 @@ import { SettingsSubsection } from "./shared/SettingsSubsection"; import Field from "../elements/Field"; import { FontWatcher } from "../../../settings/watchers/FontWatcher"; -interface IProps {} - interface IState { browserFontSize: number; // String displaying the current selected fontSize. @@ -34,7 +33,7 @@ interface IState { avatarUrl?: string; } -export default class FontScalingPanel extends React.Component { +export default class FontScalingPanel extends React.Component { private readonly MESSAGE_PREVIEW_TEXT = _t("common|preview_message"); /** * Font sizes available (in px) @@ -43,7 +42,7 @@ export default class FontScalingPanel extends React.Component { private layoutWatcherRef?: string; private unmounted = false; - public constructor(props: IProps) { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/views/settings/ImageSizePanel.tsx b/src/components/views/settings/ImageSizePanel.tsx index 8079ea16543..cae714d002a 100644 --- a/src/components/views/settings/ImageSizePanel.tsx +++ b/src/components/views/settings/ImageSizePanel.tsx @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import SettingsStore from "../../../settings/SettingsStore"; import StyledRadioButton from "../elements/StyledRadioButton"; @@ -15,16 +16,12 @@ import { SettingLevel } from "../../../settings/SettingLevel"; import { ImageSize } from "../../../settings/enums/ImageSize"; import { SettingsSubsection } from "./shared/SettingsSubsection"; -interface IProps { - // none -} - interface IState { size: ImageSize; } -export default class ImageSizePanel extends React.Component { - public constructor(props: IProps) { +export default class ImageSizePanel extends React.Component { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/views/settings/Notifications.tsx b/src/components/views/settings/Notifications.tsx index 6cf4f8abea9..1b9d266a943 100644 --- a/src/components/views/settings/Notifications.tsx +++ b/src/components/views/settings/Notifications.tsx @@ -16,6 +16,7 @@ import { IThreepid, ThreepidMedium, LocalNotificationSettings, + EmptyObject, } from "matrix-js-sdk/src/matrix"; import { logger } from "matrix-js-sdk/src/logger"; @@ -108,8 +109,6 @@ interface IVectorPushRule { syncedVectorState?: VectorState; } -interface IProps {} - interface IState { phase: Phase; @@ -205,10 +204,10 @@ const NotificationActivitySettings = (): JSX.Element => { /** * The old, deprecated notifications tab view, only displayed if the user has the labs flag disabled. */ -export default class Notifications extends React.PureComponent { +export default class Notifications extends React.PureComponent { private settingWatchers: string[] = []; - public constructor(props: IProps) { + public constructor(props: EmptyObject) { super(props); this.state = { @@ -255,7 +254,7 @@ export default class Notifications extends React.PureComponent { this.settingWatchers.forEach((watcher) => SettingsStore.unwatchSetting(watcher)); } - public componentDidUpdate(prevProps: Readonly, prevState: Readonly): void { + public componentDidUpdate(prevProps: Readonly, prevState: Readonly): void { if (this.state.deviceNotificationsEnabled !== prevState.deviceNotificationsEnabled) { this.persistLocalNotificationSettings(this.state.deviceNotificationsEnabled); } @@ -291,7 +290,7 @@ export default class Notifications extends React.PureComponent { } } - private persistLocalNotificationSettings(enabled: boolean): Promise<{}> { + private persistLocalNotificationSettings(enabled: boolean): Promise { const cli = MatrixClientPeg.safeGet(); return cli.setAccountData(getLocalNotificationAccountDataEventType(cli.deviceId), { is_silenced: !enabled, diff --git a/src/components/views/settings/SecureBackupPanel.tsx b/src/components/views/settings/SecureBackupPanel.tsx index 3d245678320..722c3fe38f2 100644 --- a/src/components/views/settings/SecureBackupPanel.tsx +++ b/src/components/views/settings/SecureBackupPanel.tsx @@ -10,6 +10,7 @@ Please see LICENSE files in the repository root for full details. import React, { lazy, ReactNode } from "react"; import { CryptoEvent, BackupTrustInfo, KeyBackupInfo } from "matrix-js-sdk/src/crypto-api"; import { logger } from "matrix-js-sdk/src/logger"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { _t } from "../../../languageHandler"; @@ -60,10 +61,10 @@ interface IState { sessionsRemaining: number | null; } -export default class SecureBackupPanel extends React.PureComponent<{}, IState> { +export default class SecureBackupPanel extends React.PureComponent { private unmounted = false; - public constructor(props: {}) { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/views/settings/SetIntegrationManager.tsx b/src/components/views/settings/SetIntegrationManager.tsx index 01dab795470..fbf9ff710f8 100644 --- a/src/components/views/settings/SetIntegrationManager.tsx +++ b/src/components/views/settings/SetIntegrationManager.tsx @@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details. import React from "react"; import { logger } from "matrix-js-sdk/src/logger"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../languageHandler"; import { IntegrationManagers } from "../../../integrations/IntegrationManagers"; @@ -19,15 +20,13 @@ import Heading from "../typography/Heading"; import { SettingsSubsectionText } from "./shared/SettingsSubsection"; import { UIFeature } from "../../../settings/UIFeature"; -interface IProps {} - interface IState { currentManager: IntegrationManagerInstance | null; provisioningEnabled: boolean; } -export default class SetIntegrationManager extends React.Component { - public constructor(props: IProps) { +export default class SetIntegrationManager extends React.Component { + public constructor(props: EmptyObject) { super(props); const currentManager = IntegrationManagers.sharedInstance().getPrimaryManager(); diff --git a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx index 4586191db14..8720c55a916 100644 --- a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx @@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details. */ import React, { ChangeEvent, ReactNode } from "react"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../../../languageHandler"; import SdkConfig from "../../../../../SdkConfig"; @@ -25,8 +26,6 @@ import SettingsTab from "../SettingsTab"; import { SettingsSection } from "../../shared/SettingsSection"; import { SettingsSubsection } from "../../shared/SettingsSubsection"; -interface IProps {} - interface IState { useBundledEmojiFont: boolean; useSystemFont: boolean; @@ -34,8 +33,8 @@ interface IState { showAdvanced: boolean; } -export default class AppearanceUserSettingsTab extends React.Component { - public constructor(props: IProps) { +export default class AppearanceUserSettingsTab extends React.Component { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx index d28c820d206..1d248754823 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx @@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details. import React, { ReactNode } from "react"; import { logger } from "matrix-js-sdk/src/logger"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import AccessibleButton from "../../../elements/AccessibleButton"; import { _t } from "../../../../../languageHandler"; @@ -23,18 +24,16 @@ import { SettingsSubsection, SettingsSubsectionText } from "../../shared/Setting import ExternalLink from "../../../elements/ExternalLink"; import MatrixClientContext from "../../../../../contexts/MatrixClientContext"; -interface IProps {} - interface IState { appVersion: string | null; canUpdate: boolean; } -export default class HelpUserSettingsTab extends React.Component { +export default class HelpUserSettingsTab extends React.Component { public static contextType = MatrixClientContext; declare public context: React.ContextType; - public constructor(props: IProps, context: React.ContextType) { + public constructor(props: EmptyObject, context: React.ContextType) { super(props, context); this.state = { diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx b/src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx index 5cee63b48e4..140b599b4a1 100644 --- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. import React from "react"; import { sortBy } from "lodash"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../../../languageHandler"; import SettingsStore from "../../../../../settings/SettingsStore"; @@ -24,11 +25,11 @@ export const showLabsFlags = (): boolean => { return SdkConfig.get("show_labs_settings") || SettingsStore.getValue("developerMode"); }; -export default class LabsUserSettingsTab extends React.Component<{}> { +export default class LabsUserSettingsTab extends React.Component { private readonly labs: FeatureSettingKey[]; private readonly betas: FeatureSettingKey[]; - public constructor(props: {}) { + public constructor(props: EmptyObject) { super(props); const features = SettingsStore.getFeatureSettingNames(); diff --git a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.tsx b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.tsx index 9b71244e554..b0fa4e0fc23 100644 --- a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.tsx @@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details. import React, { ChangeEvent, SyntheticEvent } from "react"; import { logger } from "matrix-js-sdk/src/logger"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../../../languageHandler"; import SdkConfig from "../../../../../SdkConfig"; @@ -30,8 +31,8 @@ interface IState { newList: string; } -export default class MjolnirUserSettingsTab extends React.Component<{}, IState> { - public constructor(props: {}) { +export default class MjolnirUserSettingsTab extends React.Component { + public constructor(props: EmptyObject) { super(props); this.state = { diff --git a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx index a52a232cd5f..739bf3dea1c 100644 --- a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx @@ -10,6 +10,7 @@ Please see LICENSE files in the repository root for full details. import React, { ReactNode } from "react"; import { logger } from "matrix-js-sdk/src/logger"; import { FALLBACK_ICE_SERVER } from "matrix-js-sdk/src/webrtc/call"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../../../languageHandler"; import MediaDeviceHandler, { IMediaDevices, MediaDeviceKindEnum } from "../../../../../MediaDeviceHandler"; @@ -49,11 +50,11 @@ const mapDeviceKindToHandlerValue = (deviceKind: MediaDeviceKindEnum): string | } }; -export default class VoiceUserSettingsTab extends React.Component<{}, IState> { +export default class VoiceUserSettingsTab extends React.Component { public static contextType = MatrixClientContext; declare public context: React.ContextType; - public constructor(props: {}, context: React.ContextType) { + public constructor(props: EmptyObject, context: React.ContextType) { super(props, context); this.state = { diff --git a/src/contexts/MatrixClientContext.tsx b/src/contexts/MatrixClientContext.tsx index 79ce5e50094..3401330379c 100644 --- a/src/contexts/MatrixClientContext.tsx +++ b/src/contexts/MatrixClientContext.tsx @@ -24,7 +24,7 @@ export function useMatrixClientContext(): MatrixClient { return useContext(MatrixClientContext); } -const matrixHOC = ( +const matrixHOC = ( ComposedComponent: ComponentClass, ): (( props: Omit & React.RefAttributes>, diff --git a/src/editor/autocomplete.ts b/src/editor/autocomplete.ts index ff1e89b1f16..abbea0254e5 100644 --- a/src/editor/autocomplete.ts +++ b/src/editor/autocomplete.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { KeyboardEvent } from "react"; +import React from "react"; import { Part, CommandPartCreator, PartCreator } from "./parts"; import DocumentPosition from "./position"; @@ -33,7 +33,7 @@ export default class AutocompleteWrapperModel { private partCreator: PartCreator | CommandPartCreator, ) {} - public onEscape(e: KeyboardEvent): void { + public onEscape(e: KeyboardEvent | React.KeyboardEvent): void { this.getAutocompleterComponent()?.onEscape(e); } diff --git a/src/hooks/useAccountData.ts b/src/hooks/useAccountData.ts index 7cbc77d525f..a86f8765fe3 100644 --- a/src/hooks/useAccountData.ts +++ b/src/hooks/useAccountData.ts @@ -11,10 +11,10 @@ import { AccountDataEvents, ClientEvent, MatrixClient, MatrixEvent } from "matri import { useTypedEventEmitter } from "./useEventEmitter"; -const tryGetContent = (ev?: MatrixEvent): T | undefined => ev?.getContent(); +const tryGetContent = (ev?: MatrixEvent): T | undefined => ev?.getContent(); // Hook to simplify listening to Matrix account data -export const useAccountData = (cli: MatrixClient, eventType: keyof AccountDataEvents): T => { +export const useAccountData = (cli: MatrixClient, eventType: keyof AccountDataEvents): T => { const [value, setValue] = useState(() => tryGetContent(cli.getAccountData(eventType))); const handler = useCallback( diff --git a/src/stores/CallStore.ts b/src/stores/CallStore.ts index d667e0b811b..0d950eecced 100644 --- a/src/stores/CallStore.ts +++ b/src/stores/CallStore.ts @@ -10,7 +10,7 @@ import { logger } from "matrix-js-sdk/src/logger"; import { GroupCallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/groupCallEventHandler"; import { MatrixRTCSession, MatrixRTCSessionManagerEvents } from "matrix-js-sdk/src/matrixrtc"; -import type { GroupCall, Room } from "matrix-js-sdk/src/matrix"; +import type { EmptyObject, GroupCall, Room } from "matrix-js-sdk/src/matrix"; import defaultDispatcher from "../dispatcher/dispatcher"; import { UPDATE_EVENT } from "./AsyncStore"; import { AsyncStoreWithClient } from "./AsyncStoreWithClient"; @@ -26,7 +26,7 @@ export enum CallStoreEvent { ConnectedCalls = "connected_calls", } -export class CallStore extends AsyncStoreWithClient<{}> { +export class CallStore extends AsyncStoreWithClient { private static _instance: CallStore; public static get instance(): CallStore { if (!this._instance) { diff --git a/src/stores/WidgetStore.ts b/src/stores/WidgetStore.ts index 8c697709303..a715a97c1ea 100644 --- a/src/stores/WidgetStore.ts +++ b/src/stores/WidgetStore.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { Room, RoomStateEvent, MatrixEvent, ClientEvent } from "matrix-js-sdk/src/matrix"; +import { Room, RoomStateEvent, MatrixEvent, ClientEvent, EmptyObject } from "matrix-js-sdk/src/matrix"; import { IWidget } from "matrix-widget-api"; import { logger } from "matrix-js-sdk/src/logger"; @@ -19,8 +19,6 @@ import WidgetUtils from "../utils/WidgetUtils"; import { UPDATE_EVENT } from "./AsyncStore"; import { IApp } from "../utils/WidgetUtils-types"; -interface IState {} - export type { IApp }; export function isAppWidget(widget: IWidget | IApp): widget is IApp { @@ -36,7 +34,7 @@ interface IRoomWidgets { // TODO consolidate WidgetEchoStore into this // TODO consolidate ActiveWidgetStore into this -export default class WidgetStore extends AsyncStoreWithClient { +export default class WidgetStore extends AsyncStoreWithClient { private static readonly internalInstance = (() => { const instance = new WidgetStore(); instance.start(); diff --git a/src/stores/notifications/RoomNotificationStateStore.ts b/src/stores/notifications/RoomNotificationStateStore.ts index c58125b0bab..4fa51128be9 100644 --- a/src/stores/notifications/RoomNotificationStateStore.ts +++ b/src/stores/notifications/RoomNotificationStateStore.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { Room, ClientEvent, SyncState } from "matrix-js-sdk/src/matrix"; +import { Room, ClientEvent, SyncState, EmptyObject } from "matrix-js-sdk/src/matrix"; import { ActionPayload } from "../../dispatcher/payloads"; import { AsyncStoreWithClient } from "../AsyncStoreWithClient"; @@ -19,11 +19,9 @@ import { VisibilityProvider } from "../room-list/filters/VisibilityProvider"; import { PosthogAnalytics } from "../../PosthogAnalytics"; import SettingsStore from "../../settings/SettingsStore"; -interface IState {} - export const UPDATE_STATUS_INDICATOR = Symbol("update-status-indicator"); -export class RoomNotificationStateStore extends AsyncStoreWithClient { +export class RoomNotificationStateStore extends AsyncStoreWithClient { private static readonly internalInstance = (() => { const instance = new RoomNotificationStateStore(); instance.start(); diff --git a/src/stores/room-list/MessagePreviewStore.ts b/src/stores/room-list/MessagePreviewStore.ts index 3f1614df702..fe2d56871d4 100644 --- a/src/stores/room-list/MessagePreviewStore.ts +++ b/src/stores/room-list/MessagePreviewStore.ts @@ -6,7 +6,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { Room, RelationType, MatrixEvent, Thread, M_POLL_START, RoomEvent } from "matrix-js-sdk/src/matrix"; +import { + Room, + RelationType, + MatrixEvent, + Thread, + M_POLL_START, + RoomEvent, + EmptyObject, +} from "matrix-js-sdk/src/matrix"; import { isNullOrUndefined } from "matrix-js-sdk/src/utils"; import { ActionPayload } from "../../dispatcher/payloads"; @@ -76,10 +84,6 @@ const MAX_EVENTS_BACKWARDS = 50; type TAG_ANY = "im.vector.any"; // eslint-disable-line @typescript-eslint/naming-convention const TAG_ANY: TAG_ANY = "im.vector.any"; -interface IState { - // Empty because we don't actually use the state -} - export interface MessagePreview { event: MatrixEvent; isThreadReply: boolean; @@ -117,7 +121,7 @@ const mkMessagePreview = (text: string, event: MatrixEvent): MessagePreview => { }; }; -export class MessagePreviewStore extends AsyncStoreWithClient { +export class MessagePreviewStore extends AsyncStoreWithClient { private static readonly internalInstance = (() => { const instance = new MessagePreviewStore(); instance.start(); diff --git a/src/stores/room-list/RoomListLayoutStore.ts b/src/stores/room-list/RoomListLayoutStore.ts index 90461a581c0..f739554b824 100644 --- a/src/stores/room-list/RoomListLayoutStore.ts +++ b/src/stores/room-list/RoomListLayoutStore.ts @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import { logger } from "matrix-js-sdk/src/logger"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { TagID } from "./models"; import { ListLayout } from "./ListLayout"; @@ -14,9 +15,7 @@ import { AsyncStoreWithClient } from "../AsyncStoreWithClient"; import defaultDispatcher from "../../dispatcher/dispatcher"; import { ActionPayload } from "../../dispatcher/payloads"; -interface IState {} - -export default class RoomListLayoutStore extends AsyncStoreWithClient { +export default class RoomListLayoutStore extends AsyncStoreWithClient { private static internalInstance: RoomListLayoutStore; private readonly layoutMap = new Map(); diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index 0b179f7db54..bb48ec5e188 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { MatrixClient, Room, RoomState, EventType } from "matrix-js-sdk/src/matrix"; +import { MatrixClient, Room, RoomState, EventType, EmptyObject } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; import { logger } from "matrix-js-sdk/src/logger"; @@ -32,14 +32,10 @@ import { UPDATE_EVENT } from "../AsyncStore"; import { SdkContextClass } from "../../contexts/SDKContext"; import { getChangedOverrideRoomMutePushRules } from "./utils/roomMute"; -interface IState { - // state is tracked in underlying classes -} - export const LISTS_UPDATE_EVENT = RoomListStoreEvent.ListsUpdate; export const LISTS_LOADING_EVENT = RoomListStoreEvent.ListsLoading; // unused; used by SlidingRoomListStore -export class RoomListStoreClass extends AsyncStoreWithClient implements Interface { +export class RoomListStoreClass extends AsyncStoreWithClient implements Interface { /** * Set to true if you're running tests on the store. Should not be touched in * any other environment. diff --git a/src/stores/room-list/SlidingRoomListStore.ts b/src/stores/room-list/SlidingRoomListStore.ts index ba585f32181..626ac5dc6ab 100644 --- a/src/stores/room-list/SlidingRoomListStore.ts +++ b/src/stores/room-list/SlidingRoomListStore.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { Room } from "matrix-js-sdk/src/matrix"; +import { EmptyObject, Room } from "matrix-js-sdk/src/matrix"; import { logger } from "matrix-js-sdk/src/logger"; import { MSC3575Filter, SlidingSyncEvent } from "matrix-js-sdk/src/sliding-sync"; import { Optional } from "matrix-events-sdk"; @@ -23,10 +23,6 @@ import { LISTS_LOADING_EVENT } from "./RoomListStore"; import { UPDATE_EVENT } from "../AsyncStore"; import { SdkContextClass } from "../../contexts/SDKContext"; -interface IState { - // state is tracked in underlying classes -} - export const SlidingSyncSortToFilter: Record = { [SortAlgorithm.Alphabetic]: ["by_name", "by_recency"], [SortAlgorithm.Recent]: ["by_notification_level", "by_recency"], @@ -66,7 +62,7 @@ const filterConditions: Record = { export const LISTS_UPDATE_EVENT = RoomListStoreEvent.ListsUpdate; -export class SlidingRoomListStoreClass extends AsyncStoreWithClient implements Interface { +export class SlidingRoomListStoreClass extends AsyncStoreWithClient implements Interface { private tagIdToSortAlgo: Record = {}; private tagMap: ITagMap = {}; private counts: Record = {}; diff --git a/src/stores/spaces/SpaceStore.ts b/src/stores/spaces/SpaceStore.ts index 50aa7748a55..9ee877ec3f6 100644 --- a/src/stores/spaces/SpaceStore.ts +++ b/src/stores/spaces/SpaceStore.ts @@ -17,6 +17,7 @@ import { MatrixEvent, ClientEvent, ISendEventResponse, + EmptyObject, } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; import { logger } from "matrix-js-sdk/src/logger"; @@ -63,8 +64,6 @@ import { SwitchSpacePayload } from "../../dispatcher/payloads/SwitchSpacePayload import { AfterLeaveRoomPayload } from "../../dispatcher/payloads/AfterLeaveRoomPayload"; import { SdkContextClass } from "../../contexts/SDKContext"; -interface IState {} - const ACTIVE_SPACE_LS_KEY = "mx_active_space"; const metaSpaceOrder: MetaSpace[] = [ @@ -123,7 +122,7 @@ type SpaceStoreActions = | SwitchSpacePayload | AfterLeaveRoomPayload; -export class SpaceStoreClass extends AsyncStoreWithClient { +export class SpaceStoreClass extends AsyncStoreWithClient { // The spaces representing the roots of the various tree-like hierarchies private rootSpaces: Room[] = []; // Map from room/space ID to set of spaces which list it as a child diff --git a/src/stores/widgets/WidgetMessagingStore.ts b/src/stores/widgets/WidgetMessagingStore.ts index f73fd15c513..d42c499226f 100644 --- a/src/stores/widgets/WidgetMessagingStore.ts +++ b/src/stores/widgets/WidgetMessagingStore.ts @@ -7,6 +7,7 @@ */ import { ClientWidgetApi, Widget } from "matrix-widget-api"; +import { EmptyObject } from "matrix-js-sdk/src/matrix"; import { AsyncStoreWithClient } from "../AsyncStoreWithClient"; import defaultDispatcher from "../../dispatcher/dispatcher"; @@ -24,7 +25,7 @@ export enum WidgetMessagingStoreEvent { * going to be merged with a more complete WidgetStore, but for now it's * easiest to split this into a single place. */ -export class WidgetMessagingStore extends AsyncStoreWithClient<{}> { +export class WidgetMessagingStore extends AsyncStoreWithClient { private static readonly internalInstance = (() => { const instance = new WidgetMessagingStore(); instance.start(); diff --git a/src/utils/MultiInviter.ts b/src/utils/MultiInviter.ts index 1350eb94a43..c42284db45b 100644 --- a/src/utils/MultiInviter.ts +++ b/src/utils/MultiInviter.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { MatrixError, MatrixClient, EventType } from "matrix-js-sdk/src/matrix"; +import { MatrixError, MatrixClient, EventType, EmptyObject } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; import { defer, IDeferred } from "matrix-js-sdk/src/utils"; import { logger } from "matrix-js-sdk/src/logger"; @@ -117,7 +117,7 @@ export default class MultiInviter { return this.errors[addr]?.errorText ?? null; } - private async inviteToRoom(roomId: string, addr: string, ignoreProfile = false): Promise<{}> { + private async inviteToRoom(roomId: string, addr: string, ignoreProfile = false): Promise { const addrType = getAddressType(addr); if (addrType === AddressType.Email) { diff --git a/src/utils/PinningUtils.ts b/src/utils/PinningUtils.ts index a1304598f7c..40ab66160d7 100644 --- a/src/utils/PinningUtils.ts +++ b/src/utils/PinningUtils.ts @@ -6,7 +6,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { MatrixEvent, EventType, M_POLL_START, MatrixClient, EventTimeline, Room } from "matrix-js-sdk/src/matrix"; +import { + MatrixEvent, + EventType, + M_POLL_START, + MatrixClient, + EventTimeline, + Room, + EmptyObject, +} from "matrix-js-sdk/src/matrix"; import { isContentActionable } from "./EventUtils"; import { ReadPinsEventId } from "../components/views/right_panel/types"; @@ -123,7 +131,7 @@ export default class PinningUtils { ?.getStateEvents(EventType.RoomPinnedEvents, "") ?.getContent().pinned || []; - let roomAccountDataPromise: Promise<{} | void> = Promise.resolve(); + let roomAccountDataPromise: Promise = Promise.resolve(); // If the event is already pinned, unpin it if (pinnedIds.includes(eventId)) { pinnedIds.splice(pinnedIds.indexOf(eventId), 1); diff --git a/src/utils/notifications.ts b/src/utils/notifications.ts index 9119ef9bcb7..d0dfa8ffa6b 100644 --- a/src/utils/notifications.ts +++ b/src/utils/notifications.ts @@ -14,6 +14,7 @@ import { LocalNotificationSettings, ReceiptType, IMarkedUnreadEvent, + EmptyObject, } from "matrix-js-sdk/src/matrix"; import { IndicatorIcon } from "@vector-im/compound-web"; @@ -80,7 +81,7 @@ export function localNotificationsAreSilenced(cli: MatrixClient): boolean { * @param client * @returns a promise that resolves when the room has been marked as read */ -export async function clearRoomNotification(room: Room, client: MatrixClient): Promise<{} | undefined> { +export async function clearRoomNotification(room: Room, client: MatrixClient): Promise { const lastEvent = room.getLastLiveEvent(); await setMarkedUnreadState(room, client, false); @@ -115,15 +116,17 @@ export async function clearRoomNotification(room: Room, client: MatrixClient): P * @param client The matrix client * @returns a promise that resolves when all rooms have been marked as read */ -export function clearAllNotifications(client: MatrixClient): Promise> { - const receiptPromises = client.getRooms().reduce((promises: Array>, room: Room) => { - if (doesRoomHaveUnreadMessages(room, true)) { - const promise = clearRoomNotification(room, client); - promises.push(promise); - } - - return promises; - }, []); +export function clearAllNotifications(client: MatrixClient): Promise> { + const receiptPromises = client + .getRooms() + .reduce((promises: Array>, room: Room) => { + if (doesRoomHaveUnreadMessages(room, true)) { + const promise = clearRoomNotification(room, client); + promises.push(promise); + } + + return promises; + }, []); return Promise.all(receiptPromises); } diff --git a/src/utils/objects.ts b/src/utils/objects.ts index a919699eac6..60bf7024047 100644 --- a/src/utils/objects.ts +++ b/src/utils/objects.ts @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import { arrayDiff, arrayUnion, arrayIntersection } from "./arrays"; -type ObjectExcluding = { [k in Exclude]: O[k] }; +type ObjectExcluding = { [k in Exclude]: O[k] }; /** * Gets a new object which represents the provided object, excluding some properties. @@ -16,7 +16,7 @@ type ObjectExcluding = { [k in Exclude>(a: O, props: P): ObjectExcluding { +export function objectExcluding>(a: O, props: P): ObjectExcluding { // We use a Map to avoid hammering the `delete` keyword, which is slow and painful. const tempMap = new Map(Object.entries(a) as [keyof O, any][]); for (const prop of props) { @@ -37,7 +37,7 @@ export function objectExcluding>(a: O, pr * @param props The property names to keep. * @returns The new object with only the provided properties. */ -export function objectWithOnly>(a: O, props: P): { [k in P[number]]: O[k] } { +export function objectWithOnly>(a: O, props: P): { [k in P[number]]: O[k] } { const existingProps = Object.keys(a) as (keyof O)[]; const diff = arrayDiff(existingProps, props); if (diff.removed.length === 0) { @@ -58,7 +58,7 @@ export function objectWithOnly>(a: O, pro * First argument is the property key with the second being the current value. * @returns A cloned object. */ -export function objectShallowClone(a: O, propertyCloner?: (k: keyof O, v: O[keyof O]) => any): O { +export function objectShallowClone(a: O, propertyCloner?: (k: keyof O, v: O[keyof O]) => any): O { const newObj = {} as O; for (const [k, v] of Object.entries(a) as [keyof O, O[keyof O]][]) { newObj[k] = v; @@ -77,7 +77,7 @@ export function objectShallowClone(a: O, propertyCloner?: (k: keyo * @param b The second object. Must be defined. * @returns True if there's a difference between the objects, false otherwise */ -export function objectHasDiff(a: O, b: O): boolean { +export function objectHasDiff(a: O, b: O): boolean { if (a === b) return false; const aKeys = Object.keys(a); const bKeys = Object.keys(b); @@ -99,7 +99,7 @@ type Diff = { changed: K[]; added: K[]; removed: K[] }; * @param b The second object. Must be defined. * @returns The difference between the keys of each object. */ -export function objectDiff(a: O, b: O): Diff { +export function objectDiff(a: O, b: O): Diff { const aKeys = Object.keys(a) as (keyof O)[]; const bKeys = Object.keys(b) as (keyof O)[]; const keyDiff = arrayDiff(aKeys, bKeys); @@ -118,7 +118,7 @@ export function objectDiff(a: O, b: O): Diff { * @returns The keys which have been added, removed, or changed between the * two objects. */ -export function objectKeyChanges(a: O, b: O): (keyof O)[] { +export function objectKeyChanges(a: O, b: O): (keyof O)[] { const diff = objectDiff(a, b); return arrayUnion(diff.removed, diff.added, diff.changed); } @@ -130,7 +130,7 @@ export function objectKeyChanges(a: O, b: O): (keyof O)[] { * @param obj The object to clone. * @returns The cloned object */ -export function objectClone(obj: O): O { +export function objectClone(obj: O): O { return JSON.parse(JSON.stringify(obj)); } diff --git a/src/vector/app.tsx b/src/vector/app.tsx index 2ae9e6fa03f..12d8173d5fb 100644 --- a/src/vector/app.tsx +++ b/src/vector/app.tsx @@ -17,6 +17,7 @@ import { logger } from "matrix-js-sdk/src/logger"; import { createClient, AutoDiscovery, ClientConfig } from "matrix-js-sdk/src/matrix"; import { WrapperLifecycle, WrapperOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/WrapperLifecycle"; +import type { QueryDict } from "matrix-js-sdk/src/utils"; import PlatformPeg from "../PlatformPeg"; import AutoDiscoveryUtils from "../utils/AutoDiscoveryUtils"; import * as Lifecycle from "../Lifecycle"; @@ -54,7 +55,7 @@ function onTokenLoginCompleted(): void { window.history.replaceState(null, "", url.href); } -export async function loadApp(fragParams: {}, matrixChatRef: React.Ref): Promise { +export async function loadApp(fragParams: QueryDict, matrixChatRef: React.Ref): Promise { initRouting(); const platform = PlatformPeg.get(); diff --git a/src/vector/init.tsx b/src/vector/init.tsx index bb4a128d80e..9a2f1c1196d 100644 --- a/src/vector/init.tsx +++ b/src/vector/init.tsx @@ -12,6 +12,7 @@ import { createRoot } from "react-dom/client"; import React, { StrictMode } from "react"; import { logger } from "matrix-js-sdk/src/logger"; +import type { QueryDict } from "matrix-js-sdk/src/utils"; import * as languageHandler from "../languageHandler"; import SettingsStore from "../settings/SettingsStore"; import PlatformPeg from "../PlatformPeg"; @@ -83,7 +84,7 @@ export async function loadTheme(): Promise { return setTheme(); } -export async function loadApp(fragParams: {}): Promise { +export async function loadApp(fragParams: QueryDict): Promise { // load app.js async so that its code is not executed immediately and we can catch any exceptions const module = await import( /* webpackChunkName: "element-web-app" */ diff --git a/src/vector/platform/IPCManager.ts b/src/vector/platform/IPCManager.ts index 7d329b8b2cb..5b8af55df8e 100644 --- a/src/vector/platform/IPCManager.ts +++ b/src/vector/platform/IPCManager.ts @@ -40,7 +40,7 @@ export class IPCManager { return deferred.promise; } - private onIpcReply = (_ev: {}, payload: IPCPayload): void => { + private onIpcReply = (_ev: Event, payload: IPCPayload): void => { if (payload.id === undefined) { logger.warn("Ignoring IPC reply with no ID"); return; diff --git a/test/unit-tests/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx b/test/unit-tests/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx index d9d7cb48b19..17bc426a405 100644 --- a/test/unit-tests/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx +++ b/test/unit-tests/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx @@ -14,10 +14,7 @@ import SettingsStore from "../../../../../../../src/settings/SettingsStore"; import SdkConfig from "../../../../../../../src/SdkConfig"; describe("", () => { - const defaultProps = { - closeSettingsFn: jest.fn(), - }; - const getComponent = () => ; + const getComponent = () => ; const settingsValueSpy = jest.spyOn(SettingsStore, "getValue"); diff --git a/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx b/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx index f334c6b28f8..193c77448d0 100644 --- a/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx +++ b/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx @@ -1104,8 +1104,9 @@ describe("", () => { // because promise flushing after the confirm modal is resolving this too // and we want to test the loading state here const resolveDeleteRequest = defer(); - mockClient.deleteMultipleDevices.mockImplementation(() => { - return resolveDeleteRequest.promise; + mockClient.deleteMultipleDevices.mockImplementation(async () => { + await resolveDeleteRequest.promise; + return {}; }); const { getByTestId } = render(getComponent()); diff --git a/test/unit-tests/hooks/useProfileInfo-test.tsx b/test/unit-tests/hooks/useProfileInfo-test.tsx index e42dcb18583..1b3c4b59808 100644 --- a/test/unit-tests/hooks/useProfileInfo-test.tsx +++ b/test/unit-tests/hooks/useProfileInfo-test.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import { waitFor, renderHook, act } from "jest-matrix-react"; -import { MatrixClient } from "matrix-js-sdk/src/matrix"; +import { EmptyObject, MatrixClient } from "matrix-js-sdk/src/matrix"; import { useProfileInfo } from "../../../src/hooks/useProfileInfo"; import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; @@ -93,7 +93,7 @@ describe("useProfileInfo", () => { }); it("should be able to handle an empty result", async () => { - cli.getProfileInfo = () => null as unknown as Promise<{}>; + cli.getProfileInfo = () => null as unknown as Promise; const query = "@user:home.server"; const { result } = render(); From d9001d177c2d23c09e3d6d0f8dda6787fde29fbc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:27:20 +0000 Subject: [PATCH 2/2] Update docker/build-push-action digest to ca877d9 (#29172) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/dockerhub.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerhub.yaml b/.github/workflows/dockerhub.yaml index 90a892ed8b4..28ed6a63045 100644 --- a/.github/workflows/dockerhub.yaml +++ b/.github/workflows/dockerhub.yaml @@ -51,7 +51,7 @@ jobs: - name: Build and push id: build-and-push - uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6 + uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6 with: context: . push: true