diff --git a/package.json b/package.json index 2516a083a..de4d99080 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "vite build", "preview": "vite preview", "lint": "npm run check:eslint && npm run check:prettier", - "check:eslint": "eslint src/* --max-warnings 68", + "check:eslint": "eslint src/* --max-warnings 49", "check:prettier": "prettier --check .", "fix:prettier": "prettier --write .", "typecheck": "tsc --noEmit", diff --git a/src/app/components/ImageOverlay.tsx b/src/app/components/ImageOverlay.tsx index 271c36b34..d57f37733 100644 --- a/src/app/components/ImageOverlay.tsx +++ b/src/app/components/ImageOverlay.tsx @@ -30,7 +30,7 @@ export const ImageOverlay = as<'div', ImageOverlayProps>( evt.stopPropagation()} + onContextMenu={(evt: React.MouseEvent) => evt.stopPropagation()} > {renderViewer({ src, diff --git a/src/app/components/message/content/FileContent.tsx b/src/app/components/message/content/FileContent.tsx index 80f44c7b8..466d06ff7 100644 --- a/src/app/components/message/content/FileContent.tsx +++ b/src/app/components/message/content/FileContent.tsx @@ -114,7 +114,7 @@ export function ReadTextFile({ body, mimeType, url, encInfo, renderViewer }: Rea evt.stopPropagation()} + onContextMenu={(evt: React.MouseEvent) => evt.stopPropagation()} > {renderViewer({ name: body, @@ -203,7 +203,7 @@ export function ReadPdfFile({ body, mimeType, url, encInfo, renderViewer }: Read evt.stopPropagation()} + onContextMenu={(evt: React.MouseEvent) => evt.stopPropagation()} > {renderViewer({ name: body, diff --git a/src/app/components/message/content/ImageContent.tsx b/src/app/components/message/content/ImageContent.tsx index 98aa00a67..8d1c5f2c1 100644 --- a/src/app/components/message/content/ImageContent.tsx +++ b/src/app/components/message/content/ImageContent.tsx @@ -143,7 +143,7 @@ export const ImageContent = as<'div', ImageContentProps>( evt.stopPropagation()} + onContextMenu={(evt: React.MouseEvent) => evt.stopPropagation()} > {renderViewer({ src: srcState.data, diff --git a/src/app/components/user-profile/UserHero.tsx b/src/app/components/user-profile/UserHero.tsx index 3fb8d231b..ee17a7724 100644 --- a/src/app/components/user-profile/UserHero.tsx +++ b/src/app/components/user-profile/UserHero.tsx @@ -88,7 +88,7 @@ export function UserHero({ userId, avatarUrl, presence }: UserHeroProps) { evt.stopPropagation()} + onContextMenu={(evt: React.MouseEvent) => evt.stopPropagation()} > + onClick={(evt: React.MouseEvent) => openUserProfile( room.roomId, undefined, diff --git a/src/app/features/room/RoomTombstone.tsx b/src/app/features/room/RoomTombstone.tsx index 947735638..f4414fafa 100644 --- a/src/app/features/room/RoomTombstone.tsx +++ b/src/app/features/room/RoomTombstone.tsx @@ -36,7 +36,7 @@ export function RoomTombstone({ roomId, body, replacementRoomId }: RoomTombstone {body || 'This room has been replaced and is no longer active.'} {joinState.status === AsyncStatus.Error && ( - {(joinState.error as any)?.message ?? 'Failed to join replacement room!'} + {(joinState.error as Error | undefined)?.message ?? 'Failed to join replacement room!'} )} diff --git a/src/app/features/room/message/Message.tsx b/src/app/features/room/message/Message.tsx index 927a8786c..4bc003bad 100644 --- a/src/app/features/room/message/Message.tsx +++ b/src/app/features/room/message/Message.tsx @@ -214,7 +214,7 @@ export const MessageAllReactionItem = as< return ( <> { + onContextMenu={(evt: React.MouseEvent) => { evt.stopPropagation(); }} open={open} @@ -1087,7 +1087,7 @@ export const Message = React.memo( const handleContextMenu: MouseEventHandler = (evt) => { if (evt.altKey || !window.getSelection()?.isCollapsed || edit) return; - const tag = (evt.target as any).tagName; + const tag = (evt.target as HTMLElement | null)?.tagName; if (typeof tag === 'string' && tag.toLowerCase() === 'a') return; evt.preventDefault(); if (coarsePointer) { @@ -1155,7 +1155,7 @@ export const Message = React.memo( after={} radii="300" data-event-id={mEvent.getId()} - onClick={(evt: any) => { + onClick={(evt: React.MouseEvent) => { onReplyClick(evt); closeMenu(); }} @@ -1232,7 +1232,7 @@ export const Message = React.memo( after={} radii="300" data-event-id={mEvent.getId()} - onClick={(evt: any) => { + onClick={(evt: React.MouseEvent) => { onReplyClick(evt, true); closeMenu(); }} @@ -1599,7 +1599,7 @@ export const Event = React.memo( const stateEvent = typeof mEvent.getStateKey() === 'string'; const handleContextMenu: MouseEventHandler = (evt) => { if (evt.altKey || !window.getSelection()?.isCollapsed) return; - const tag = (evt.target as any).tagName; + const tag = (evt.target as HTMLElement | null)?.tagName; if (typeof tag === 'string' && tag.toLowerCase() === 'a') return; evt.preventDefault(); setMenuAnchor({ diff --git a/src/app/features/room/message/Reactions.tsx b/src/app/features/room/message/Reactions.tsx index baf8cb44e..e8b3181af 100644 --- a/src/app/features/room/message/Reactions.tsx +++ b/src/app/features/room/message/Reactions.tsx @@ -202,7 +202,7 @@ export const Reactions = as<'div', ReactionsProps>( )} {reactions.length > 0 && ( { + onContextMenu={(evt: React.MouseEvent) => { evt.stopPropagation(); }} open={!!viewer} diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx index fe4ce435e..a2657c245 100644 --- a/src/app/pages/client/space/Space.tsx +++ b/src/app/pages/client/space/Space.tsx @@ -378,7 +378,7 @@ export function SpaceTombstone({ roomId, replacementRoomId }: SpaceTombstoneProp This space has been replaced and is no longer active. {joinState.status === AsyncStatus.Error && ( - {(joinState.error as any)?.message ?? 'Failed to join replacement space!'} + {(joinState.error as Error | undefined)?.message ?? 'Failed to join replacement space!'} )} diff --git a/src/app/plugins/call/CallEmbed.ts b/src/app/plugins/call/CallEmbed.ts index 4a8b884fa..66f0617f4 100644 --- a/src/app/plugins/call/CallEmbed.ts +++ b/src/app/plugins/call/CallEmbed.ts @@ -368,7 +368,7 @@ export class CallEmbed { return this.listenEvent('preparing', callback); } - public onPreparingError(callback: (error: any) => void) { + public onPreparingError(callback: (error: unknown) => void) { return this.listenEvent('error:preparing', callback); } diff --git a/src/app/utils/lotusDenoiseUtils.ts b/src/app/utils/lotusDenoiseUtils.ts index d4f721a2e..8d9e0ee08 100644 --- a/src/app/utils/lotusDenoiseUtils.ts +++ b/src/app/utils/lotusDenoiseUtils.ts @@ -68,7 +68,9 @@ export const isMLDenoiseSupported = (): boolean => { // 1. AudioContext/webkitAudioContext (Web Audio API) // 2. AudioWorklet (Real-time processing in a background thread) // 3. getUserMedia (Microphone access) - const hasAudioContext = !!(window.AudioContext || (window as any).webkitAudioContext); + const hasAudioContext = !!( + window.AudioContext || (window as Window & { webkitAudioContext?: unknown }).webkitAudioContext + ); // Use `typeof` rather than `!!AudioWorkletNode`: on a browser that has // AudioContext but no AudioWorkletNode binding (older Safari/Edge), a bare // reference throws ReferenceError, making this feature-detection helper throw diff --git a/src/app/utils/matrix-uia.ts b/src/app/utils/matrix-uia.ts index b46cea6da..7507a3669 100644 --- a/src/app/utils/matrix-uia.ts +++ b/src/app/utils/matrix-uia.ts @@ -72,7 +72,10 @@ export const getLoginTermUrl = (params: UIAParams): string | undefined => { if (terms.policies === null) return undefined; if ('privacy_policy' in terms.policies && typeof terms.policies.privacy_policy === 'object') { if (terms.policies.privacy_policy === null) return undefined; - const langToPolicy = terms.policies.privacy_policy as Record; + const langToPolicy = terms.policies.privacy_policy as Record< + string, + { url?: string } | undefined + >; const url = langToPolicy.en?.url; if (typeof url === 'string') return url; diff --git a/src/sw.ts b/src/sw.ts index 4f8789e4b..158773965 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -63,7 +63,7 @@ async function cleanupDeadClients() { }); } -function setSession(clientId: string, accessToken: any, baseUrl: any) { +function setSession(clientId: string, accessToken: string, baseUrl: string) { if (typeof accessToken === 'string' && typeof baseUrl === 'string') { sessions.set(clientId, { accessToken, baseUrl }); } else {