{result.items.map((userId) => {
const username = `${getMxIdLocalPart(userId)}`;
const userServer = getMxIdServer(userId);
diff --git a/src/app/components/join-address-prompt/JoinAddressPrompt.tsx b/src/app/components/join-address-prompt/JoinAddressPrompt.tsx
index d6a6478d2..fc33f55ca 100644
--- a/src/app/components/join-address-prompt/JoinAddressPrompt.tsx
+++ b/src/app/components/join-address-prompt/JoinAddressPrompt.tsx
@@ -1,4 +1,5 @@
-import { FormEventHandler, useState } from 'react';
+import type { FormEventHandler } from 'react';
+import { useState } from 'react';
import FocusTrap from 'focus-trap-react';
import {
Dialog,
diff --git a/src/app/components/knock-room-prompt/KnockRoomPrompt.tsx b/src/app/components/knock-room-prompt/KnockRoomPrompt.tsx
index a7948e9ab..5974cb0f6 100644
--- a/src/app/components/knock-room-prompt/KnockRoomPrompt.tsx
+++ b/src/app/components/knock-room-prompt/KnockRoomPrompt.tsx
@@ -1,4 +1,5 @@
-import { useCallback, useEffect, FormEventHandler } from 'react';
+import type { FormEventHandler } from 'react';
+import { useCallback, useEffect } from 'react';
import FocusTrap from 'focus-trap-react';
import {
Dialog,
@@ -17,7 +18,7 @@ import {
Button,
Spinner,
} from 'folds';
-import { MatrixError } from '$types/matrix-sdk';
+import type { MatrixError } from '$types/matrix-sdk';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback';
diff --git a/src/app/components/leave-room-prompt/LeaveRoomPrompt.tsx b/src/app/components/leave-room-prompt/LeaveRoomPrompt.tsx
index 36cdd89de..d9b97f0fc 100644
--- a/src/app/components/leave-room-prompt/LeaveRoomPrompt.tsx
+++ b/src/app/components/leave-room-prompt/LeaveRoomPrompt.tsx
@@ -16,7 +16,7 @@ import {
Button,
Spinner,
} from 'folds';
-import { MatrixError } from '$types/matrix-sdk';
+import type { MatrixError } from '$types/matrix-sdk';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback';
import { stopPropagation } from '$utils/keyboard';
diff --git a/src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx b/src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx
index 5bee7af26..c6aef838d 100644
--- a/src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx
+++ b/src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx
@@ -16,7 +16,7 @@ import {
Button,
Spinner,
} from 'folds';
-import { MatrixError } from '$types/matrix-sdk';
+import type { MatrixError } from '$types/matrix-sdk';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback';
import { stopPropagation } from '$utils/keyboard';
diff --git a/src/app/components/media/Image.tsx b/src/app/components/media/Image.tsx
index 29990e99e..6970c70bb 100644
--- a/src/app/components/media/Image.tsx
+++ b/src/app/components/media/Image.tsx
@@ -1,4 +1,5 @@
-import { ImgHTMLAttributes, forwardRef } from 'react';
+import type { ImgHTMLAttributes } from 'react';
+import { forwardRef } from 'react';
import classNames from 'classnames';
import * as css from './media.css';
diff --git a/src/app/components/media/MediaControls.tsx b/src/app/components/media/MediaControls.tsx
index 2360b9f96..313f138e3 100644
--- a/src/app/components/media/MediaControls.tsx
+++ b/src/app/components/media/MediaControls.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { Box, as } from 'folds';
export type MediaControlProps = {
diff --git a/src/app/components/media/Video.tsx b/src/app/components/media/Video.tsx
index c28efcaa3..b27b4d0e8 100644
--- a/src/app/components/media/Video.tsx
+++ b/src/app/components/media/Video.tsx
@@ -1,10 +1,11 @@
-import { VideoHTMLAttributes, forwardRef, useEffect, useRef } from 'react';
+import type { VideoHTMLAttributes } from 'react';
+import { forwardRef, useEffect, useRef } from 'react';
import classNames from 'classnames';
import * as css from './media.css';
export const Video = forwardRef
>(
({ className, ...props }, ref) => (
- // eslint-disable-next-line jsx-a11y/media-has-caption
+ // oxlint-disable-next-line jsx-a11y/media-has-caption
)
);
diff --git a/src/app/components/member-tile/MemberTile.tsx b/src/app/components/member-tile/MemberTile.tsx
index e30c226c7..f6cb1cc94 100644
--- a/src/app/components/member-tile/MemberTile.tsx
+++ b/src/app/components/member-tile/MemberTile.tsx
@@ -1,6 +1,6 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { as, Avatar, Box, Icon, Icons, Text } from 'folds';
-import { MatrixClient, Room, RoomMember } from '$types/matrix-sdk';
+import type { MatrixClient, Room, RoomMember } from '$types/matrix-sdk';
import { getMemberDisplayName } from '$utils/room';
import { getMxIdLocalPart } from '$utils/matrix';
import { useSableCosmetics } from '$hooks/useSableCosmetics';
diff --git a/src/app/components/message/FileHeader.tsx b/src/app/components/message/FileHeader.tsx
index 36d8adeb1..92c41d37e 100644
--- a/src/app/components/message/FileHeader.tsx
+++ b/src/app/components/message/FileHeader.tsx
@@ -1,6 +1,7 @@
import { Badge, Box, Icon, IconButton, Icons, Spinner, Text, as, toRem } from 'folds';
-import { ReactNode, useCallback } from 'react';
-import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
+import type { ReactNode } from 'react';
+import { useCallback } from 'react';
+import type { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
import FileSaver from 'file-saver';
import { mimeTypeToExt } from '$utils/mimeTypes';
import { useMatrixClient } from '$hooks/useMatrixClient';
diff --git a/src/app/components/message/MsgTypeRenderers.tsx b/src/app/components/message/MsgTypeRenderers.tsx
index d52cdc5e1..399228cc2 100644
--- a/src/app/components/message/MsgTypeRenderers.tsx
+++ b/src/app/components/message/MsgTypeRenderers.tsx
@@ -1,9 +1,10 @@
-import { CSSProperties, ReactNode, useMemo } from 'react';
+import type { CSSProperties, ReactNode } from 'react';
+import { useMemo } from 'react';
import { Box, Chip, Icon, Icons, Text, toRem } from 'folds';
-import { IContent, IPreviewUrlResponse } from '$types/matrix-sdk';
+import type { IContent, IPreviewUrlResponse } from '$types/matrix-sdk';
import { JUMBO_EMOJI_REG, URL_REG } from '$utils/regex';
import { trimReplyFromBody } from '$utils/room';
-import {
+import type {
IAudioContent,
IAudioInfo,
IEncryptedFile,
@@ -14,6 +15,8 @@ import {
IThumbnailContent,
IVideoContent,
IVideoInfo,
+} from '$types/matrix/common';
+import {
MATRIX_SPOILER_PROPERTY_NAME,
MATRIX_SPOILER_REASON_PROPERTY_NAME,
} from '$types/matrix/common';
@@ -21,7 +24,7 @@ import { FALLBACK_MIMETYPE, getBlobSafeMimeType } from '$utils/mimeTypes';
import { parseGeoUri, scaleYDimension } from '$utils/common';
import { useSetting } from '$state/hooks/settings';
import { settingsAtom } from '$state/settings';
-import { PerMessageProfileBeeperFormat } from '$hooks/usePerMessageProfile';
+import type { PerMessageProfileBeeperFormat } from '$hooks/usePerMessageProfile';
import { Attachment, AttachmentBox, AttachmentContent, AttachmentHeader } from './attachment';
import { FileHeader, FileDownloadButton } from './FileHeader';
import {
@@ -34,6 +37,10 @@ import {
import { MessageTextBody } from './layout';
import { unwrapForwardedContent } from './modals/MessageForward';
+interface BundleContent extends IPreviewUrlResponse {
+ matched_url: string;
+}
+
export function MBadEncrypted() {
return (
@@ -138,13 +145,12 @@ export function MText({
if (!body && !customBody) return ;
- let bundleContent: object[] | undefined;
+ let bundleContent: BundleContent[] | undefined;
const urlsMatch = trimmedBody.match(URL_REG);
let urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
- bundleContent = content['com.beeper.linkpreviews'] as object[];
- bundleContent = bundleContent?.filter((bundle) => !!urls?.includes((bundle as any).matched_url));
- if (renderUrlsPreview && bundleContent)
- urls = bundleContent.map((bundle) => (bundle as any).matched_url);
+ bundleContent = content['com.beeper.linkpreviews'] as BundleContent[];
+ bundleContent = bundleContent?.filter((bundle) => !!urls?.includes(bundle.matched_url));
+ if (renderUrlsPreview && bundleContent) urls = bundleContent.map((bundle) => bundle.matched_url);
if ((content['com.beeper.per_message_profile'] as PerMessageProfileBeeperFormat)?.has_fallback) {
// unwrap per-message profile fallback if present
@@ -227,11 +233,11 @@ export function MEmote({
const trimmedBody = trimReplyFromBody(body);
const isJumbo = JUMBO_EMOJI_REG.test(trimmedBody);
- let bundleContent: object[] | undefined;
+ let bundleContent: BundleContent[] | undefined;
const urlsMatch = trimmedBody.match(URL_REG);
const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
- bundleContent = content['com.beeper.linkpreviews'] as object[];
- bundleContent = bundleContent?.filter((bundle) => !!urls?.includes((bundle as any).matched_url));
+ bundleContent = content['com.beeper.linkpreviews'] as BundleContent[];
+ bundleContent = bundleContent?.filter((bundle) => !!urls?.includes(bundle.matched_url));
return (
<>
@@ -279,11 +285,11 @@ export function MNotice({
const trimmedBody = trimReplyFromBody(body);
const isJumbo = JUMBO_EMOJI_REG.test(trimmedBody);
- let bundleContent: object[] | undefined;
+ let bundleContent: BundleContent[] | undefined;
const urlsMatch = trimmedBody.match(URL_REG);
const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
- bundleContent = content['com.beeper.linkpreviews'] as object[];
- bundleContent = bundleContent?.filter((bundle) => !!urls?.includes((bundle as any).matched_url));
+ bundleContent = content['com.beeper.linkpreviews'] as BundleContent[];
+ bundleContent = bundleContent?.filter((bundle) => !!urls?.includes(bundle.matched_url));
return (
<>
diff --git a/src/app/components/message/Reaction.tsx b/src/app/components/message/Reaction.tsx
index 155de11f4..c6d212ec4 100644
--- a/src/app/components/message/Reaction.tsx
+++ b/src/app/components/message/Reaction.tsx
@@ -1,7 +1,7 @@
import { useState } from 'react';
import { Box, Icon, Icons, Text, as } from 'folds';
import classNames from 'classnames';
-import { MatrixClient, MatrixEvent, Room } from '$types/matrix-sdk';
+import type { MatrixClient, MatrixEvent, Room } from '$types/matrix-sdk';
import { getHexcodeForEmoji, getShortcodeFor } from '$plugins/emoji';
import { getMemberDisplayName } from '$utils/room';
import { eventWithShortcode, getMxIdLocalPart, mxcUrlToHttp } from '$utils/matrix';
diff --git a/src/app/components/message/RenderBody.tsx b/src/app/components/message/RenderBody.tsx
index 8b83dff99..c83f58e3b 100644
--- a/src/app/components/message/RenderBody.tsx
+++ b/src/app/components/message/RenderBody.tsx
@@ -1,12 +1,17 @@
-import { MouseEventHandler, useEffect, useState } from 'react';
-import parse, { HTMLReactParserOptions } from 'html-react-parser';
+import type { MouseEventHandler } from 'react';
+import { useEffect, useState } from 'react';
+import type { HTMLReactParserOptions } from 'html-react-parser';
+import parse from 'html-react-parser';
import Linkify from 'linkify-react';
-import { find, Opts } from 'linkifyjs';
-import { PopOut, RectCords, Text, Tooltip, TooltipProvider, toRem } from 'folds';
+import type { Opts } from 'linkifyjs';
+import { find } from 'linkifyjs';
+import type { RectCords } from 'folds';
+import { PopOut, Text, Tooltip, TooltipProvider, toRem } from 'folds';
import { sanitizeCustomHtml } from '$utils/sanitize';
import { highlightText, scaleSystemEmoji } from '$plugins/react-custom-html-parser';
import { useRoomAbbreviationsContext } from '$hooks/useRoomAbbreviations';
-import { splitByAbbreviations, TextSegment } from '$utils/abbreviations';
+import type { TextSegment } from '$utils/abbreviations';
+import { splitByAbbreviations } from '$utils/abbreviations';
import { MessageEmptyContent } from './content';
function getRenderedBodyText(text: string, highlightRegex?: RegExp): (string | JSX.Element)[] {
@@ -64,9 +69,14 @@ function splitBodyTextByAbbreviations(
);
}
- return segments.length > 0
- ? segments.map((segment, index) => ({ ...segment, id: `txt-${index}` }))
- : [{ id: 'txt-0', text }];
+ if (segments.length === 0) {
+ return [{ id: 'txt-0', text }];
+ }
+ const result = segments as TextSegment[];
+ for (let i = 0; i < result.length; i += 1) {
+ result[i]!.id = `txt-${i}`;
+ }
+ return result;
}
type AbbreviationTermProps = {
@@ -101,7 +111,7 @@ function AbbreviationTerm({ text, definition }: AbbreviationTermProps) {
<>
{(triggerRef) => (
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events
}
onClick={handleClick}
diff --git a/src/app/components/message/Reply.test.tsx b/src/app/components/message/Reply.test.tsx
index 1d57a4645..e19334081 100644
--- a/src/app/components/message/Reply.test.tsx
+++ b/src/app/components/message/Reply.test.tsx
@@ -2,9 +2,12 @@ import { render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { Reply } from './Reply';
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
const { mockUseRoomEvent, mockInvalidateQueries } = vi.hoisted(() => ({
- mockUseRoomEvent: vi.fn(),
- mockInvalidateQueries: vi.fn(),
+ mockUseRoomEvent:
+ vi.fn<(_room: unknown, _replyEventId: unknown, _getFromLocalTimeline: unknown) => unknown>(),
+ mockInvalidateQueries: vi.fn<() => Promise>(),
}));
vi.mock('@tanstack/react-query', () => ({
@@ -14,7 +17,7 @@ vi.mock('@tanstack/react-query', () => ({
}));
vi.mock('jotai', async (importActual) => {
- const actual = await importActual();
+ const actual = (await importActual()) as object;
return {
...actual,
useAtomValue: () => ({}),
@@ -28,7 +31,7 @@ vi.mock('react-i18next', () => ({
}));
vi.mock('$hooks/useRoomEvent', () => ({
- useRoomEvent: (...args: unknown[]) => mockUseRoomEvent(...args),
+ useRoomEvent: (...args: unknown[]) => mockUseRoomEvent(args[0], args[1], args[2]),
}));
vi.mock('$hooks/useSableCosmetics', () => ({
@@ -53,7 +56,7 @@ vi.mock('$hooks/useMatrixClient', () => ({
}));
vi.mock('$hooks/useMemberEventParser', () => ({
- useMemberEventParser: () => vi.fn(),
+ useMemberEventParser: () => vi.fn<() => unknown>(),
}));
vi.mock('$hooks/useMentionClickHandler', () => ({
@@ -65,7 +68,7 @@ vi.mock('$features/settings/useSettingsLinkBaseUrl', () => ({
}));
vi.mock('$utils/room', async (importActual) => {
- const actual = await importActual();
+ const actual = (await importActual()) as object;
return {
...actual,
getMemberDisplayName: () => 'Alice',
@@ -112,7 +115,7 @@ describe('Reply', () => {
});
it('does not render unresolved mxc images as raw browser img tags in reply previews', () => {
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(vi.fn<() => void>());
mockUseRoomEvent.mockReturnValue(
createReplyEvent(
diff --git a/src/app/components/message/Reply.tsx b/src/app/components/message/Reply.tsx
index 331ef043a..da299bc5d 100644
--- a/src/app/components/message/Reply.tsx
+++ b/src/app/components/message/Reply.tsx
@@ -1,6 +1,8 @@
-import { Box, Chip, Icon, IconSrc, Icons, Text, as, color, toRem } from 'folds';
-import { EventTimelineSet, IMentions, Room, SessionMembershipData } from '$types/matrix-sdk';
-import { MouseEventHandler, ReactNode, useCallback, useMemo } from 'react';
+import type { IconSrc } from 'folds';
+import { Box, Chip, Icon, Icons, Text, as, color, toRem } from 'folds';
+import type { EventTimelineSet, IMentions, Room, SessionMembershipData } from '$types/matrix-sdk';
+import type { MouseEventHandler, ReactNode } from 'react';
+import { useCallback, useMemo } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import classNames from 'classnames';
import parse from 'html-react-parser';
@@ -299,7 +301,9 @@ export const Reply = as<'div', ReplyProps>(
before={}
onClick={(evt) => {
evt.stopPropagation();
- queryClient.invalidateQueries({ queryKey: [room.roomId, replyEventId] });
+ queryClient.invalidateQueries({
+ queryKey: [room.roomId, replyEventId],
+ });
}}
/>
)}
diff --git a/src/app/components/message/Time.tsx b/src/app/components/message/Time.tsx
index dc190d93d..75b7aa422 100644
--- a/src/app/components/message/Time.tsx
+++ b/src/app/components/message/Time.tsx
@@ -1,4 +1,4 @@
-import { ComponentProps } from 'react';
+import type { ComponentProps } from 'react';
import { Text, as, Tooltip, TooltipProvider } from 'folds';
import {
timeDayMonYear,
diff --git a/src/app/components/message/attachment/Attachment.css.ts b/src/app/components/message/attachment/Attachment.css.ts
index dad95f616..d98b7fb61 100644
--- a/src/app/components/message/attachment/Attachment.css.ts
+++ b/src/app/components/message/attachment/Attachment.css.ts
@@ -1,5 +1,6 @@
import { style } from '@vanilla-extract/css';
-import { RecipeVariants, recipe } from '@vanilla-extract/recipes';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
import { DefaultReset, color, config, toRem } from 'folds';
export const Attachment = recipe({
diff --git a/src/app/components/message/content/AudioContent.tsx b/src/app/components/message/content/AudioContent.tsx
index fb0f2bef9..f20bbca64 100644
--- a/src/app/components/message/content/AudioContent.tsx
+++ b/src/app/components/message/content/AudioContent.tsx
@@ -1,13 +1,14 @@
-/* eslint-disable jsx-a11y/media-has-caption */
-import { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
+/* oxlint-disable jsx-a11y/media-has-caption */
+import type { ReactNode } from 'react';
+import { useCallback, useEffect, useRef, useState } from 'react';
import { Badge, Chip, Icon, IconButton, Icons, ProgressBar, Spinner, Text, toRem } from 'folds';
-import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
+import type { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
import { Range } from 'react-range';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback';
-import { IAudioInfo } from '$types/matrix/common';
+import type { IAudioInfo } from '$types/matrix/common';
+import type { PlayTimeCallback } from '$hooks/media';
import {
- PlayTimeCallback,
useMediaLoading,
useMediaPlay,
useMediaPlayTimeCallback,
@@ -103,9 +104,12 @@ export function AudioContent({
min={0}
max={duration || 1}
values={[currentTime]}
- onChange={(values) => seek(values[0])}
+ onChange={(values) => seek(values[0] ?? 0)}
renderTrack={(params) => {
- const { key, ...restProps } = params.props as any;
+ const { key, ...restProps } = params.props as unknown as {
+ key?: string;
+ [key: string]: unknown;
+ };
return (
{params.children}
@@ -122,18 +126,22 @@ export function AudioContent({
);
}}
renderThumb={(params) => {
- const { key, style, ...restProps } = params.props as any;
+ const { key, style, ...restProps } = params.props as unknown as {
+ key?: unknown;
+ style?: Record
;
+ [key: string]: unknown;
+ };
return (
)}
style={{
- ...style,
+ ...(style as Record),
zIndex: 0,
}}
/>
@@ -180,9 +188,12 @@ export function AudioContent({
min={0}
max={1}
values={[volume]}
- onChange={(values) => setVolume(values[0])}
+ onChange={(values) => setVolume(values[0] ?? 1)}
renderTrack={(params) => {
- const { key, ...restProps } = params.props as any;
+ const { key, ...restProps } = params.props as unknown as {
+ key?: string;
+ [key: string]: unknown;
+ };
return (
{params.children}
@@ -199,18 +210,22 @@ export function AudioContent({
);
}}
renderThumb={(params) => {
- const { key, style, ...restProps } = params.props as any;
+ const { key, style, ...restProps } = params.props as unknown as {
+ key?: unknown;
+ style?: Record
;
+ [key: string]: unknown;
+ };
return (
)}
style={{
- ...style,
+ ...(style as Record),
zIndex: 0,
}}
/>
diff --git a/src/app/components/message/content/EventContent.tsx b/src/app/components/message/content/EventContent.tsx
index 35449e1ba..ac058985c 100644
--- a/src/app/components/message/content/EventContent.tsx
+++ b/src/app/components/message/content/EventContent.tsx
@@ -1,5 +1,6 @@
-import { Box, Icon, IconSrc } from 'folds';
-import { ReactNode } from 'react';
+import type { IconSrc } from 'folds';
+import { Box, Icon } from 'folds';
+import type { ReactNode } from 'react';
import { MessageLayout } from '$state/settings';
import { BubbleLayout, CompactLayout, ModernLayout } from '$components/message/layout';
@@ -12,9 +13,9 @@ export type EventContentProps = {
export function EventContent({ messageLayout, time, iconSrc, content }: EventContentProps) {
const beforeJSX = (
- {messageLayout === MessageLayout.Compact && time}
+ {messageLayout === (MessageLayout.Compact as number) && time}
@@ -26,14 +27,14 @@ export function EventContent({ messageLayout, time, iconSrc, content }: EventCon
const msgContentJSX = (
{content}
- {messageLayout !== MessageLayout.Compact && time}
+ {messageLayout !== (MessageLayout.Compact as number) && time}
);
- if (messageLayout === MessageLayout.Compact) {
+ if (messageLayout === (MessageLayout.Compact as number)) {
return {msgContentJSX};
}
- if (messageLayout === MessageLayout.Bubble) {
+ if (messageLayout === (MessageLayout.Bubble as number)) {
return (
{msgContentJSX}
diff --git a/src/app/components/message/content/FileContent.tsx b/src/app/components/message/content/FileContent.tsx
index af802d46b..73b11613f 100644
--- a/src/app/components/message/content/FileContent.tsx
+++ b/src/app/components/message/content/FileContent.tsx
@@ -1,4 +1,5 @@
-import { ReactNode, useCallback, useState } from 'react';
+import type { ReactNode } from 'react';
+import { useCallback, useState } from 'react';
import {
Box,
Button,
@@ -15,9 +16,9 @@ import {
as,
} from 'folds';
import FileSaver from 'file-saver';
-import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
+import type { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
import FocusTrap from 'focus-trap-react';
-import { IFileInfo } from '$types/matrix/common';
+import type { IFileInfo } from '$types/matrix/common';
import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { bytesToSize } from '$utils/common';
@@ -109,7 +110,7 @@ export function ReadTextFile({ body, mimeType, url, encInfo, renderViewer }: Rea
evt.stopPropagation()}
+ onContextMenu={(evt: React.MouseEvent) => evt.stopPropagation()}
>
{renderViewer({
name: body,
@@ -198,7 +199,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 ad51d2a4f..136a8a7b3 100644
--- a/src/app/components/message/content/ImageContent.tsx
+++ b/src/app/components/message/content/ImageContent.tsx
@@ -1,4 +1,5 @@
-import { ReactNode, useCallback, useEffect, useState } from 'react';
+import type { ReactNode } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import {
Badge,
Box,
@@ -22,8 +23,9 @@ import {
import classNames from 'classnames';
import { BlurhashCanvas } from 'react-blurhash';
import FocusTrap from 'focus-trap-react';
-import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
-import { IImageInfo, MATRIX_BLUR_HASH_PROPERTY_NAME } from '$types/matrix/common';
+import type { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
+import type { IImageInfo } from '$types/matrix/common';
+import { MATRIX_BLUR_HASH_PROPERTY_NAME } from '$types/matrix/common';
import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { bytesToSize } from '$utils/common';
@@ -151,7 +153,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/message/content/ThumbnailContent.tsx b/src/app/components/message/content/ThumbnailContent.tsx
index 2d0510bed..53e27002f 100644
--- a/src/app/components/message/content/ThumbnailContent.tsx
+++ b/src/app/components/message/content/ThumbnailContent.tsx
@@ -1,5 +1,6 @@
-import { ReactNode, useCallback, useEffect } from 'react';
-import { IThumbnailContent } from '$types/matrix/common';
+import type { ReactNode } from 'react';
+import { useCallback, useEffect } from 'react';
+import type { IThumbnailContent } from '$types/matrix/common';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback';
import { decryptFile, downloadEncryptedMedia, mxcUrlToHttp } from '$utils/matrix';
diff --git a/src/app/components/message/content/VideoContent.tsx b/src/app/components/message/content/VideoContent.tsx
index 71613c598..51658ebf5 100644
--- a/src/app/components/message/content/VideoContent.tsx
+++ b/src/app/components/message/content/VideoContent.tsx
@@ -1,4 +1,5 @@
-import { ReactNode, useCallback, useEffect, useState } from 'react';
+import type { ReactNode } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import {
Badge,
Box,
@@ -17,12 +18,9 @@ import {
} from 'folds';
import classNames from 'classnames';
import { BlurhashCanvas } from 'react-blurhash';
-import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
-import {
- IThumbnailContent,
- IVideoInfo,
- MATRIX_BLUR_HASH_PROPERTY_NAME,
-} from '$types/matrix/common';
+import type { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
+import type { IThumbnailContent, IVideoInfo } from '$types/matrix/common';
+import { MATRIX_BLUR_HASH_PROPERTY_NAME } from '$types/matrix/common';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback';
import { bytesToSize, millisecondsToMinutesAndSeconds } from '$utils/common';
diff --git a/src/app/components/message/layout/Bubble.tsx b/src/app/components/message/layout/Bubble.tsx
index 21120da47..27ab97bac 100644
--- a/src/app/components/message/layout/Bubble.tsx
+++ b/src/app/components/message/layout/Bubble.tsx
@@ -1,6 +1,7 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import classNames from 'classnames';
-import { Box, ContainerColor, as, color } from 'folds';
+import type { ContainerColor } from 'folds';
+import { Box, as, color } from 'folds';
import * as css from './layout.css';
type BubbleArrowProps = {
diff --git a/src/app/components/message/layout/Compact.tsx b/src/app/components/message/layout/Compact.tsx
index e9015ab96..a5422bb0d 100644
--- a/src/app/components/message/layout/Compact.tsx
+++ b/src/app/components/message/layout/Compact.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { Box, as } from 'folds';
import * as css from './layout.css';
diff --git a/src/app/components/message/layout/Modern.tsx b/src/app/components/message/layout/Modern.tsx
index e73e93013..6c21b07ab 100644
--- a/src/app/components/message/layout/Modern.tsx
+++ b/src/app/components/message/layout/Modern.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { Box, as } from 'folds';
import * as css from './layout.css';
diff --git a/src/app/components/message/layout/layout.css.ts b/src/app/components/message/layout/layout.css.ts
index ee423ca2c..e30e4c8c3 100644
--- a/src/app/components/message/layout/layout.css.ts
+++ b/src/app/components/message/layout/layout.css.ts
@@ -1,5 +1,6 @@
import { createVar, keyframes, style, styleVariants } from '@vanilla-extract/css';
-import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
import { DefaultReset, color, config, toRem } from 'folds';
export const StickySection = style({
diff --git a/src/app/components/message/modals/MessageDelete.tsx b/src/app/components/message/modals/MessageDelete.tsx
index 666895102..7e4fba5be 100644
--- a/src/app/components/message/modals/MessageDelete.tsx
+++ b/src/app/components/message/modals/MessageDelete.tsx
@@ -1,5 +1,6 @@
-import { FormEventHandler, MouseEvent, useCallback, useEffect } from 'react';
-import { Room, MatrixEvent } from '$types/matrix-sdk';
+import type { FormEventHandler, MouseEvent } from 'react';
+import { useCallback, useEffect } from 'react';
+import type { Room, MatrixEvent } from '$types/matrix-sdk';
import { useSetAtom } from 'jotai';
import {
Box,
diff --git a/src/app/components/message/modals/MessageEditHistory.tsx b/src/app/components/message/modals/MessageEditHistory.tsx
index 9581aa419..f806b61ae 100644
--- a/src/app/components/message/modals/MessageEditHistory.tsx
+++ b/src/app/components/message/modals/MessageEditHistory.tsx
@@ -1,5 +1,5 @@
-import { MouseEvent } from 'react';
-import { Room, MatrixEvent } from '$types/matrix-sdk';
+import type { MouseEvent } from 'react';
+import type { Room, MatrixEvent } from '$types/matrix-sdk';
import { useSetAtom } from 'jotai';
import { MenuItem, Icon, Icons, Text } from 'folds';
import { getEventEdits } from '$utils/room';
diff --git a/src/app/components/message/modals/MessageForward.tsx b/src/app/components/message/modals/MessageForward.tsx
index 133dc940e..294f47e47 100644
--- a/src/app/components/message/modals/MessageForward.tsx
+++ b/src/app/components/message/modals/MessageForward.tsx
@@ -17,7 +17,8 @@ import {
as,
} from 'folds';
import { useAtomValue, useSetAtom } from 'jotai';
-import { JoinRule, MatrixEvent, Room } from '$types/matrix-sdk';
+import type { MatrixEvent, Room } from '$types/matrix-sdk';
+import { JoinRule } from '$types/matrix-sdk';
import { useEffect, useMemo, useState } from 'react';
import { allRoomsAtom } from '$state/room-list/roomList';
import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom';
@@ -265,7 +266,7 @@ export function MessageForwardInternal({
};
}
- const msgtype = String(originalContent.msgtype ?? 'unknown');
+ const msgtype = originalContent.msgtype ?? 'unknown';
debugLog.info('ui', 'Forwarding message', {
sourceRoomId: room.roomId,
targetRoomId: targetRoom.roomId,
diff --git a/src/app/components/message/modals/MessageReactions.tsx b/src/app/components/message/modals/MessageReactions.tsx
index f2fa7a5bd..a2fbae286 100644
--- a/src/app/components/message/modals/MessageReactions.tsx
+++ b/src/app/components/message/modals/MessageReactions.tsx
@@ -1,5 +1,5 @@
-import { MouseEvent } from 'react';
-import { Room, Relations } from '$types/matrix-sdk';
+import type { MouseEvent } from 'react';
+import type { Room, Relations } from '$types/matrix-sdk';
import { useSetAtom } from 'jotai';
import { Icon, Icons, Text, MenuItem } from 'folds';
import { modalAtom, ModalType } from '$state/modal';
diff --git a/src/app/components/message/modals/MessageReadRecipts.tsx b/src/app/components/message/modals/MessageReadRecipts.tsx
index 6642627c0..6dfec9849 100644
--- a/src/app/components/message/modals/MessageReadRecipts.tsx
+++ b/src/app/components/message/modals/MessageReadRecipts.tsx
@@ -1,5 +1,5 @@
-import { MouseEvent } from 'react';
-import { Room } from '$types/matrix-sdk';
+import type { MouseEvent } from 'react';
+import type { Room } from '$types/matrix-sdk';
import { useSetAtom } from 'jotai';
import { MenuItem, Icon, Icons, Text } from 'folds';
import { modalAtom, ModalType } from '$state/modal';
diff --git a/src/app/components/message/modals/MessageReport.tsx b/src/app/components/message/modals/MessageReport.tsx
index 71cf03cc5..1d1357ddf 100644
--- a/src/app/components/message/modals/MessageReport.tsx
+++ b/src/app/components/message/modals/MessageReport.tsx
@@ -1,5 +1,6 @@
-import { FormEventHandler, MouseEvent, useCallback, useEffect } from 'react';
-import { Room, MatrixEvent } from '$types/matrix-sdk';
+import type { FormEventHandler, MouseEvent } from 'react';
+import { useCallback, useEffect } from 'react';
+import type { Room, MatrixEvent } from '$types/matrix-sdk';
import { useSetAtom } from 'jotai';
import {
Box,
diff --git a/src/app/components/message/modals/MessageSource.tsx b/src/app/components/message/modals/MessageSource.tsx
index eff8e1e58..6d186a780 100644
--- a/src/app/components/message/modals/MessageSource.tsx
+++ b/src/app/components/message/modals/MessageSource.tsx
@@ -1,5 +1,5 @@
-import { MouseEvent } from 'react';
-import { Room, MatrixEvent } from '$types/matrix-sdk';
+import type { MouseEvent } from 'react';
+import type { Room, MatrixEvent } from '$types/matrix-sdk';
import { useSetAtom } from 'jotai';
import { MenuItem, Icon, Icons, Text } from 'folds';
import { TextViewer } from '$components/text-viewer';
@@ -38,15 +38,15 @@ type MessageSourceInternalProps = {
onClose: () => void;
};
-export function MessageSourceInternal({ room, mEvent, onClose }: MessageSourceInternalProps) {
- const getContent = (evt: MatrixEvent) =>
- evt.isEncrypted()
- ? {
- [`<== DECRYPTED_EVENT ==>`]: evt.getEffectiveEvent(),
- [`<== ORIGINAL_EVENT ==>`]: evt.event,
- }
- : evt.event;
+const getContent = (evt: MatrixEvent) =>
+ evt.isEncrypted()
+ ? {
+ [`<== DECRYPTED_EVENT ==>`]: evt.getEffectiveEvent(),
+ [`<== ORIGINAL_EVENT ==>`]: evt.event,
+ }
+ : evt.event;
+export function MessageSourceInternal({ room, mEvent, onClose }: MessageSourceInternalProps) {
const getText = (): string => {
const evtId = mEvent.getId()!;
const evtTimeline = room.getTimelineForEvent(evtId);
diff --git a/src/app/components/message/placeholder/CompactPlaceholder.tsx b/src/app/components/message/placeholder/CompactPlaceholder.tsx
index c6e6dda00..f96d79497 100644
--- a/src/app/components/message/placeholder/CompactPlaceholder.tsx
+++ b/src/app/components/message/placeholder/CompactPlaceholder.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { as, ContainerColor, toRem } from 'folds';
+import type { ContainerColor } from 'folds';
+import { as, toRem } from 'folds';
import { randomNumberBetween } from '$utils/common';
import { CompactLayout } from '$components/message/layout';
import { LinePlaceholder } from './LinePlaceholder';
diff --git a/src/app/components/message/placeholder/DefaultPlaceholder.tsx b/src/app/components/message/placeholder/DefaultPlaceholder.tsx
index 444990ac6..7e9438e90 100644
--- a/src/app/components/message/placeholder/DefaultPlaceholder.tsx
+++ b/src/app/components/message/placeholder/DefaultPlaceholder.tsx
@@ -1,12 +1,18 @@
-import { CSSProperties, useMemo } from 'react';
-import { Avatar, Box, ContainerColor, as, color, toRem } from 'folds';
+import type { CSSProperties } from 'react';
+import { useMemo } from 'react';
+import type { ContainerColor } from 'folds';
+import { Avatar, Box, as, color, toRem } from 'folds';
import { randomNumberBetween } from '$utils/common';
import { ModernLayout } from '$components/message/layout';
import { LinePlaceholder } from './LinePlaceholder';
const contentMargin: CSSProperties = { marginTop: toRem(3) };
-export const DefaultPlaceholder = as<'div', { variant?: ContainerColor }>(
+type DefaultPlaceholderProps = {
+ variant?: ContainerColor;
+};
+
+export const DefaultPlaceholder = as<'div', DefaultPlaceholderProps>(
({ variant, ...props }, ref) => {
const nameSize = useMemo(() => randomNumberBetween(40, 100), []);
const msgSize = useMemo(() => randomNumberBetween(80, 200), []);
@@ -18,7 +24,9 @@ export const DefaultPlaceholder = as<'div', { variant?: ContainerColor }>(
ref={ref}
before={
}
diff --git a/src/app/components/message/placeholder/LinePlaceholder.css.ts b/src/app/components/message/placeholder/LinePlaceholder.css.ts
index 34ad76a3e..aefc3c655 100644
--- a/src/app/components/message/placeholder/LinePlaceholder.css.ts
+++ b/src/app/components/message/placeholder/LinePlaceholder.css.ts
@@ -1,6 +1,8 @@
-import { ComplexStyleRule } from '@vanilla-extract/css';
-import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
-import { ContainerColor, DefaultReset, color, config, toRem } from 'folds';
+import type { ComplexStyleRule } from '@vanilla-extract/css';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
+import type { ContainerColor } from 'folds';
+import { DefaultReset, color, config, toRem } from 'folds';
const getVariant = (variant: ContainerColor): ComplexStyleRule => ({
backgroundColor: color[variant].Container,
diff --git a/src/app/components/nav/NavCategory.tsx b/src/app/components/nav/NavCategory.tsx
index 7285330f0..8c87f84de 100644
--- a/src/app/components/nav/NavCategory.tsx
+++ b/src/app/components/nav/NavCategory.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { as } from 'folds';
import classNames from 'classnames';
import * as css from './styles.css';
diff --git a/src/app/components/nav/NavCategoryHeader.tsx b/src/app/components/nav/NavCategoryHeader.tsx
index 1d4152fc9..9c09ca186 100644
--- a/src/app/components/nav/NavCategoryHeader.tsx
+++ b/src/app/components/nav/NavCategoryHeader.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import classNames from 'classnames';
import { Header, as } from 'folds';
import * as css from './styles.css';
diff --git a/src/app/components/nav/NavEmptyLayout.tsx b/src/app/components/nav/NavEmptyLayout.tsx
index 25b69380b..6b110cac7 100644
--- a/src/app/components/nav/NavEmptyLayout.tsx
+++ b/src/app/components/nav/NavEmptyLayout.tsx
@@ -1,5 +1,5 @@
import { Box, config } from 'folds';
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
export function NavEmptyCenter({ children }: { children: ReactNode }) {
return (
diff --git a/src/app/components/nav/NavItem.tsx b/src/app/components/nav/NavItem.tsx
index 68a967f6f..673baea9d 100644
--- a/src/app/components/nav/NavItem.tsx
+++ b/src/app/components/nav/NavItem.tsx
@@ -1,24 +1,22 @@
import classNames from 'classnames';
-import { ComponentProps, forwardRef } from 'react';
+import type { ComponentProps } from 'react';
+import { forwardRef } from 'react';
import { Link } from 'react-router-dom';
import { as } from 'folds';
import * as css from './styles.css';
-export const NavItem = as<
- 'div',
- {
- highlight?: boolean;
- } & css.RoomSelectorVariants
->(({ as: AsNavItem = 'div', className, highlight, variant, radii, children, ...props }, ref) => (
-
- {children}
-
-));
+export const NavItem = as<'div', { highlight?: boolean } & css.RoomSelectorVariants>(
+ ({ as: AsNavItem = 'div', className, highlight, variant, radii, children, ...props }, ref) => (
+
+ {children}
+
+ )
+);
export const NavLink = forwardRef>(
({ className, ...props }, ref) => (
diff --git a/src/app/components/nav/NavItemContent.tsx b/src/app/components/nav/NavItemContent.tsx
index eaf8f113e..a6aa6e985 100644
--- a/src/app/components/nav/NavItemContent.tsx
+++ b/src/app/components/nav/NavItemContent.tsx
@@ -1,4 +1,4 @@
-import { ComponentProps } from 'react';
+import type { ComponentProps } from 'react';
import { Text, as } from 'folds';
import classNames from 'classnames';
import * as css from './styles.css';
diff --git a/src/app/components/nav/NavItemOptions.tsx b/src/app/components/nav/NavItemOptions.tsx
index a735781e5..1929dfff2 100644
--- a/src/app/components/nav/NavItemOptions.tsx
+++ b/src/app/components/nav/NavItemOptions.tsx
@@ -1,4 +1,4 @@
-import { ComponentProps } from 'react';
+import type { ComponentProps } from 'react';
import { Box, as } from 'folds';
import classNames from 'classnames';
import * as css from './styles.css';
diff --git a/src/app/components/nav/styles.css.ts b/src/app/components/nav/styles.css.ts
index 48b2a4d34..f72d3fe38 100644
--- a/src/app/components/nav/styles.css.ts
+++ b/src/app/components/nav/styles.css.ts
@@ -1,6 +1,9 @@
-import { ComplexStyleRule, createVar, style } from '@vanilla-extract/css';
-import { RecipeVariants, recipe } from '@vanilla-extract/recipes';
-import { ContainerColor, DefaultReset, Disabled, RadiiVariant, color, config, toRem } from 'folds';
+import type { ComplexStyleRule } from '@vanilla-extract/css';
+import { createVar, style } from '@vanilla-extract/css';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
+import type { ContainerColor } from 'folds';
+import { DefaultReset, Disabled, RadiiVariant, color, config, toRem } from 'folds';
export const NavCategory = style([
DefaultReset,
diff --git a/src/app/components/notification-banner/NotificationBanner.tsx b/src/app/components/notification-banner/NotificationBanner.tsx
index b574e3585..4476e8389 100644
--- a/src/app/components/notification-banner/NotificationBanner.tsx
+++ b/src/app/components/notification-banner/NotificationBanner.tsx
@@ -1,8 +1,10 @@
import { useAtom } from 'jotai';
-import { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
+import type { ReactNode } from 'react';
+import { useCallback, useEffect, useRef, useState } from 'react';
import { Box, Icon, IconButton, Icons, Text } from 'folds';
import { createLogger } from '$utils/debug';
-import { inAppBannerAtom, InAppBannerNotification } from '$state/sessions';
+import type { InAppBannerNotification } from '$state/sessions';
+import { inAppBannerAtom } from '$state/sessions';
import * as css from './NotificationBanner.css';
const log = createLogger('NotificationBanner');
diff --git a/src/app/components/page/Page.tsx b/src/app/components/page/Page.tsx
index b481df637..c6bb22d44 100644
--- a/src/app/components/page/Page.tsx
+++ b/src/app/components/page/Page.tsx
@@ -1,4 +1,4 @@
-import { ComponentProps, MutableRefObject, ReactNode } from 'react';
+import type { ComponentProps, MutableRefObject, ReactNode } from 'react';
import { Box, Header, Line, Scroll, Text, as } from 'folds';
import classNames from 'classnames';
import { ContainerColor } from '$styles/ContainerColor.css';
diff --git a/src/app/components/page/style.css.ts b/src/app/components/page/style.css.ts
index bd14cd583..d35fa651d 100644
--- a/src/app/components/page/style.css.ts
+++ b/src/app/components/page/style.css.ts
@@ -1,5 +1,6 @@
import { style } from '@vanilla-extract/css';
-import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
import { DefaultReset, color, config, toRem } from 'folds';
export const PageNav = recipe({
diff --git a/src/app/components/password-input/PasswordInput.tsx b/src/app/components/password-input/PasswordInput.tsx
index d1fdea246..d859af8d7 100644
--- a/src/app/components/password-input/PasswordInput.tsx
+++ b/src/app/components/password-input/PasswordInput.tsx
@@ -1,4 +1,5 @@
-import { ComponentProps, forwardRef } from 'react';
+import type { ComponentProps } from 'react';
+import { forwardRef } from 'react';
import { Icon, IconButton, Input, config, Icons } from 'folds';
import { UseStateProvider } from '$components/UseStateProvider';
diff --git a/src/app/components/power/PowerSelector.tsx b/src/app/components/power/PowerSelector.tsx
index 23188aeae..8d4d61876 100644
--- a/src/app/components/power/PowerSelector.tsx
+++ b/src/app/components/power/PowerSelector.tsx
@@ -1,7 +1,10 @@
-import { forwardRef, MouseEventHandler, ReactNode, useState } from 'react';
+import type { MouseEventHandler, ReactNode } from 'react';
+import { forwardRef, useState } from 'react';
import FocusTrap from 'focus-trap-react';
-import { Box, config, Menu, MenuItem, PopOut, Scroll, Text, toRem, RectCords } from 'folds';
-import { getPowers, PowerLevelTags } from '$hooks/usePowerLevelTags';
+import type { RectCords } from 'folds';
+import { Box, config, Menu, MenuItem, PopOut, Scroll, Text, toRem } from 'folds';
+import type { PowerLevelTags } from '$hooks/usePowerLevelTags';
+import { getPowers } from '$hooks/usePowerLevelTags';
import { stopPropagation } from '$utils/keyboard';
import { PowerColorBadge } from './PowerColorBadge';
@@ -33,11 +36,11 @@ export const PowerSelector = forwardRef(
aria-pressed={selected}
radii="300"
onClick={selected ? undefined : () => onChange(power)}
- before={}
+ before={}
after={{power}}
>
- {tag.name}
+ {tag!.name}
);
diff --git a/src/app/components/power/style.css.ts b/src/app/components/power/style.css.ts
index 60737f8cb..d0ccc88fc 100644
--- a/src/app/components/power/style.css.ts
+++ b/src/app/components/power/style.css.ts
@@ -1,5 +1,6 @@
import { createVar, style } from '@vanilla-extract/css';
-import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
import { color, config, DefaultReset, toRem } from 'folds';
export const PowerColorBadge = style({
diff --git a/src/app/components/presence/Presence.tsx b/src/app/components/presence/Presence.tsx
index e6ac463bb..88543b7f6 100644
--- a/src/app/components/presence/Presence.tsx
+++ b/src/app/components/presence/Presence.tsx
@@ -1,16 +1,7 @@
-import {
- as,
- Badge,
- Box,
- color,
- ContainerColor,
- MainColor,
- Text,
- Tooltip,
- TooltipProvider,
- toRem,
-} from 'folds';
-import { ReactNode, useId } from 'react';
+import type { ContainerColor, MainColor } from 'folds';
+import { as, Badge, Box, color, Text, Tooltip, TooltipProvider, toRem } from 'folds';
+import type { ReactNode } from 'react';
+import { useId } from 'react';
import { Presence, usePresenceLabel } from '$hooks/useUserPresence';
import * as css from './styles.css';
diff --git a/src/app/components/room-avatar/AvatarImage.tsx b/src/app/components/room-avatar/AvatarImage.tsx
index 1e4cb0d0a..f322bce0e 100644
--- a/src/app/components/room-avatar/AvatarImage.tsx
+++ b/src/app/components/room-avatar/AvatarImage.tsx
@@ -1,5 +1,6 @@
import { AvatarImage as FoldsAvatarImage } from 'folds';
-import { ReactEventHandler, useState, useEffect } from 'react';
+import type { ReactEventHandler } from 'react';
+import { useState, useEffect } from 'react';
import bgColorImg from '$utils/bgColorImg';
import { settingsAtom } from '$state/settings';
import { useSetting } from '$state/hooks/settings';
diff --git a/src/app/components/room-avatar/RoomAvatar.tsx b/src/app/components/room-avatar/RoomAvatar.tsx
index 33f9f6881..fa8acd4e5 100644
--- a/src/app/components/room-avatar/RoomAvatar.tsx
+++ b/src/app/components/room-avatar/RoomAvatar.tsx
@@ -1,6 +1,7 @@
-import { JoinRule } from '$types/matrix-sdk';
+import type { JoinRule } from '$types/matrix-sdk';
import { AvatarFallback, Icon, Icons, color } from 'folds';
-import { ComponentProps, ReactNode, forwardRef, useEffect, useState } from 'react';
+import type { ComponentProps, ReactNode } from 'react';
+import { forwardRef, useEffect, useState } from 'react';
import { getRoomIconSrc } from '$utils/room';
import colorMXID from '$utils/colorMXID';
import * as css from './RoomAvatar.css';
diff --git a/src/app/components/room-card/RoomCard.tsx b/src/app/components/room-card/RoomCard.tsx
index 7f9046d77..39630e745 100644
--- a/src/app/components/room-card/RoomCard.tsx
+++ b/src/app/components/room-card/RoomCard.tsx
@@ -1,5 +1,7 @@
-import { ReactNode, useCallback, useRef, useState } from 'react';
-import { JoinRule, MatrixError, Room } from '$types/matrix-sdk';
+import type { ReactNode } from 'react';
+import { useCallback, useRef, useState } from 'react';
+import type { MatrixError, Room } from '$types/matrix-sdk';
+import { JoinRule } from '$types/matrix-sdk';
import {
Avatar,
Badge,
@@ -195,7 +197,7 @@ export const RoomCard = as<'div', RoomCardProps>(
if (
joinedRoom &&
event.getRoomId() === joinedRoom.roomId &&
- event.getType() === StateEvent.RoomTopic
+ event.getType() === (StateEvent.RoomTopic as string)
) {
setTopicEvent(getStateEvent(joinedRoom, StateEvent.RoomTopic));
}
diff --git a/src/app/components/room-intro/RoomIntro.tsx b/src/app/components/room-intro/RoomIntro.tsx
index 3ad39546f..09757edba 100644
--- a/src/app/components/room-intro/RoomIntro.tsx
+++ b/src/app/components/room-intro/RoomIntro.tsx
@@ -1,8 +1,9 @@
import { useCallback, useEffect, useState } from 'react';
import { Avatar, Box, Button, Icon, Icons, Spinner, Text, as } from 'folds';
-import { Room } from '$types/matrix-sdk';
+import type { Room } from '$types/matrix-sdk';
import { useAtomValue } from 'jotai';
-import { IRoomCreateContent, Membership, StateEvent } from '$types/matrix/room';
+import type { IRoomCreateContent } from '$types/matrix/room';
+import { Membership, StateEvent } from '$types/matrix/room';
import { getMemberDisplayName, getStateEvent } from '$utils/room';
import { nicknamesAtom } from '$state/nicknames';
import { useMatrixClient } from '$hooks/useMatrixClient';
diff --git a/src/app/components/scroll-top-container/ScrollTopContainer.tsx b/src/app/components/scroll-top-container/ScrollTopContainer.tsx
index 4681e7baf..e9d2915a3 100644
--- a/src/app/components/scroll-top-container/ScrollTopContainer.tsx
+++ b/src/app/components/scroll-top-container/ScrollTopContainer.tsx
@@ -1,4 +1,5 @@
-import { RefObject, useCallback, useState } from 'react';
+import type { RefObject } from 'react';
+import { useCallback, useState } from 'react';
import { Box, as } from 'folds';
import classNames from 'classnames';
import {
diff --git a/src/app/components/sequence-card/SequenceCard.tsx b/src/app/components/sequence-card/SequenceCard.tsx
index 810afd3da..3db7d0bf5 100644
--- a/src/app/components/sequence-card/SequenceCard.tsx
+++ b/src/app/components/sequence-card/SequenceCard.tsx
@@ -1,7 +1,8 @@
-import { ComponentProps } from 'react';
+import type { ComponentProps } from 'react';
import { Box, as } from 'folds';
import classNames from 'classnames';
-import { ContainerColor, ContainerColorVariants } from '$styles/ContainerColor.css';
+import type { ContainerColorVariants } from '$styles/ContainerColor.css';
+import { ContainerColor } from '$styles/ContainerColor.css';
import * as css from './style.css';
export const SequenceCard = as<
diff --git a/src/app/components/sequence-card/style.css.ts b/src/app/components/sequence-card/style.css.ts
index 2665b46e7..dc027da7f 100644
--- a/src/app/components/sequence-card/style.css.ts
+++ b/src/app/components/sequence-card/style.css.ts
@@ -1,5 +1,6 @@
import { createVar } from '@vanilla-extract/css';
-import { RecipeVariants, recipe } from '@vanilla-extract/recipes';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
import { config } from 'folds';
const outlinedWidth = createVar('0');
diff --git a/src/app/components/setting-menu-selector/SettingMenuSelector.test.tsx b/src/app/components/setting-menu-selector/SettingMenuSelector.test.tsx
index 60fd7453b..5941f15ba 100644
--- a/src/app/components/setting-menu-selector/SettingMenuSelector.test.tsx
+++ b/src/app/components/setting-menu-selector/SettingMenuSelector.test.tsx
@@ -5,7 +5,7 @@ import { SettingMenuSelector, type SettingMenuOption } from './SettingMenuSelect
describe('SettingMenuSelector', () => {
it('renders the selected label, opens the menu, and selects an option', () => {
- const onSelect = vi.fn();
+ const onSelect = vi.fn<(value: 'light' | 'dark') => void>();
const options: SettingMenuOption<'light' | 'dark'>[] = [
{ value: 'light', label: 'Light', description: 'Plain theme' },
{ value: 'dark', label: 'Dark', description: 'High contrast' },
@@ -28,7 +28,7 @@ describe('SettingMenuSelector', () => {
});
it('disables the trigger while loading', () => {
- const onSelect = vi.fn();
+ const onSelect = vi.fn<() => void>();
render(
{
});
it('supports custom trigger and option rendering', () => {
- const onSelect = vi.fn();
+ const onSelect = vi.fn<(value: 'one' | 'two') => void>();
const options: SettingMenuOption<'one' | 'two'>[] = [
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two' },
diff --git a/src/app/components/setting-menu-selector/SettingMenuSelector.tsx b/src/app/components/setting-menu-selector/SettingMenuSelector.tsx
index 3e39dd243..6717313b2 100644
--- a/src/app/components/setting-menu-selector/SettingMenuSelector.tsx
+++ b/src/app/components/setting-menu-selector/SettingMenuSelector.tsx
@@ -1,17 +1,6 @@
import FocusTrap from 'focus-trap-react';
-import {
- Box,
- Button,
- config,
- Icon,
- Icons,
- Menu,
- MenuItem,
- PopOut,
- RectCords,
- Spinner,
- Text,
-} from 'folds';
+import type { RectCords } from 'folds';
+import { Box, Button, config, Icon, Icons, Menu, MenuItem, PopOut, Spinner, Text } from 'folds';
import {
type ComponentPropsWithoutRef,
type MouseEventHandler,
diff --git a/src/app/components/setting-tile/SettingTile.test.tsx b/src/app/components/setting-tile/SettingTile.test.tsx
index da5d25c10..1ae2ba5d5 100644
--- a/src/app/components/setting-tile/SettingTile.test.tsx
+++ b/src/app/components/setting-tile/SettingTile.test.tsx
@@ -10,7 +10,7 @@ import {
settingTileSettingLinkActionTransparentBackground,
} from './SettingTile.css';
-const writeText = vi.fn();
+const writeText = vi.fn<() => Promise>();
function renderTile(
screenSize: ScreenSize,
diff --git a/src/app/components/setting-tile/SettingTile.tsx b/src/app/components/setting-tile/SettingTile.tsx
index 9ee2696dc..7c3982442 100644
--- a/src/app/components/setting-tile/SettingTile.tsx
+++ b/src/app/components/setting-tile/SettingTile.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { Box, Icon, IconButton, Icons, Text } from 'folds';
import { BreakWord } from '$styles/Text.css';
import { buildSettingsLink } from '$features/settings/settingsLink';
diff --git a/src/app/components/sidebar/Sidebar.css.ts b/src/app/components/sidebar/Sidebar.css.ts
index 2952a0f7d..e82e3934a 100644
--- a/src/app/components/sidebar/Sidebar.css.ts
+++ b/src/app/components/sidebar/Sidebar.css.ts
@@ -1,5 +1,6 @@
import { createVar, style } from '@vanilla-extract/css';
-import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
import { color, config, DefaultReset, Disabled, FocusOutline, toRem } from 'folds';
import { ContainerColor } from '$styles/ContainerColor.css';
diff --git a/src/app/components/sidebar/SidebarContent.tsx b/src/app/components/sidebar/SidebarContent.tsx
index a4546b196..1faa5ab06 100644
--- a/src/app/components/sidebar/SidebarContent.tsx
+++ b/src/app/components/sidebar/SidebarContent.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { Box } from 'folds';
type SidebarContentProps = {
diff --git a/src/app/components/sidebar/SidebarItem.tsx b/src/app/components/sidebar/SidebarItem.tsx
index b624bf0c9..9b7f7ec12 100644
--- a/src/app/components/sidebar/SidebarItem.tsx
+++ b/src/app/components/sidebar/SidebarItem.tsx
@@ -1,6 +1,6 @@
import classNames from 'classnames';
import { as, Avatar, Text, Tooltip, TooltipProvider, toRem } from 'folds';
-import { ComponentProps, ReactNode, RefCallback } from 'react';
+import type { ComponentProps, ReactNode, RefCallback } from 'react';
import * as css from './Sidebar.css';
export const SidebarItem = as<'div', css.SidebarItemVariants>(
diff --git a/src/app/components/sidebar/SidebarUnreadBadge.tsx b/src/app/components/sidebar/SidebarUnreadBadge.tsx
index df1f5b7ee..42476cc6b 100644
--- a/src/app/components/sidebar/SidebarUnreadBadge.tsx
+++ b/src/app/components/sidebar/SidebarUnreadBadge.tsx
@@ -1,4 +1,5 @@
-import { UnreadBadge, UnreadBadgeMode, resolveUnreadBadgeMode } from '$components/unread-badge';
+import type { UnreadBadgeMode } from '$components/unread-badge';
+import { UnreadBadge, resolveUnreadBadgeMode } from '$components/unread-badge';
import { useSetting } from '$state/hooks/settings';
import { settingsAtom } from '$state/settings';
import { SidebarItemBadge } from './SidebarItem';
diff --git a/src/app/components/splash-screen/SplashScreen.tsx b/src/app/components/splash-screen/SplashScreen.tsx
index 463fd66d6..4ddf2ca8a 100644
--- a/src/app/components/splash-screen/SplashScreen.tsx
+++ b/src/app/components/splash-screen/SplashScreen.tsx
@@ -1,5 +1,5 @@
import { Box, Text } from 'folds';
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import classNames from 'classnames';
import * as patternsCSS from '$styles/Patterns.css';
import * as css from './SplashScreen.css';
diff --git a/src/app/components/stacked-avatar/StackedAvatar.tsx b/src/app/components/stacked-avatar/StackedAvatar.tsx
index 78ca8a4c3..f45d4dd49 100644
--- a/src/app/components/stacked-avatar/StackedAvatar.tsx
+++ b/src/app/components/stacked-avatar/StackedAvatar.tsx
@@ -5,6 +5,7 @@ import * as css from './styles.css';
type StackedAvatarProps = {
radii?: '0' | '300' | '400' | '500' | 'Pill' | 'Inherit' | undefined;
};
+
export const StackedAvatar = as<'span', css.StackedAvatarVariants & StackedAvatarProps>(
({ size, variant, className, ...props }, ref) => (
({
outlineColor: color[variant].Container,
diff --git a/src/app/components/telemetry-consent/TelemetryConsentBanner.test.tsx b/src/app/components/telemetry-consent/TelemetryConsentBanner.test.tsx
index a1030889e..666d9a5bb 100644
--- a/src/app/components/telemetry-consent/TelemetryConsentBanner.test.tsx
+++ b/src/app/components/telemetry-consent/TelemetryConsentBanner.test.tsx
@@ -8,7 +8,7 @@ const TEST_DSN = 'https://examplePublicKey@o0.ingest.sentry.io/0';
describe('TelemetryConsentBanner', () => {
beforeEach(() => {
localStorage.clear();
- vi.stubGlobal('location', { reload: vi.fn() });
+ vi.stubGlobal('location', { reload: vi.fn<() => void>() });
});
afterEach(() => {
diff --git a/src/app/components/text-viewer/TextViewer.test.tsx b/src/app/components/text-viewer/TextViewer.test.tsx
index 2112b0f14..8308ec100 100644
--- a/src/app/components/text-viewer/TextViewer.test.tsx
+++ b/src/app/components/text-viewer/TextViewer.test.tsx
@@ -5,9 +5,15 @@ import { TextViewer } from './TextViewer';
import * as css from './TextViewer.css';
const { copyToClipboard, CodeHighlightRenderer } = vi.hoisted(() => ({
- copyToClipboard: vi.fn(),
- CodeHighlightRenderer: vi.fn(({ code, language, allowDetect }) => (
-
+ copyToClipboard: vi.fn<() => Promise>(),
+ CodeHighlightRenderer: vi.fn<
+ (props: { code: string; language?: string; allowDetect?: boolean }) => JSX.Element
+ >(({ code, language, allowDetect }) => (
+
{code}
)),
@@ -30,7 +36,12 @@ describe('TextViewer', () => {
const user = userEvent.setup();
render(
-
+ void>()}
+ />
);
expect(CodeHighlightRenderer).toHaveBeenCalled();
diff --git a/src/app/components/text-viewer/TextViewer.tsx b/src/app/components/text-viewer/TextViewer.tsx
index c2d06937c..74cd47188 100644
--- a/src/app/components/text-viewer/TextViewer.tsx
+++ b/src/app/components/text-viewer/TextViewer.tsx
@@ -1,4 +1,5 @@
-import { ComponentProps, HTMLAttributes, forwardRef } from 'react';
+import type { ComponentProps, HTMLAttributes } from 'react';
+import { forwardRef } from 'react';
import classNames from 'classnames';
import { Box, Chip, Header, Icon, IconButton, Icons, Scroll, Text, as } from 'folds';
import { CodeHighlightRenderer } from '$components/code-highlight';
diff --git a/src/app/components/time-date/DatePicker.tsx b/src/app/components/time-date/DatePicker.tsx
index 078d91d8e..93934d618 100644
--- a/src/app/components/time-date/DatePicker.tsx
+++ b/src/app/components/time-date/DatePicker.tsx
@@ -60,9 +60,8 @@ export const DatePicker = forwardRef(
diff --git a/src/app/components/time-date/PickerColumn.tsx b/src/app/components/time-date/PickerColumn.tsx
index a1fbcb34f..d7f849e61 100644
--- a/src/app/components/time-date/PickerColumn.tsx
+++ b/src/app/components/time-date/PickerColumn.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { Box, Text, Scroll } from 'folds';
import { CutoutCard } from '$components/cutout-card';
import * as css from './styles.css';
diff --git a/src/app/components/time-date/TimePicker.tsx b/src/app/components/time-date/TimePicker.tsx
index c16ad7caa..dd3e1a4e6 100644
--- a/src/app/components/time-date/TimePicker.tsx
+++ b/src/app/components/time-date/TimePicker.tsx
@@ -64,7 +64,7 @@ export const TimePicker = forwardRef(
{hour24Clock
- ? Array.from(new Array(24).keys()).map((hour) => (
+ ? Array.from({ length: 24 }, (_, i) => i).map((hour) => (
(
{hour < 10 ? `0${hour}` : hour}
))
- : Array.from(new Array(12).keys())
- .map((i) => {
- if (i === 0) return 12;
- return i;
- })
- .map((hour) => (
- handleHour(hour)}
- disabled={
- (minDay && hour12to24(hour, selectedPM) < minHour24) ||
- (maxDay && hour12to24(hour, selectedPM) > maxHour24)
- }
- >
- {hour < 10 ? `0${hour}` : hour}
-
- ))}
+ : Array.from({ length: 12 }, (_, i) => {
+ if (i === 0) return 12;
+ return i;
+ }).map((hour) => (
+ handleHour(hour)}
+ disabled={
+ (minDay && hour12to24(hour, selectedPM) < minHour24) ||
+ (maxDay && hour12to24(hour, selectedPM) > maxHour24)
+ }
+ >
+ {hour < 10 ? `0${hour}` : hour}
+
+ ))}
- {Array.from(new Array(60).keys()).map((minute) => (
+ {Array.from({ length: 60 }, (_, i) => i).map((minute) => (
- {errorCode === ErrorCode.M_FORBIDDEN
+ {errorCode === (ErrorCode.M_FORBIDDEN as string)
? 'Invalid Password!'
: `${errorCode}: ${error}`}
diff --git a/src/app/components/uia-stages/ReCaptchaStage.tsx b/src/app/components/uia-stages/ReCaptchaStage.tsx
index 65357b0e4..dcd2ec4c7 100644
--- a/src/app/components/uia-stages/ReCaptchaStage.tsx
+++ b/src/app/components/uia-stages/ReCaptchaStage.tsx
@@ -1,7 +1,7 @@
import { Dialog, Text, Box, Button, config } from 'folds';
import { AuthType } from '$types/matrix-sdk';
import ReCAPTCHA from 'react-google-recaptcha';
-import { StageComponentProps } from './types';
+import type { StageComponentProps } from './types';
function ReCaptchaErrorDialog({
title,
diff --git a/src/app/components/uia-stages/RegistrationTokenStage.tsx b/src/app/components/uia-stages/RegistrationTokenStage.tsx
index cfe79786c..3e71cbc3d 100644
--- a/src/app/components/uia-stages/RegistrationTokenStage.tsx
+++ b/src/app/components/uia-stages/RegistrationTokenStage.tsx
@@ -1,7 +1,8 @@
-import { useEffect, useCallback, FormEventHandler } from 'react';
+import type { FormEventHandler } from 'react';
+import { useEffect, useCallback } from 'react';
import { Dialog, Text, Box, Button, config, Input } from 'folds';
import { AuthType } from '$types/matrix-sdk';
-import { StageComponentProps } from './types';
+import type { StageComponentProps } from './types';
function RegistrationTokenErrorDialog({
title,
diff --git a/src/app/components/uia-stages/SSOStage.tsx b/src/app/components/uia-stages/SSOStage.tsx
index fb20e03b1..6de4cbdfd 100644
--- a/src/app/components/uia-stages/SSOStage.tsx
+++ b/src/app/components/uia-stages/SSOStage.tsx
@@ -1,6 +1,6 @@
import { Box, Button, color, config, Dialog, Header, Icon, IconButton, Icons, Text } from 'folds';
import { useCallback, useEffect, useState } from 'react';
-import { StageComponentProps } from './types';
+import type { StageComponentProps } from './types';
export function SSOStage({
ssoRedirectURL,
diff --git a/src/app/components/uia-stages/TermsStage.tsx b/src/app/components/uia-stages/TermsStage.tsx
index bfe8e4032..d4789aa86 100644
--- a/src/app/components/uia-stages/TermsStage.tsx
+++ b/src/app/components/uia-stages/TermsStage.tsx
@@ -1,7 +1,7 @@
import { useEffect, useCallback } from 'react';
import { Dialog, Text, Box, Button, config } from 'folds';
import { AuthType } from '$types/matrix-sdk';
-import { StageComponentProps } from './types';
+import type { StageComponentProps } from './types';
function TermsErrorDialog({
title,
diff --git a/src/app/components/uia-stages/types.ts b/src/app/components/uia-stages/types.ts
index 3408cd013..72256e8a9 100644
--- a/src/app/components/uia-stages/types.ts
+++ b/src/app/components/uia-stages/types.ts
@@ -1,5 +1,5 @@
-import { AuthDict } from '$types/matrix-sdk';
-import { AuthStageData } from '$hooks/useUIAFlows';
+import type { AuthDict } from '$types/matrix-sdk';
+import type { AuthStageData } from '$hooks/useUIAFlows';
export type StageComponentProps = {
stageData: AuthStageData;
diff --git a/src/app/components/unread-badge/UnreadBadge.tsx b/src/app/components/unread-badge/UnreadBadge.tsx
index c623795de..6f86f87e7 100644
--- a/src/app/components/unread-badge/UnreadBadge.tsx
+++ b/src/app/components/unread-badge/UnreadBadge.tsx
@@ -1,4 +1,4 @@
-import { CSSProperties, ReactNode } from 'react';
+import type { CSSProperties, ReactNode } from 'react';
import { Box, Badge, toRem, Text } from 'folds';
import { useSetting } from '$state/hooks/settings';
import { settingsAtom } from '$state/settings';
diff --git a/src/app/components/upload-board/UploadBoard.tsx b/src/app/components/upload-board/UploadBoard.tsx
index 8f71c22e9..ff808124f 100644
--- a/src/app/components/upload-board/UploadBoard.tsx
+++ b/src/app/components/upload-board/UploadBoard.tsx
@@ -1,9 +1,11 @@
-import { MutableRefObject, ReactNode, useImperativeHandle, useRef } from 'react';
+import type { MutableRefObject, ReactNode } from 'react';
+import { useImperativeHandle, useRef } from 'react';
import { Badge, Box, Chip, Header, Icon, Icons, Spinner, Text, as, percent } from 'folds';
import classNames from 'classnames';
import { useAtomValue } from 'jotai';
-import { TUploadFamilyObserverAtom, Upload, UploadStatus, UploadSuccess } from '$state/upload';
+import type { TUploadFamilyObserverAtom, Upload, UploadSuccess } from '$state/upload';
+import { UploadStatus } from '$state/upload';
import * as css from './UploadBoard.css';
type UploadBoardProps = {
diff --git a/src/app/components/upload-card/CompactUploadCardRenderer.tsx b/src/app/components/upload-card/CompactUploadCardRenderer.tsx
index c4f5cdfa2..06378d450 100644
--- a/src/app/components/upload-card/CompactUploadCardRenderer.tsx
+++ b/src/app/components/upload-card/CompactUploadCardRenderer.tsx
@@ -1,8 +1,9 @@
import { useEffect } from 'react';
import { Chip, Icon, IconButton, Icons, Text, color } from 'folds';
-import { TUploadAtom, UploadStatus, UploadSuccess, useBindUploadAtom } from '$state/upload';
+import type { TUploadAtom, UploadSuccess } from '$state/upload';
+import { UploadStatus, useBindUploadAtom } from '$state/upload';
import { useMatrixClient } from '$hooks/useMatrixClient';
-import { TUploadContent } from '$utils/matrix';
+import type { TUploadContent } from '$utils/matrix';
import { bytesToSize, getFileTypeIcon } from '$utils/common';
import { useMediaConfig } from '$hooks/useMediaConfig';
import { UploadCard, UploadCardError, CompactUploadCardProgress } from './UploadCard';
diff --git a/src/app/components/upload-card/UploadCard.css.ts b/src/app/components/upload-card/UploadCard.css.ts
index d02cbe3f5..03bde3049 100644
--- a/src/app/components/upload-card/UploadCard.css.ts
+++ b/src/app/components/upload-card/UploadCard.css.ts
@@ -1,5 +1,6 @@
import { style } from '@vanilla-extract/css';
-import { RecipeVariants, recipe } from '@vanilla-extract/recipes';
+import type { RecipeVariants } from '@vanilla-extract/recipes';
+import { recipe } from '@vanilla-extract/recipes';
import { DefaultReset, RadiiVariant, color, config, toRem } from 'folds';
export const UploadCard = recipe({
diff --git a/src/app/components/upload-card/UploadCard.tsx b/src/app/components/upload-card/UploadCard.tsx
index bfe11d475..bbab67a25 100644
--- a/src/app/components/upload-card/UploadCard.tsx
+++ b/src/app/components/upload-card/UploadCard.tsx
@@ -1,5 +1,6 @@
import { Badge, Box, Icon, Icons, ProgressBar, Text, percent } from 'folds';
-import { ReactNode, forwardRef } from 'react';
+import type { ReactNode } from 'react';
+import { forwardRef } from 'react';
import { bytesToSize } from '$utils/common';
import * as css from './UploadCard.css';
diff --git a/src/app/components/upload-card/UploadCardRenderer.tsx b/src/app/components/upload-card/UploadCardRenderer.tsx
index d97a29f54..a9378059e 100644
--- a/src/app/components/upload-card/UploadCardRenderer.tsx
+++ b/src/app/components/upload-card/UploadCardRenderer.tsx
@@ -1,4 +1,5 @@
-import { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
+import type { ReactNode } from 'react';
+import { useEffect, useMemo, useRef, useState } from 'react';
import {
Box,
Chip,
@@ -13,18 +14,20 @@ import {
config,
toRem,
} from 'folds';
-import { HTMLReactParserOptions } from 'html-react-parser';
+import type { HTMLReactParserOptions } from 'html-react-parser';
import { Play, Pause } from '@phosphor-icons/react';
import { useMediaAuthentication } from '$hooks/useMediaAuthentication';
-import { Opts as LinkifyOpts } from 'linkifyjs';
+import type { Opts as LinkifyOpts } from 'linkifyjs';
import { getReactCustomHtmlParser, LINKIFY_OPTS } from '$plugins/react-custom-html-parser';
import { useSpoilerClickHandler } from '$hooks/useSpoilerClickHandler';
import { RenderBody } from '$components/message';
-import { UploadStatus, UploadSuccess, useBindUploadAtom } from '$state/upload';
+import type { UploadSuccess } from '$state/upload';
+import { UploadStatus, useBindUploadAtom } from '$state/upload';
import { useMatrixClient } from '$hooks/useMatrixClient';
-import { TUploadContent } from '$utils/matrix';
+import type { TUploadContent } from '$utils/matrix';
import { bytesToSize, getFileTypeIcon } from '$utils/common';
-import { roomUploadAtomFamily, TUploadItem, TUploadMetadata } from '$state/room/roomInputDrafts';
+import type { TUploadItem, TUploadMetadata } from '$state/room/roomInputDrafts';
+import { roomUploadAtomFamily } from '$state/room/roomInputDrafts';
import { useObjectURL } from '$hooks/useObjectURL';
import { useMediaConfig } from '$hooks/useMediaConfig';
import { useSettingsLinkBaseUrl } from '$features/settings/useSettingsLinkBaseUrl';
@@ -61,7 +64,7 @@ function PreviewVideo({ fileItem }: Readonly) {
const fileUrl = useObjectURL(originalFile);
return (
- // eslint-disable-next-line jsx-a11y/media-has-caption
+ // oxlint-disable-next-line jsx-a11y/media-has-caption