diff --git a/apps/desktop/electron-builder.ts b/apps/desktop/electron-builder.ts index 013991ce95..830b68dfca 100644 --- a/apps/desktop/electron-builder.ts +++ b/apps/desktop/electron-builder.ts @@ -75,7 +75,7 @@ if (process.env.VARIANT_PATH) { console.log(`Using variant configuration from '${process.env.VARIANT_PATH}':`); variant = { ...variant, - ...JSON.parse(fs.readFileSync(`${process.env.VARIANT_PATH}`, "utf8")), + ...JSON.parse(fs.readFileSync(process.env.VARIANT_PATH, "utf8")), }; } else { console.warn(`No VARIANT_PATH specified, using default variant configuration '${DEFAULT_VARIANT}':`); diff --git a/apps/desktop/hak/matrix-seshat/check.ts b/apps/desktop/hak/matrix-seshat/check.ts index 99a107eb5a..dba992e6fc 100644 --- a/apps/desktop/hak/matrix-seshat/check.ts +++ b/apps/desktop/hak/matrix-seshat/check.ts @@ -48,8 +48,9 @@ export default async function (hakEnv: HakEnv, moduleInfo: DependencyInfo): Prom "` " + "or your package manager if not using `rustup`", ); + return; } - fsProm.unlink("tmp").then(resolve); + resolve(fsProm.unlink("tmp")); }, ); rustc.stdin!.write("fn main() {}"); diff --git a/apps/desktop/scripts/hak/copy.ts b/apps/desktop/scripts/hak/copy.ts index dd266201cf..167aa8ef0b 100644 --- a/apps/desktop/scripts/hak/copy.ts +++ b/apps/desktop/scripts/hak/copy.ts @@ -27,7 +27,7 @@ export default async function copy(hakEnv: HakEnv, moduleInfo: DependencyInfo): if (moduleInfo.moduleBuildDirs.length > 1) { if (!hakEnv.isMac()) { console.error( - "You asked me to copy multiple targets but I've only been taught " + "how to do that on macOS.", + "You asked me to copy multiple targets but I've only been taught how to do that on macOS.", ); throw new Error("Can't copy multiple targets on this platform"); } diff --git a/apps/desktop/scripts/hak/index.ts b/apps/desktop/scripts/hak/index.ts index 78da8aaefd..db6ecd4da9 100644 --- a/apps/desktop/scripts/hak/index.ts +++ b/apps/desktop/scripts/hak/index.ts @@ -131,7 +131,7 @@ async function main(): Promise { for (const mod of modules) { const depInfo = deps[mod]; if (depInfo === undefined) { - console.log("Module " + mod + " not found - is it in hakDependencies " + "in your package.json?"); + console.log(`Module ${mod} not found - is it in hakDependencies in your package.json?`); process.exit(1); } console.log("hak " + cmd + ": " + mod); diff --git a/apps/desktop/src/vectormenu.test.ts b/apps/desktop/src/vectormenu.test.ts index f0d1c15375..5b3582e7c7 100644 --- a/apps/desktop/src/vectormenu.test.ts +++ b/apps/desktop/src/vectormenu.test.ts @@ -42,12 +42,10 @@ describe("buildMenuTemplate", () => { ({ buildMenuTemplate } = await import("./vectormenu.js")); }); - if (platform === "darwin") { - it("should have an app-named item first", () => { - const menu = buildMenuTemplate(); - expect(menu.items[0].label).toBe("ChatApp"); - }); - } + it.runIf(platform === "darwin")("should have an app-named item first", () => { + const menu = buildMenuTemplate(); + expect(menu.items[0].label).toBe("ChatApp"); + }); it("should include expected `help` menu", () => { const menu = buildMenuTemplate(); @@ -55,8 +53,8 @@ describe("buildMenuTemplate", () => { const helpMenu = menu.items.at(-1)!; expect(helpMenu.label).toBe("common|help"); const helpSubmenu = helpMenu.submenu as unknown as MenuItemConstructorOptions[]; - expect(helpSubmenu[0]!.label).toBe("common|brand_help"); - helpSubmenu[0]!.click!(menu.items.at(-1)!, undefined, new Event("click") as KeyboardEvent); + expect(helpSubmenu[0].label).toBe("common|brand_help"); + helpSubmenu[0].click!(menu.items.at(-1)!, undefined, new Event("click") as KeyboardEvent); expect(shell.openExternal).toHaveBeenCalledWith("https://i.need.help"); }); }); diff --git a/apps/web/@types/webpack-version-file-plugin.d.ts b/apps/web/@types/webpack-version-file-plugin.d.ts index 7869805f83..95432bdb1c 100644 --- a/apps/web/@types/webpack-version-file-plugin.d.ts +++ b/apps/web/@types/webpack-version-file-plugin.d.ts @@ -13,6 +13,7 @@ declare module "webpack-version-file-plugin" { extras?: Record; } + // oxlint-disable-next-line typescript/no-extraneous-class export default class VersionFilePlugin { public constructor(opts: Opts); } diff --git a/apps/web/playwright/e2e/read-receipts/index.ts b/apps/web/playwright/e2e/read-receipts/index.ts index 6ff5789795..ee8cbb0667 100644 --- a/apps/web/playwright/e2e/read-receipts/index.ts +++ b/apps/web/playwright/e2e/read-receipts/index.ts @@ -609,7 +609,7 @@ class Helpers { const roomListContainer = this.page.getByTestId("room-list"); const roomTiles = roomListContainer.getByRole("option"); for (const [i, room] of rooms.entries()) { - await expect(roomTiles.nth(i)).toHaveAccessibleName(new RegExp(`${room.name}`)); + await expect(roomTiles.nth(i)).toHaveAccessibleName(new RegExp(room.name)); } } } diff --git a/apps/web/playwright/e2e/read-receipts/read-receipts.spec.ts b/apps/web/playwright/e2e/read-receipts/read-receipts.spec.ts index 9e38cd4d71..dbb6fd4d8e 100644 --- a/apps/web/playwright/e2e/read-receipts/read-receipts.spec.ts +++ b/apps/web/playwright/e2e/read-receipts/read-receipts.spec.ts @@ -120,11 +120,11 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => { await sendUnthreadedReadReceipt(app, main2); // (So the room has no unreads) - await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible(); + await expect(page.getByLabel(otherRoomName)).toBeVisible(); // And we persuade the app to persist its state to indexeddb by reloading and waiting await page.reload(); - await expect(page.getByLabel(`${selectedRoomName}`)).toBeVisible(); + await expect(page.getByLabel(selectedRoomName)).toBeVisible(); // And we reload again, fetching the persisted state FROM indexeddb await page.reload(); @@ -132,7 +132,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => { // Then the room is read, because the persisted state correctly remembers both // receipts. (In #24629, the unthreaded receipt overwrote the main thread one, // meaning that the room still said it had unread messages.) - await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible(); + await expect(page.getByLabel(otherRoomName)).toBeVisible(); await expect(page.getByLabel(`${otherRoomName} Unread messages.`)).not.toBeVisible(); }); @@ -172,7 +172,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => { await sendThreadedReadReceipt(app, main3); // Then the room has no unreads - await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible(); + await expect(page.getByLabel(otherRoomName)).toBeVisible(); }); test("Recognises unread messages on other thread after receiving a receipt for earlier ones", async ({ @@ -210,7 +210,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => { await sendThreadedReadReceipt(app, thread1b, main1); // Then the room has no unreads - await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible(); + await expect(page.getByLabel(otherRoomName)).toBeVisible(); await util.goTo({ name: otherRoomName, roomId: otherRoomId }); await util.assertReadThread("Message 1"); }); @@ -235,7 +235,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => { // thread. The one in main is read because the unthreaded // receipt is for a later event. The room should therefore be // read, and the thread unread. - await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible(); + await expect(page.getByLabel(otherRoomName)).toBeVisible(); await util.goTo({ name: otherRoomName, roomId: otherRoomId }); await util.assertUnreadThread("Message 1"); }); diff --git a/apps/web/project.json b/apps/web/project.json index 812dfec740..6c69f26dfc 100644 --- a/apps/web/project.json +++ b/apps/web/project.json @@ -46,6 +46,10 @@ }, "dependsOn": ["^build", "^build:playwright"] }, + "lint:prepare": { + "executor": "nx:noop", + "dependsOn": ["^build"] + }, "test:unit:prepare": { "executor": "nx:noop", "dependsOn": ["^build"] diff --git a/apps/web/src/HtmlUtils.tsx b/apps/web/src/HtmlUtils.tsx index 9a8d885d25..7630d8550f 100644 --- a/apps/web/src/HtmlUtils.tsx +++ b/apps/web/src/HtmlUtils.tsx @@ -459,7 +459,7 @@ export function bodyToNode(content: IContent, highlights?: string[], opts: Event // This has to be done after the emojiBody check as to not break big emoji on replies formattedBody = formatEmojis(eventInfo.safeBody, true).join(""); } else { - emojiBodyElements = formatEmojis(eventInfo.strippedBody, false) as JSX.Element[]; + emojiBodyElements = formatEmojis(eventInfo.strippedBody, false); } } diff --git a/apps/web/src/Notifier.ts b/apps/web/src/Notifier.ts index 5f0ccd18d5..14ad1a03a7 100644 --- a/apps/web/src/Notifier.ts +++ b/apps/web/src/Notifier.ts @@ -262,7 +262,7 @@ export default class Notifier extends TypedEventEmitter { return Promise.all( diff --git a/apps/web/src/RoomInvite.tsx b/apps/web/src/RoomInvite.tsx index 0b789a5766..2c3632c8c3 100644 --- a/apps/web/src/RoomInvite.tsx +++ b/apps/web/src/RoomInvite.tsx @@ -117,7 +117,7 @@ export function showAnyInviteErrors( (avatarUrl && mediaFromMxc(avatarUrl).getSquareThumbnailHttp(24)) ?? undefined } - name={name!} + name={name} idName={user?.userId} size="36px" /> diff --git a/apps/web/src/RoomNotifs.ts b/apps/web/src/RoomNotifs.ts index 2db2cf2158..4489dbf6c3 100644 --- a/apps/web/src/RoomNotifs.ts +++ b/apps/web/src/RoomNotifs.ts @@ -237,7 +237,7 @@ function isRuleRoomMuteRuleForRoomId(roomId: string, rule: IPushRule): boolean { return false; } // isRuleMaybeRoomMuteRule checks this condition exists - const cond = rule.conditions![0]!; + const cond = rule.conditions![0]; return cond.pattern === roomId; } diff --git a/apps/web/src/ScalarMessaging.ts b/apps/web/src/ScalarMessaging.ts index 2c3f0bfc65..20858b5d1c 100644 --- a/apps/web/src/ScalarMessaging.ts +++ b/apps/web/src/ScalarMessaging.ts @@ -316,14 +316,14 @@ enum Action { ReadEvents = "read_events", } -function sendResponse(event: MessageEvent, res: any): void { +function sendResponse(event: MessageEvent, res: any): void { const data = objectClone(event.data); data.response = res; // @ts-ignore event.source.postMessage(data, event.origin); } -function sendError(event: MessageEvent, msg: string, nestedError?: Error): void { +function sendError(event: MessageEvent, msg: string, nestedError?: Error): void { logger.error("Action:" + event.data.action + " failed with message: " + msg); const data = objectClone(event.data); data.response = { @@ -338,7 +338,7 @@ function sendError(event: MessageEvent, msg: string, nestedError?: Error): event.source.postMessage(data, event.origin); } -function inviteUser(event: MessageEvent, roomId: string, userId: string): void { +function inviteUser(event: MessageEvent, roomId: string, userId: string): void { logger.log(`Received request to invite ${userId} into room ${roomId}`); const client = MatrixClientPeg.get(); if (!client) { @@ -372,7 +372,7 @@ function inviteUser(event: MessageEvent, roomId: string, userId: string): v ); } -function kickUser(event: MessageEvent, roomId: string, userId: string): void { +function kickUser(event: MessageEvent, roomId: string, userId: string): void { logger.log(`Received request to kick ${userId} from room ${roomId}`); const client = MatrixClientPeg.get(); if (!client) { @@ -404,7 +404,7 @@ function kickUser(event: MessageEvent, roomId: string, userId: string): voi }); } -function setWidget(event: MessageEvent, roomId: string | null): void { +function setWidget(event: MessageEvent, roomId: string | null): void { const client = MatrixClientPeg.safeGet(); const widgetId = event.data.widget_id; let widgetType = event.data.type; @@ -488,7 +488,7 @@ function setWidget(event: MessageEvent, roomId: string | null): void { } } -function getWidgets(event: MessageEvent, roomId: string | null): void { +function getWidgets(event: MessageEvent, roomId: string | null): void { const client = MatrixClientPeg.get(); if (!client) { sendError(event, _t("widget|error_need_to_be_logged_in")); @@ -514,7 +514,7 @@ function getWidgets(event: MessageEvent, roomId: string | null): void { sendResponse(event, widgetStateEvents); } -async function getRoomEncState(event: MessageEvent, roomId: string): Promise { +async function getRoomEncState(event: MessageEvent, roomId: string): Promise { const client = MatrixClientPeg.get(); if (!client) { sendError(event, _t("widget|error_need_to_be_logged_in")); @@ -530,7 +530,7 @@ async function getRoomEncState(event: MessageEvent, roomId: string): Promis sendResponse(event, roomIsEncrypted); } -function setPlumbingState(event: MessageEvent, roomId: string, status: string): void { +function setPlumbingState(event: MessageEvent, roomId: string, status: string): void { if (typeof status !== "string") { throw new Error("Plumbing state status should be a string"); } @@ -552,7 +552,7 @@ function setPlumbingState(event: MessageEvent, roomId: string, status: stri ); } -function setBotOptions(event: MessageEvent, roomId: string, userId: string): void { +function setBotOptions(event: MessageEvent, roomId: string, userId: string): void { logger.log(`Received request to set options for bot ${userId} in room ${roomId}`); const client = MatrixClientPeg.get(); if (!client) { @@ -572,7 +572,7 @@ function setBotOptions(event: MessageEvent, roomId: string, userId: string) } async function setBotPower( - event: MessageEvent, + event: MessageEvent, roomId: string, userId: string, level: number, @@ -613,22 +613,22 @@ async function setBotPower( } } -function getMembershipState(event: MessageEvent, roomId: string, userId: string): void { +function getMembershipState(event: MessageEvent, roomId: string, userId: string): void { logger.log(`membership_state of ${userId} in room ${roomId} requested.`); returnStateEvent(event, roomId, "m.room.member", userId); } -function getJoinRules(event: MessageEvent, roomId: string): void { +function getJoinRules(event: MessageEvent, roomId: string): void { logger.log(`join_rules of ${roomId} requested.`); returnStateEvent(event, roomId, "m.room.join_rules", ""); } -function botOptions(event: MessageEvent, roomId: string, userId: string): void { +function botOptions(event: MessageEvent, roomId: string, userId: string): void { logger.log(`bot_options of ${userId} in room ${roomId} requested.`); returnStateEvent(event, roomId, "m.room.bot.options", "_" + userId); } -function getMembershipCount(event: MessageEvent, roomId: string): void { +function getMembershipCount(event: MessageEvent, roomId: string): void { const client = MatrixClientPeg.get(); if (!client) { sendError(event, _t("widget|error_need_to_be_logged_in")); @@ -643,7 +643,7 @@ function getMembershipCount(event: MessageEvent, roomId: string): void { sendResponse(event, count); } -function canSendEvent(event: MessageEvent, roomId: string): void { +function canSendEvent(event: MessageEvent, roomId: string): void { const evType = "" + event.data.event_type; // force stringify const isState = Boolean(event.data.is_state); const client = MatrixClientPeg.get(); @@ -677,7 +677,7 @@ function canSendEvent(event: MessageEvent, roomId: string): void { sendResponse(event, true); } -function returnStateEvent(event: MessageEvent, roomId: string, eventType: string, stateKey: string): void { +function returnStateEvent(event: MessageEvent, roomId: string, eventType: string, stateKey: string): void { const client = MatrixClientPeg.get(); if (!client) { sendError(event, _t("widget|error_need_to_be_logged_in")); @@ -696,7 +696,7 @@ function returnStateEvent(event: MessageEvent, roomId: string, eventType: s sendResponse(event, stateEvent.getContent()); } -async function getOpenIdToken(event: MessageEvent): Promise { +async function getOpenIdToken(event: MessageEvent): Promise { try { const tokenObject = await MatrixClientPeg.safeGet().getOpenIdToken(); sendResponse(event, tokenObject); @@ -841,7 +841,7 @@ async function readEvents( } } -const onMessage = function (event: MessageEvent): void { +const onMessage = function (event: MessageEvent): void { if (!event.origin) { // @ts-ignore - stupid chrome event.origin = event.originalEvent.origin; @@ -987,7 +987,7 @@ export function stopListening(): void { } if (listenerCount < 0) { // Make an error so we get a stack trace - const e = new Error("ScalarMessaging: mismatched startListening / stopListening detected." + " Negative count"); + const e = new Error("ScalarMessaging: mismatched startListening / stopListening detected. Negative count"); logger.error(e); } } diff --git a/apps/web/src/SdkConfig.ts b/apps/web/src/SdkConfig.ts index a52dd8eb66..3cbd4bb1a8 100644 --- a/apps/web/src/SdkConfig.ts +++ b/apps/web/src/SdkConfig.ts @@ -95,6 +95,7 @@ type ObjectType = IConfigOptions[K] extends obje ? SnakedObject> : SnakedObject> | null | undefined; +// oxlint-disable-next-line typescript/no-extraneous-class export default class SdkConfig { private static instance: DeepReadonly; private static fallback: SnakedObject>; diff --git a/apps/web/src/TextForEvent.tsx b/apps/web/src/TextForEvent.tsx index 77d476e0b0..41d0abf8f1 100644 --- a/apps/web/src/TextForEvent.tsx +++ b/apps/web/src/TextForEvent.tsx @@ -49,7 +49,7 @@ function getRoomMemberDisplayname(client: MatrixClient, event: MatrixEvent, user } function textForCallEvent(event: MatrixEvent, client: MatrixClient): () => string { - const roomName = client.getRoom(event.getRoomId()!)?.name; + const roomName = client.getRoom(event.getRoomId())?.name; const isSupported = client.supportsVoip(); return isSupported diff --git a/apps/web/src/accessibility/KeyboardShortcutUtils.ts b/apps/web/src/accessibility/KeyboardShortcutUtils.ts index 2d383d10f6..16c7a5a77a 100644 --- a/apps/web/src/accessibility/KeyboardShortcutUtils.ts +++ b/apps/web/src/accessibility/KeyboardShortcutUtils.ts @@ -96,7 +96,7 @@ export const getKeyboardShortcuts = (): IKeyboardShortcuts => { return true; }) .reduce((o, key) => { - o[key as KeyBindingAction] = KEYBOARD_SHORTCUTS[key as KeyBindingAction]; + o[key] = KEYBOARD_SHORTCUTS[key]; return o; }, {} as IKeyboardShortcuts); }; diff --git a/apps/web/src/accessibility/LandmarkNavigation.ts b/apps/web/src/accessibility/LandmarkNavigation.ts index acb6812ca3..9ad30020a6 100644 --- a/apps/web/src/accessibility/LandmarkNavigation.ts +++ b/apps/web/src/accessibility/LandmarkNavigation.ts @@ -32,6 +32,7 @@ const ORDERED_LANDMARKS = [ * The landmarks are cycled through in the following order: * ACTIVE_SPACE_BUTTON <-> ROOM_SEARCH <-> ROOM_LIST <-> MESSAGE_COMPOSER/HOME <-> ACTIVE_SPACE_BUTTON */ +// oxlint-disable-next-line typescript/no-extraneous-class export class LandmarkNavigation { /** * Get the next/previous landmark that must be focused from a given landmark diff --git a/apps/web/src/actions/RoomListActions.ts b/apps/web/src/actions/RoomListActions.ts index b91be93042..a63b71a6c5 100644 --- a/apps/web/src/actions/RoomListActions.ts +++ b/apps/web/src/actions/RoomListActions.ts @@ -18,6 +18,7 @@ import { type AsyncActionPayload } from "../dispatcher/payloads"; import { DefaultTagID, type TagID } from "../stores/room-list-v3/skip-list/tag"; import ErrorDialog from "../components/views/dialogs/ErrorDialog"; +// oxlint-disable-next-line typescript/no-extraneous-class export default class RoomListActions { /** * Creates an action thunk that will do an asynchronous request to diff --git a/apps/web/src/audio/RecorderWorklet.ts b/apps/web/src/audio/RecorderWorklet.ts index 53c99d2b8e..8f47be28a7 100644 --- a/apps/web/src/audio/RecorderWorklet.ts +++ b/apps/web/src/audio/RecorderWorklet.ts @@ -62,16 +62,16 @@ class MxVoiceWorklet extends AudioWorkletProcessor { const maxVal = Math.max(...monoChan); const amplitude = percentageOf(maxVal, -1, 1) - percentageOf(minVal, -1, 1); - this.port.postMessage({ + this.port.postMessage({ ev: PayloadEvent.AmplitudeMark, amplitude: amplitude, forIndex: this.amplitudeIndex++, - }); + } satisfies IAmplitudePayload); this.nextAmplitudeSecond = nextTimeForTargetFreq(currentSecond); } // We mostly use this worklet to fire regular clock updates through to components - this.port.postMessage({ ev: PayloadEvent.Timekeep, timeSeconds: currentTime }); + this.port.postMessage({ ev: PayloadEvent.Timekeep, timeSeconds: currentTime } satisfies ITimingPayload); // We're supposed to return false when we're "done" with the audio clip, but seeing as // we are acting as a passive processor we are never truly "done". The browser will clean diff --git a/apps/web/src/autocomplete/NotifProvider.tsx b/apps/web/src/autocomplete/NotifProvider.tsx index 3a0fbf3909..ca76a46839 100644 --- a/apps/web/src/autocomplete/NotifProvider.tsx +++ b/apps/web/src/autocomplete/NotifProvider.tsx @@ -40,7 +40,7 @@ export default class NotifProvider extends AutocompleteProvider { if ( command?.[0] && command[0].length > 1 && - ["@room", "@channel", "@everyone", "@here"].some((c) => c.startsWith(command![0])) + ["@room", "@channel", "@everyone", "@here"].some((c) => c.startsWith(command[0])) ) { return [ { diff --git a/apps/web/src/components/structures/ContextMenu.tsx b/apps/web/src/components/structures/ContextMenu.tsx index 0d3a8086b2..2dcbf4d6b9 100644 --- a/apps/web/src/components/structures/ContextMenu.tsx +++ b/apps/web/src/components/structures/ContextMenu.tsx @@ -228,7 +228,7 @@ export default class ContextMenu extends React.PureComponent is focused, only handle the Escape key - if (checkInputableElement(ev.target as HTMLElement) && action !== KeyBindingAction.Escape) { + if (checkInputableElement(ev.target) && action !== KeyBindingAction.Escape) { return; } diff --git a/apps/web/src/components/structures/GenericDropdownMenu.tsx b/apps/web/src/components/structures/GenericDropdownMenu.tsx index f76e43c108..2a9f2f0055 100644 --- a/apps/web/src/components/structures/GenericDropdownMenu.tsx +++ b/apps/web/src/components/structures/GenericDropdownMenu.tsx @@ -123,7 +123,7 @@ export function GenericDropdownMenu({ className, AdditionalOptions, }: IProps): JSX.Element { - const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); + const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); const valueKey = calculateKey(value, toKey); const selected: GenericDropdownMenuItem | undefined = options diff --git a/apps/web/src/components/structures/MatrixChat.tsx b/apps/web/src/components/structures/MatrixChat.tsx index fd42de69ee..7707069fc4 100644 --- a/apps/web/src/components/structures/MatrixChat.tsx +++ b/apps/web/src/components/structures/MatrixChat.tsx @@ -1264,7 +1264,7 @@ export default class MatrixChat extends React.PureComponent { if (isOnlyAdmin(roomToLeave)) { const userLevelValues = roomToLeave.getJoinedMembers().map((m) => m.powerLevel); - const maxUserLevel = Math.max(...(userLevelValues as number[])); + const maxUserLevel = Math.max(...userLevelValues); const warning = maxUserLevel >= 100 diff --git a/apps/web/src/components/structures/PictureInPictureDragger.tsx b/apps/web/src/components/structures/PictureInPictureDragger.tsx index d9f472c311..914a53f0bb 100644 --- a/apps/web/src/components/structures/PictureInPictureDragger.tsx +++ b/apps/web/src/components/structures/PictureInPictureDragger.tsx @@ -31,7 +31,7 @@ export type CreatePipChildren = (options: IChildrenOptions) => JSX.Element; interface IChildrenOptions { // a callback which is called when a mouse event (most likely mouse down) occurs at start of moving the pip around - onStartMoving: (event: React.MouseEvent) => void; + onStartMoving: (event: React.MouseEvent) => void; // a callback which is called when the content fo the pip changes in a way that is likely to cause a resize onResize: (event: Event) => void; } diff --git a/apps/web/src/components/structures/RightPanel.tsx b/apps/web/src/components/structures/RightPanel.tsx index 24c1655455..00cdebe5b5 100644 --- a/apps/web/src/components/structures/RightPanel.tsx +++ b/apps/web/src/components/structures/RightPanel.tsx @@ -256,7 +256,7 @@ export default class RightPanel extends React.Component { { this.setState({ membersLoaded: true }); } } catch (err) { - const errorMessage = - `Fetching room members for ${room.roomId} failed.` + " Room members will appear incomplete."; + const errorMessage = `Fetching room members for ${room.roomId} failed. Room members will appear incomplete.`; logger.error(errorMessage); logger.error(err); } diff --git a/apps/web/src/components/structures/ScrollPanel.tsx b/apps/web/src/components/structures/ScrollPanel.tsx index 05bf2e5a7a..da77abe5e6 100644 --- a/apps/web/src/components/structures/ScrollPanel.tsx +++ b/apps/web/src/components/structures/ScrollPanel.tsx @@ -457,7 +457,7 @@ export default class ScrollPanel extends React.Component { this.unfillDebouncer = window.setTimeout(() => { this.unfillDebouncer = null; debuglog("unfilling now", { backwards, origExcessHeight }); - this.props.onUnfillRequest?.(backwards, markerScrollToken!); + this.props.onUnfillRequest?.(backwards, markerScrollToken); }, UNFILL_REQUEST_DEBOUNCE_MS); } } @@ -666,7 +666,7 @@ export default class ScrollPanel extends React.Component { debuglog("unable to save scroll state: found no children in the viewport"); return; } - const scrollToken = node!.dataset.scrollTokens?.split(",")[0]; + const scrollToken = node.dataset.scrollTokens?.split(",")[0]; debuglog("saving anchored scroll state to message", scrollToken); const bottomOffset = this.topFromBottom(node); this.scrollState = { @@ -788,7 +788,7 @@ export default class ScrollPanel extends React.Component { const m = messages[i] as HTMLElement; // 'data-scroll-tokens' is a DOMString of comma-separated scroll tokens // There might only be one scroll token - if (scrollToken && m.dataset.scrollTokens?.split(",").includes(scrollToken!)) { + if (scrollToken && m.dataset.scrollTokens?.split(",").includes(scrollToken)) { node = m; break; } diff --git a/apps/web/src/components/structures/SpaceHierarchy.tsx b/apps/web/src/components/structures/SpaceHierarchy.tsx index dbfd21bef6..fc9d81988f 100644 --- a/apps/web/src/components/structures/SpaceHierarchy.tsx +++ b/apps/web/src/components/structures/SpaceHierarchy.tsx @@ -62,7 +62,6 @@ import { Action } from "../../dispatcher/actions"; import { type IState, RovingTabIndexProvider, useRovingTabIndex } from "../../accessibility/RovingTabIndex"; import MatrixClientContext from "../../contexts/MatrixClientContext"; import { useTypedEventEmitterState } from "../../hooks/useEventEmitter"; -import { type IOOBData } from "../../stores/ThreepidInviteStore"; import { awaitRoomDownSync } from "../../utils/RoomUpgrade"; import { type ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; import { type JoinRoomReadyPayload } from "../../dispatcher/payloads/JoinRoomReadyPayload"; @@ -400,7 +399,7 @@ export const showRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: st // XXX: This logic is duplicated from the JS SDK which would normally decide what the name is. name: room?.name || roomAlias || _t("common|unnamed_room"), roomType, - } as IOOBData, + }, metricsTrigger: "RoomDirectory", }); }; diff --git a/apps/web/src/components/structures/SpaceRoomView.tsx b/apps/web/src/components/structures/SpaceRoomView.tsx index fff3eb710f..569c15090a 100644 --- a/apps/web/src/components/structures/SpaceRoomView.tsx +++ b/apps/web/src/components/structures/SpaceRoomView.tsx @@ -617,7 +617,7 @@ export default class SpaceRoomView extends React.PureComponent { if (showSetup) { phase = - this.props.justCreatedOpts!.createOpts?.preset === Preset.PublicChat + this.props.justCreatedOpts.createOpts?.preset === Preset.PublicChat ? Phase.PublicCreateRooms : Phase.PrivateScope; } diff --git a/apps/web/src/components/structures/ThreadPanel.tsx b/apps/web/src/components/structures/ThreadPanel.tsx index c1da58b692..c61d428b32 100644 --- a/apps/web/src/components/structures/ThreadPanel.tsx +++ b/apps/web/src/components/structures/ThreadPanel.tsx @@ -70,7 +70,7 @@ export const ThreadPanelHeader: React.FC<{ }> = ({ filterOption, setFilterOption }) => { const mxClient = useMatrixClientContext(); const roomContext = useScopedRoomContext("room"); - const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); + const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); const options: readonly ThreadPanelHeaderOption[] = [ { label: _t("threads|all_threads"), diff --git a/apps/web/src/components/structures/ThreadView.tsx b/apps/web/src/components/structures/ThreadView.tsx index 6c0a04bb4b..3ff168a46c 100644 --- a/apps/web/src/components/structures/ThreadView.tsx +++ b/apps/web/src/components/structures/ThreadView.tsx @@ -272,7 +272,7 @@ export default class ThreadView extends React.Component { this.timelinePanel.current?.refreshTimeline(this.props.initialEvent?.getId()); } - private setupThreadListeners(thread?: Thread | undefined, oldThread?: Thread | undefined): void { + private setupThreadListeners(thread?: Thread, oldThread?: Thread): void { if (oldThread) { this.state.thread?.off(ThreadEvent.NewReply, this.updateThreadRelation); this.props.room.off(RoomEvent.LocalEchoUpdated, this.updateThreadRelation); diff --git a/apps/web/src/components/structures/TimelinePanel.tsx b/apps/web/src/components/structures/TimelinePanel.tsx index 51bce161c7..392622745b 100644 --- a/apps/web/src/components/structures/TimelinePanel.tsx +++ b/apps/web/src/components/structures/TimelinePanel.tsx @@ -1532,6 +1532,7 @@ class TimelinePanel extends React.Component { description, }); if (onFinished) { + // oxlint-disable-next-line promise/no-promise-in-callback finished.then(onFinished); } }; diff --git a/apps/web/src/components/structures/UploadBar.tsx b/apps/web/src/components/structures/UploadBar.tsx index 4fbe35f3fd..b118e197a5 100644 --- a/apps/web/src/components/structures/UploadBar.tsx +++ b/apps/web/src/components/structures/UploadBar.tsx @@ -63,7 +63,7 @@ export default class UploadBar extends React.PureComponent { public componentWillUnmount(): void { this.unmounted = true; - dis.unregister(this.dispatcherRef!); + dis.unregister(this.dispatcherRef); } private getUploadsInRoom(): RoomUpload[] { diff --git a/apps/web/src/components/structures/auth/ForgotPassword.tsx b/apps/web/src/components/structures/auth/ForgotPassword.tsx index b8a1ead479..e6de8edb8b 100644 --- a/apps/web/src/components/structures/auth/ForgotPassword.tsx +++ b/apps/web/src/components/structures/auth/ForgotPassword.tsx @@ -339,7 +339,7 @@ export default class ForgotPassword extends React.Component { homeserver={this.props.serverConfig.hsName} loading={this.state.phase === Phase.SendingEmail} onInputChanged={this.onInputChanged} - onLoginClick={this.props.onLoginClick!} // set by default props + onLoginClick={this.props.onLoginClick} // set by default props onSubmitForm={this.onSubmitForm} /> ); diff --git a/apps/web/src/components/views/audio_messages/LegacySeekBar.tsx b/apps/web/src/components/views/audio_messages/LegacySeekBar.tsx index fe9e1dacd8..92d5415fef 100644 --- a/apps/web/src/components/views/audio_messages/LegacySeekBar.tsx +++ b/apps/web/src/components/views/audio_messages/LegacySeekBar.tsx @@ -89,7 +89,7 @@ export default class LegacySeekBar extends React.PureComponent { this.props.playback.skipTo(Number(ev.target.value) * this.props.playback.durationSeconds); }; - private onMouseDown = (event: React.MouseEvent): void => { + private onMouseDown = (event: React.MouseEvent): void => { // do not propagate mouse down events, because these should be handled by the seekbar event.stopPropagation(); }; diff --git a/apps/web/src/components/views/auth/LoginWithQR.tsx b/apps/web/src/components/views/auth/LoginWithQR.tsx index 257d2af1ea..a8d9a1e1d3 100644 --- a/apps/web/src/components/views/auth/LoginWithQR.tsx +++ b/apps/web/src/components/views/auth/LoginWithQR.tsx @@ -286,9 +286,7 @@ export default class LoginWithQR extends React.Component { } catch (e: RendezvousError | unknown) { if (abortController.signal.aborted) return; logger.error("Error whilst approving login", e); - await rendezvous.cancel( - e instanceof RendezvousError ? (e.code as MSC4108FailureReason) : ClientRendezvousFailureReason.Unknown, - ); + await rendezvous.cancel(e instanceof RendezvousError ? e.code : ClientRendezvousFailureReason.Unknown); } }; diff --git a/apps/web/src/components/views/dialogs/BugReportDialog.tsx b/apps/web/src/components/views/dialogs/BugReportDialog.tsx index 1b108bcb52..f4bfc2f2c0 100644 --- a/apps/web/src/components/views/dialogs/BugReportDialog.tsx +++ b/apps/web/src/components/views/dialogs/BugReportDialog.tsx @@ -205,7 +205,7 @@ export default class BugReportDialog extends React.Component { msg: this.state[repo], }); } else { - content = (this.state[repo] as Commit[]).map(this.elementsForCommit); + content = this.state[repo].map(this.elementsForCommit); } return (
diff --git a/apps/web/src/components/views/dialogs/ExportDialog.tsx b/apps/web/src/components/views/dialogs/ExportDialog.tsx index d4c19374fe..e6242fbbdf 100644 --- a/apps/web/src/components/views/dialogs/ExportDialog.tsx +++ b/apps/web/src/components/views/dialogs/ExportDialog.tsx @@ -381,7 +381,7 @@ const ExportDialog: React.FC = ({ room, onFinished }) => { className="mx_ExportDialog_attachments-checkbox" id="include-attachments" checked={includeAttachments} - onChange={(e) => setAttachments((e.target as HTMLInputElement).checked)} + onChange={(e) => setAttachments(e.target.checked)} > {_t("export_chat|include_attachments")} diff --git a/apps/web/src/components/views/dialogs/GenericFeatureFeedbackDialog.tsx b/apps/web/src/components/views/dialogs/GenericFeatureFeedbackDialog.tsx index c2f79a6c8a..1a42aa3163 100644 --- a/apps/web/src/components/views/dialogs/GenericFeatureFeedbackDialog.tsx +++ b/apps/web/src/components/views/dialogs/GenericFeatureFeedbackDialog.tsx @@ -78,10 +78,7 @@ const GenericFeatureFeedbackDialog: React.FC = ({ }} autoFocus={true} /> - setCanContact((e.target as HTMLInputElement).checked)} - > + setCanContact(e.target.checked)}> {_t("feedback|can_contact_label")} diff --git a/apps/web/src/components/views/dialogs/InviteDialog.test.tsx b/apps/web/src/components/views/dialogs/InviteDialog.test.tsx index b29b88e2c1..867e78158d 100644 --- a/apps/web/src/components/views/dialogs/InviteDialog.test.tsx +++ b/apps/web/src/components/views/dialogs/InviteDialog.test.tsx @@ -323,10 +323,10 @@ describe("InviteDialog", () => { const input = screen.getByTestId("invite-dialog-input"); input.focus(); - await userEvent.paste(`${bobbob}`); + await userEvent.paste(bobbob); await screen.findAllByText(bobId); - expect(input).toHaveValue(`${bobbob}`); + expect(input).toHaveValue(bobbob); }); it("should allow to invite multiple emails to a room", async () => { @@ -409,9 +409,9 @@ describe("InviteDialog", () => { const input = screen.getByTestId("invite-dialog-input"); input.focus(); - await userEvent.paste(`${bobId}`); - await userEvent.paste(`${bobId}`); - await userEvent.paste(`${bobId}`); + await userEvent.paste(bobId); + await userEvent.paste(bobId); + await userEvent.paste(bobId); expect(input).toHaveValue(""); await expect(screen.findAllByText(bobId, { selector: "a" })).resolves.toHaveLength(1); @@ -422,7 +422,7 @@ describe("InviteDialog", () => { const input = screen.getByTestId("invite-dialog-input"); input.focus(); - await userEvent.keyboard(`${aliceId}`); + await userEvent.keyboard(aliceId); const btn = await screen.findByRole("option", { name: aliceId }); fireEvent.click(btn); diff --git a/apps/web/src/components/views/dialogs/ModalWidgetDialog.tsx b/apps/web/src/components/views/dialogs/ModalWidgetDialog.tsx index 6c438bfd3a..1fe5e3328b 100644 --- a/apps/web/src/components/views/dialogs/ModalWidgetDialog.tsx +++ b/apps/web/src/components/views/dialogs/ModalWidgetDialog.tsx @@ -116,7 +116,7 @@ export default class ModalWidgetDialog extends React.PureComponent - {this.props.contentFactory(contentProps, this.contentRef as RefObject)} -
- ); + return
{this.props.contentFactory(contentProps, this.contentRef)}
; } } diff --git a/apps/web/src/components/views/dialogs/invite/DMRoomTile.tsx b/apps/web/src/components/views/dialogs/invite/DMRoomTile.tsx index 78024188f0..28a6e6e5bc 100644 --- a/apps/web/src/components/views/dialogs/invite/DMRoomTile.tsx +++ b/apps/web/src/components/views/dialogs/invite/DMRoomTile.tsx @@ -41,7 +41,7 @@ export class DMRoomTile extends React.PureComponent { | React.KeyboardEvent | React.FormEvent; +export type ButtonEvent = React.MouseEvent | React.KeyboardEvent | React.FormEvent; /** * The kind of button, similar to how Bootstrap works. diff --git a/apps/web/src/components/views/elements/EventListSummary.tsx b/apps/web/src/components/views/elements/EventListSummary.tsx index 3ed8764dd9..051a4a4902 100644 --- a/apps/web/src/components/views/elements/EventListSummary.tsx +++ b/apps/web/src/components/views/elements/EventListSummary.tsx @@ -306,8 +306,8 @@ export default class EventListSummary extends React.Component { let transition = t; - if (i < transitions.length - 1 && modMap[t] && modMap[t]!.after === t2) { - transition = modMap[t]!.newTransition; + if (i < transitions.length - 1 && modMap[t] && modMap[t].after === t2) { + transition = modMap[t].newTransition; i++; } diff --git a/apps/web/src/components/views/elements/ImageView.tsx b/apps/web/src/components/views/elements/ImageView.tsx index d5de5c2bba..71578a0946 100644 --- a/apps/web/src/components/views/elements/ImageView.tsx +++ b/apps/web/src/components/views/elements/ImageView.tsx @@ -459,7 +459,7 @@ export default class ImageView extends React.Component { let info: JSX.Element | undefined; if (showEventMeta) { - const mxEvent = this.props.mxEvent!; + const mxEvent = this.props.mxEvent; const showTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps"); let permalink = "#"; if (this.props.permalinkCreator) { diff --git a/apps/web/src/components/views/location/Map.tsx b/apps/web/src/components/views/location/Map.tsx index 55597acbe4..23d8911b85 100644 --- a/apps/web/src/components/views/location/Map.tsx +++ b/apps/web/src/components/views/location/Map.tsx @@ -163,7 +163,7 @@ const MapComponent: React.FC = ({ }) => { const { map, bodyId } = useMapWithStyle({ centerGeoUri, onError, id, interactive, bounds, allowGeolocate }); - const onMapClick = (event: React.MouseEvent): void => { + const onMapClick = (event: React.MouseEvent): void => { // Eat click events when clicking the attribution button const target = event.target as Element; if (target.classList.contains("maplibregl-ctrl-attrib-button")) { diff --git a/apps/web/src/components/views/location/Marker.tsx b/apps/web/src/components/views/location/Marker.tsx index 92a6313f38..ca845d1415 100644 --- a/apps/web/src/components/views/location/Marker.tsx +++ b/apps/web/src/components/views/location/Marker.tsx @@ -39,7 +39,7 @@ const OptionalTooltip: React.FC<{ const show = (): void => setIsVisible(true); const hide = (): void => setIsVisible(false); - const toggleVisibility = (e: React.MouseEvent): void => { + const toggleVisibility = (e: React.MouseEvent): void => { // stop map from zooming in on click e.stopPropagation(); setIsVisible(!isVisible); diff --git a/apps/web/src/components/views/messages/MImageReplyBody.tsx b/apps/web/src/components/views/messages/MImageReplyBody.tsx index 87c6a9666c..1f03cc5e59 100644 --- a/apps/web/src/components/views/messages/MImageReplyBody.tsx +++ b/apps/web/src/components/views/messages/MImageReplyBody.tsx @@ -25,7 +25,7 @@ import { type Media, mediaFromContent } from "../../../customisations/Media"; import { BLURHASH_FIELD, createThumbnail } from "../../../utils/image-media"; import ImageView from "../elements/ImageView"; import { type IBodyProps } from "./IBodyProps"; -import { type ImageSize, suggestedSize as suggestedImageSize } from "../../../settings/enums/ImageSize"; +import { suggestedSize as suggestedImageSize } from "../../../settings/enums/ImageSize"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext"; import { blobIsAnimated, mayBeAnimated } from "../../../utils/Image"; @@ -409,7 +409,7 @@ export class ImageBodyBaseInner extends React.Component { */ export function collectUserVotes( userResponses: Array, - userId?: string | null | undefined, - selected?: string | null | undefined, + userId?: string | null, + selected?: string | null, ): Map { const userVotes: Map = new Map(); diff --git a/apps/web/src/components/views/polls/pollHistory/PollHistoryList.tsx b/apps/web/src/components/views/polls/pollHistory/PollHistoryList.tsx index 2370c80ba6..d75204bef5 100644 --- a/apps/web/src/components/views/polls/pollHistory/PollHistoryList.tsx +++ b/apps/web/src/components/views/polls/pollHistory/PollHistoryList.tsx @@ -129,13 +129,13 @@ export const PollHistoryList: React.FC = ({ {pollStartEvents.map((pollStartEvent) => filter === "ACTIVE" ? ( onItemClick(pollStartEvent.getId()!)} /> ) : ( onItemClick(pollStartEvent.getId()!)} diff --git a/apps/web/src/components/views/right_panel/UserInfo.tsx b/apps/web/src/components/views/right_panel/UserInfo.tsx index c896115cf6..9875ebfe15 100644 --- a/apps/web/src/components/views/right_panel/UserInfo.tsx +++ b/apps/web/src/components/views/right_panel/UserInfo.tsx @@ -195,14 +195,14 @@ const UserInfo: React.FC = ({ user, room, onClose, phase = RightPanelPha let content: JSX.Element | undefined; switch (phase) { case RightPanelPhases.MemberInfo: - content = ; + content = ; break; case RightPanelPhases.EncryptionPanel: classes.push("mx_UserInfo_smallAvatar"); content = ( )} - member={member as User | RoomMember} + member={member} onClose={onEncryptionPanelClose} isRoomEncrypted={Boolean(isRoomEncrypted)} /> diff --git a/apps/web/src/components/views/room_settings/AliasSettings.tsx b/apps/web/src/components/views/room_settings/AliasSettings.tsx index aa662bbdd8..1633cfeb62 100644 --- a/apps/web/src/components/views/room_settings/AliasSettings.tsx +++ b/apps/web/src/components/views/room_settings/AliasSettings.tsx @@ -240,11 +240,11 @@ export default class AliasSettings extends React.Component { .createAlias(alias, this.props.roomId) .then(() => { this.setState({ - localAliases: this.state.localAliases.concat(alias!), + localAliases: this.state.localAliases.concat(alias), newAlias: undefined, }); if (!this.state.canonicalAlias) { - this.changeCanonicalAlias(alias!); + this.changeCanonicalAlias(alias); } }) .catch((err) => { diff --git a/apps/web/src/components/views/rooms/AppsDrawer.tsx b/apps/web/src/components/views/rooms/AppsDrawer.tsx index a9a3f95de4..492268b100 100644 --- a/apps/web/src/components/views/rooms/AppsDrawer.tsx +++ b/apps/web/src/components/views/rooms/AppsDrawer.tsx @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import React, { type AriaRole, useContext } from "react"; import classNames from "classnames"; -import { Resizable, type Size } from "re-resizable"; +import { Resizable } from "re-resizable"; import { type Room } from "matrix-js-sdk/src/matrix"; import { type IWidget } from "matrix-widget-api"; import { clamp, percentageOf, percentageWithin } from "@element-hq/web-shared-components"; @@ -340,7 +340,7 @@ const PersistentVResizer: React.FC = ({ { @@ -350,7 +350,7 @@ const PersistentVResizer: React.FC = ({ resizeNotifier.notifyTimelineHeightChanged(); }} onResizeStop={(e, dir, ref, d) => { - let newHeight = defaultHeight! + d.height; + let newHeight = defaultHeight + d.height; newHeight = percentageOf(newHeight, minHeight, maxHeight) * 100; sdkContext.widgetLayoutStore.setContainerHeight(room, "top", newHeight); diff --git a/apps/web/src/components/views/rooms/EventTile.tsx b/apps/web/src/components/views/rooms/EventTile.tsx index 11466bbb75..18e2a57a10 100644 --- a/apps/web/src/components/views/rooms/EventTile.tsx +++ b/apps/web/src/components/views/rooms/EventTile.tsx @@ -668,7 +668,7 @@ export class UnwrappedEventTile extends React.Component private readonly onFocusWithin = (event: FocusEvent): void => { // Show the action toolbar for keyboard-visible focus, with what-input as a fallback signal. - const target = event.target as HTMLElement; + const target = event.target; const showActionBarFromFocus = target.matches(":focus-visible") || document.body.dataset["data-whatinput"] === "keyboard"; this.setState((prevState) => ({ diff --git a/apps/web/src/components/views/rooms/NewRoomIntro.tsx b/apps/web/src/components/views/rooms/NewRoomIntro.tsx index 748c644282..cc9f3f3403 100644 --- a/apps/web/src/components/views/rooms/NewRoomIntro.tsx +++ b/apps/web/src/components/views/rooms/NewRoomIntro.tsx @@ -179,7 +179,7 @@ const NewRoomIntro: React.FC = () => { let parentSpace: Room | undefined; if ( sdkContext.spaceStore.activeSpaceRoom?.canInvite(cli.getSafeUserId()) && - sdkContext.spaceStore.isRoomInSpace(sdkContext.spaceStore.activeSpace!, room.roomId) + sdkContext.spaceStore.isRoomInSpace(sdkContext.spaceStore.activeSpace, room.roomId) ) { parentSpace = sdkContext.spaceStore.activeSpaceRoom; } @@ -192,7 +192,7 @@ const NewRoomIntro: React.FC = () => { className="mx_NewRoomIntro_inviteButton" kind="primary" onClick={() => { - showSpaceInvite(parentSpace!); + showSpaceInvite(parentSpace); }} > diff --git a/apps/web/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx b/apps/web/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx index 282c8e7e42..06d4f3bfa1 100644 --- a/apps/web/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx +++ b/apps/web/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx @@ -38,7 +38,7 @@ export const RoomListPanel: React.FC = ({ activeSpace }) => const [focusedElement, setFocusedElement] = useState(null); const onFocus = useCallback((ev: React.FocusEvent): void => { - setFocusedElement(ev.target as Element); + setFocusedElement(ev.target); }, []); const onBlur = useCallback((): void => { diff --git a/apps/web/src/components/views/rooms/RoomPreviewBar.tsx b/apps/web/src/components/views/rooms/RoomPreviewBar.tsx index eae70d61aa..1a0195a68c 100644 --- a/apps/web/src/components/views/rooms/RoomPreviewBar.tsx +++ b/apps/web/src/components/views/rooms/RoomPreviewBar.tsx @@ -218,7 +218,7 @@ class RoomPreviewBar extends React.Component { } return MessageCase.Invite; } else if (this.props.error) { - if ((this.props.error as MatrixError).errcode == "M_NOT_FOUND") { + if (this.props.error.errcode === "M_NOT_FOUND") { return MessageCase.RoomNotFound; } else { return MessageCase.OtherError; diff --git a/apps/web/src/components/views/rooms/SendMessageComposer.tsx b/apps/web/src/components/views/rooms/SendMessageComposer.tsx index 914499250a..13cdefaa69 100644 --- a/apps/web/src/components/views/rooms/SendMessageComposer.tsx +++ b/apps/web/src/components/views/rooms/SendMessageComposer.tsx @@ -610,7 +610,7 @@ export class SendMessageComposer extends React.Component { diff --git a/apps/web/src/components/views/rooms/WhoIsTypingTile.tsx b/apps/web/src/components/views/rooms/WhoIsTypingTile.tsx index 64a7ccaebf..7fd197f162 100644 --- a/apps/web/src/components/views/rooms/WhoIsTypingTile.tsx +++ b/apps/web/src/components/views/rooms/WhoIsTypingTile.tsx @@ -66,7 +66,7 @@ export default class WhoIsTypingTile extends React.Component { client.removeListener(RoomMemberEvent.Typing, this.onRoomMemberTyping); client.removeListener(RoomEvent.Timeline, this.onRoomTimeline); } - Object.values(this.state.delayedStopTypingTimers).forEach((t) => (t as Timer).abort()); + Object.values(this.state.delayedStopTypingTimers).forEach((t) => t.abort()); } private static isVisible(state: IState): boolean { diff --git a/apps/web/src/components/views/rooms/wysiwyg_composer/utils/message.ts b/apps/web/src/components/views/rooms/wysiwyg_composer/utils/message.ts index d5365d5311..1ff011c64a 100644 --- a/apps/web/src/components/views/rooms/wysiwyg_composer/utils/message.ts +++ b/apps/web/src/components/views/rooms/wysiwyg_composer/utils/message.ts @@ -133,7 +133,7 @@ export async function sendMessage( const prom = doMaybeLocalRoomAction( roomId, - (actualRoomId: string) => mxClient.sendMessage(actualRoomId, threadId, content!), + (actualRoomId: string) => mxClient.sendMessage(actualRoomId, threadId, content), mxClient, ); diff --git a/apps/web/src/components/views/settings/AddRemoveThreepids.tsx b/apps/web/src/components/views/settings/AddRemoveThreepids.tsx index 91df12f45f..301afd4d41 100644 --- a/apps/web/src/components/views/settings/AddRemoveThreepids.tsx +++ b/apps/web/src/components/views/settings/AddRemoveThreepids.tsx @@ -127,7 +127,7 @@ const ExistingThreepid: React.FC = ({ mode, threepid, onC threepid.medium === "email" ? _t("settings|general|error_revoke_email_discovery") : _t("settings|general|error_revoke_msisdn_discovery"), - }).then(); + }); }, [changeBinding, threepid.medium], ); @@ -143,7 +143,7 @@ const ExistingThreepid: React.FC = ({ mode, threepid, onC threepid.medium === "email" ? _t("settings|general|error_share_email_discovery") : _t("settings|general|error_share_msisdn_discovery"), - }).then(); + }); }, [changeBinding, threepid.medium], ); diff --git a/apps/web/src/components/views/settings/IntegrationManager.tsx b/apps/web/src/components/views/settings/IntegrationManager.tsx index bb6893551a..175146e6f2 100644 --- a/apps/web/src/components/views/settings/IntegrationManager.tsx +++ b/apps/web/src/components/views/settings/IntegrationManager.tsx @@ -96,6 +96,7 @@ export default class IntegrationManager extends React.Component ); } + // oxlint-disable-next-line react/iframe-missing-sandbox return