From 9aa401b517aaebc62a87d0efb94b100c12589a8c Mon Sep 17 00:00:00 2001 From: hazre Date: Sat, 28 Mar 2026 17:25:06 +0100 Subject: [PATCH 01/11] chore: refresh tsconfig and tooling --- .gitignore | 2 + eslint.config.js | 53 ++ knip.json | 3 +- package.json | 25 +- pnpm-lock.yaml | 734 ++++++++++++++++++++------ scripts/import-rewrites.test.js | 73 +++ scripts/migrate-matrix-sdk-imports.js | 234 ++++++++ scripts/normalize-imports.js | 205 +------ scripts/utils/import-rewrites.js | 280 ++++++++++ src/app/components/editor/output.ts | 7 +- src/app/pages/Router.tsx | 5 +- tsconfig.json | 45 +- tsconfig.node.json | 29 + tsconfig.web.json | 52 ++ vite.config.ts | 14 +- vitest.config.ts | 17 +- 16 files changed, 1350 insertions(+), 428 deletions(-) create mode 100644 scripts/import-rewrites.test.js create mode 100644 scripts/migrate-matrix-sdk-imports.js create mode 100644 scripts/utils/import-rewrites.js create mode 100644 tsconfig.node.json create mode 100644 tsconfig.web.json diff --git a/.gitignore b/.gitignore index d6c83cfb1..fce1c2439 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ dist coverage node_modules devAssets +.tsbuildinfo +*.tsbuildinfo .DS_Store .idea diff --git a/eslint.config.js b/eslint.config.js index 9fa0c87bb..dc2a2ebc6 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,9 +1,11 @@ import path from 'node:path'; +import e18ePlugin from '@e18e/eslint-plugin'; import { includeIgnoreFile } from '@eslint/compat'; import js from '@eslint/js'; import { defineConfig } from 'eslint/config'; import { configs, helpers, plugins } from 'eslint-config-airbnb-extended'; +import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript'; import { rules as prettierConfigRules } from 'eslint-config-prettier'; import prettierPlugin from 'eslint-plugin-prettier'; import reactPlugin from 'eslint-plugin-react'; @@ -66,10 +68,53 @@ const prettierConfig = defineConfig([ }, ]); +const e18eConfig = defineConfig([ + { + name: 'e18e/scripts', + files: ['scripts/**/*.js'], + plugins: { + e18e: e18ePlugin, + }, + rules: { + 'e18e/prefer-array-at': 'error', + 'e18e/prefer-array-some': 'error', + 'e18e/prefer-array-to-sorted': 'error', + 'e18e/prefer-spread-syntax': 'error', + }, + }, +]); + +const scriptOverrides = defineConfig([ + { + name: 'project/script-overrides', + files: ['scripts/**/*.js'], + languageOptions: { + globals: { + ...globals.node, + }, + }, + rules: { + 'no-await-in-loop': 'off', + 'no-bitwise': 'off', + 'no-continue': 'off', + 'no-restricted-syntax': 'off', + 'prefer-destructuring': 'off', + }, + }, +]); + const projectOverrides = defineConfig([ { name: 'project/rule-overrides', files: [...jsFiles, ...tsFiles], + settings: { + 'import-x/resolver-next': [ + createTypeScriptImportResolver({ + alwaysTryTypes: true, + project: ['tsconfig.web.json', 'tsconfig.node.json'], + }), + ], + }, languageOptions: { globals: { JSX: 'readonly', @@ -110,6 +155,12 @@ const projectOverrides = defineConfig([ { name: 'project/typescript-rule-overrides', files: tsFiles, + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, rules: { // disabled for now to get eslint to pass '@typescript-eslint/consistent-type-definitions': 'off', @@ -138,6 +189,8 @@ export default defineConfig([ ...jsConfig, ...reactConfig, ...typescriptConfig, + ...e18eConfig, + ...scriptOverrides, ...prettierConfig, ...projectOverrides, ]); diff --git a/knip.json b/knip.json index c6cca1d75..e011aaea4 100644 --- a/knip.json +++ b/knip.json @@ -1,6 +1,7 @@ { "$schema": "https://unpkg.com/knip@5/schema.json", - "entry": ["src/sw.ts", "scripts/normalize-imports.js"], + "entry": ["src/sw.ts"], + "ignore": ["src/ext.d.ts", "src/types/matrix-sdk-events.d.ts"], "ignoreExportsUsedInFile": { "interface": true, "type": true diff --git a/package.json b/package.json index 23853c9e2..86ea3ff21 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,16 @@ "lint:fix": "eslint . --fix", "fmt": "prettier --write .", "fmt:check": "prettier --check .", - "typecheck": "tsc", + "typecheck": "tsc -b", "test": "vitest", "test:ui": "vitest --ui", "test:run": "vitest run", "test:coverage": "vitest run --coverage", + "imports:normalize": "node scripts/normalize-imports.js", + "imports:normalize:write": "node scripts/normalize-imports.js --write", + "imports:repair": "pnpm run imports:normalize:write", + "imports:migrate:matrix-sdk": "node scripts/migrate-matrix-sdk-imports.js", + "imports:migrate:matrix-sdk:write": "node scripts/migrate-matrix-sdk-imports.js --write", "knip": "knip", "tunnel": "cloudflared tunnel --url http://localhost:8080", "knope": "knope", @@ -44,7 +49,7 @@ "@use-gesture/react": "10.3.1", "@vanilla-extract/css": "^1.18.0", "@vanilla-extract/recipes": "^0.5.7", - "@vanilla-extract/vite-plugin": "^5.1.4", + "@vanilla-extract/vite-plugin": "^5.2.1", "await-to-js": "^3.0.0", "badwords-list": "^2.0.1-4", "blurhash": "^2.0.5", @@ -95,7 +100,8 @@ "workbox-precaching": "^7.4.0" }, "devDependencies": { - "@cloudflare/vite-plugin": "^1.26.0", + "@cloudflare/vite-plugin": "^1.30.2", + "@e18e/eslint-plugin": "^0.3.0", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@eslint/compat": "2.0.2", "@eslint/js": "9.39.3", @@ -116,7 +122,7 @@ "@types/react-google-recaptcha": "^2.1.9", "@types/sanitize-html": "^2.16.0", "@types/ua-parser-js": "^0.7.39", - "@vitejs/plugin-react": "^5.1.4", + "@vitejs/plugin-react": "^6.0.1", "@vitest/coverage-v8": "^4.1.0", "@vitest/ui": "^4.1.0", "buffer": "^6.0.3", @@ -124,19 +130,20 @@ "eslint": "9.39.3", "eslint-config-airbnb-extended": "3.0.1", "eslint-config-prettier": "10.1.8", + "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-prettier": "5.5.5", "globals": "17.3.0", "jsdom": "^29.0.0", "knip": "5.85.0", "prettier": "3.8.1", "typescript": "^5.9.3", - "vite": "^7.3.1", - "vite-plugin-compression2": "2.5.0", + "vite": "^8.0.3", + "vite-plugin-compression2": "2.5.3", "vite-plugin-pwa": "^1.2.0", - "vite-plugin-static-copy": "^3.2.0", + "vite-plugin-static-copy": "^4.0.0", "vite-plugin-svgr": "4.5.0", "vite-plugin-top-level-await": "^1.6.0", "vitest": "^4.1.0", - "wrangler": "^4.70.0" + "wrangler": "^4.78.0" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad8544f09..935490119 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,8 +58,8 @@ importers: specifier: ^0.5.7 version: 0.5.7(@vanilla-extract/css@1.18.0) '@vanilla-extract/vite-plugin': - specifier: ^5.1.4 - version: 5.1.4(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(yaml@2.8.2) + specifier: ^5.2.1 + version: 5.2.1(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(yaml@2.8.2) await-to-js: specifier: ^3.0.0 version: 3.0.0 @@ -206,8 +206,11 @@ importers: version: 7.4.0 devDependencies: '@cloudflare/vite-plugin': - specifier: ^1.26.0 - version: 1.27.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workerd@1.20260310.1)(wrangler@4.72.0) + specifier: ^1.30.2 + version: 1.30.2(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workerd@1.20260317.1)(wrangler@4.78.0) + '@e18e/eslint-plugin': + specifier: ^0.3.0 + version: 0.3.0(eslint@9.39.3(jiti@2.6.1)) '@esbuild-plugins/node-globals-polyfill': specifier: ^0.2.3 version: 0.2.3(esbuild@0.27.3) @@ -269,8 +272,8 @@ importers: specifier: ^0.7.39 version: 0.7.39 '@vitejs/plugin-react': - specifier: ^5.1.4 - version: 5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + specifier: ^6.0.1 + version: 6.0.1(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) '@vitest/coverage-v8': specifier: ^4.1.0 version: 4.1.0(vitest@4.1.0) @@ -292,6 +295,9 @@ importers: eslint-config-prettier: specifier: 10.1.8 version: 10.1.8(eslint@9.39.3(jiti@2.6.1)) + eslint-import-resolver-typescript: + specifier: ^4.4.4 + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.3(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-prettier: specifier: 5.5.5 version: 5.5.5(eslint-config-prettier@10.1.8(eslint@9.39.3(jiti@2.6.1)))(eslint@9.39.3(jiti@2.6.1))(prettier@3.8.1) @@ -311,29 +317,29 @@ importers: specifier: ^5.9.3 version: 5.9.3 vite: - specifier: ^7.3.1 - version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + specifier: ^8.0.3 + version: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) vite-plugin-compression2: - specifier: 2.5.0 - version: 2.5.0(rollup@4.59.0) + specifier: 2.5.3 + version: 2.5.3(rollup@4.59.0) vite-plugin-pwa: specifier: ^1.2.0 - version: 1.2.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) + version: 1.2.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) vite-plugin-static-copy: - specifier: ^3.2.0 - version: 3.2.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + specifier: ^4.0.0 + version: 4.0.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) vite-plugin-svgr: specifier: 4.5.0 - version: 4.5.0(rollup@4.59.0)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + version: 4.5.0(rollup@4.59.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) vite-plugin-top-level-await: specifier: ^1.6.0 - version: 1.6.0(@swc/helpers@0.5.19)(rollup@4.59.0)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + version: 1.6.0(@swc/helpers@0.5.19)(rollup@4.59.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) vitest: specifier: ^4.1.0 - version: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + version: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) wrangler: - specifier: ^4.70.0 - version: 4.72.0 + specifier: ^4.78.0 + version: 4.78.0 packages: @@ -768,18 +774,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-self@7.27.1': - resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx-source@7.27.1': - resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.29.0': resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} engines: {node: '>=6.9.0'} @@ -895,8 +889,8 @@ packages: resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==} engines: {node: '>=18.0.0'} - '@cloudflare/unenv-preset@2.15.0': - resolution: {integrity: sha512-EGYmJaGZKWl+X8tXxcnx4v2bOZSjQeNI5dWFeXivgX9+YCT69AkzHHwlNbVpqtEUTbew8eQurpyOpeN8fg00nw==} + '@cloudflare/unenv-preset@2.16.0': + resolution: {integrity: sha512-8ovsRpwzPoEqPUzoErAYVv8l3FMZNeBVQfJTvtzP4AgLSRGZISRfuChFxHWUQd3n6cnrwkuTGxT+2cGo8EsyYg==} peerDependencies: unenv: 2.0.0-rc.24 workerd: 1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0 @@ -904,38 +898,38 @@ packages: workerd: optional: true - '@cloudflare/vite-plugin@1.27.0': - resolution: {integrity: sha512-+s8APrIadCf2h0zYZ3WIPVeQ2CYgbXgFiR3BIrKvbpoo5klLgTeYpTq8ggxBmtjwt88PNruI4eCGZ6XNaDHMaA==} + '@cloudflare/vite-plugin@1.30.2': + resolution: {integrity: sha512-1TG/GyYxMAVhRtbKs9dPCsJY+c4qaPk+NKiLywKLV/BuvgMTBGhrmIvkC9NQSaw9sa5fPOYmv9me68AIs5kXJQ==} peerDependencies: - vite: ^6.1.0 || ^7.0.0 - wrangler: ^4.72.0 + vite: ^6.1.0 || ^7.0.0 || ^8.0.0 + wrangler: ^4.78.0 - '@cloudflare/workerd-darwin-64@1.20260310.1': - resolution: {integrity: sha512-hF2VpoWaMb1fiGCQJqCY6M8I+2QQqjkyY4LiDYdTL5D/w6C1l5v1zhc0/jrjdD1DXfpJtpcSMSmEPjHse4p9Ig==} + '@cloudflare/workerd-darwin-64@1.20260317.1': + resolution: {integrity: sha512-8hjh3sPMwY8M/zedq3/sXoA2Q4BedlGufn3KOOleIG+5a4ReQKLlUah140D7J6zlKmYZAFMJ4tWC7hCuI/s79g==} engines: {node: '>=16'} cpu: [x64] os: [darwin] - '@cloudflare/workerd-darwin-arm64@1.20260310.1': - resolution: {integrity: sha512-h/Vl3XrYYPI6yFDE27XO1QPq/1G1lKIM8tzZGIWYpntK3IN5XtH3Ee/sLaegpJ49aIJoqhF2mVAZ6Yw+Vk2gJw==} + '@cloudflare/workerd-darwin-arm64@1.20260317.1': + resolution: {integrity: sha512-M/MnNyvO5HMgoIdr3QHjdCj2T1ki9gt0vIUnxYxBu9ISXS/jgtMl6chUVPJ7zHYBn9MyYr8ByeN6frjYxj0MGg==} engines: {node: '>=16'} cpu: [arm64] os: [darwin] - '@cloudflare/workerd-linux-64@1.20260310.1': - resolution: {integrity: sha512-XzQ0GZ8G5P4d74bQYOIP2Su4CLdNPpYidrInaSOuSxMw+HamsHaFrjVsrV2mPy/yk2hi6SY2yMbgKFK9YjA7vw==} + '@cloudflare/workerd-linux-64@1.20260317.1': + resolution: {integrity: sha512-1ltuEjkRcS3fsVF7CxsKlWiRmzq2ZqMfqDN0qUOgbUwkpXsLVJsXmoblaLf5OP00ELlcgF0QsN0p2xPEua4Uug==} engines: {node: '>=16'} cpu: [x64] os: [linux] - '@cloudflare/workerd-linux-arm64@1.20260310.1': - resolution: {integrity: sha512-sxv4CxnN4ZR0uQGTFVGa0V4KTqwdej/czpIc5tYS86G8FQQoGIBiAIs2VvU7b8EROPcandxYHDBPTb+D9HIMPw==} + '@cloudflare/workerd-linux-arm64@1.20260317.1': + resolution: {integrity: sha512-3QrNnPF1xlaNwkHpasvRvAMidOvQs2NhXQmALJrEfpIJ/IDL2la8g499yXp3eqhG3hVMCB07XVY149GTs42Xtw==} engines: {node: '>=16'} cpu: [arm64] os: [linux] - '@cloudflare/workerd-windows-64@1.20260310.1': - resolution: {integrity: sha512-+1ZTViWKJypLfgH/luAHCqkent0DEBjAjvO40iAhOMHRLYP/SPphLvr4Jpi6lb+sIocS8Q1QZL4uM5Etg1Wskg==} + '@cloudflare/workerd-windows-64@1.20260317.1': + resolution: {integrity: sha512-MfZTz+7LfuIpMGTa3RLXHX8Z/pnycZLItn94WRdHr8LPVet+C5/1Nzei399w/jr3+kzT4pDKk26JF/tlI5elpQ==} engines: {node: '>=16'} cpu: [x64] os: [win32] @@ -980,6 +974,17 @@ packages: resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} engines: {node: '>=20.19.0'} + '@e18e/eslint-plugin@0.3.0': + resolution: {integrity: sha512-hHgfpxsrZ2UYHcicA+tGZnmk19uJTaye9VH79O+XS8R4ona2Hx3xjhXghclNW58uXMk3xXlbYEOMr8thsoBmWg==} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + oxlint: ^1.55.0 + peerDependenciesMeta: + eslint: + optional: true + oxlint: + optional: true + '@emnapi/core@1.8.1': resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} @@ -1544,6 +1549,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@oxc-project/types@0.122.0': + resolution: {integrity: sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==} + '@oxc-resolver/binding-android-arm-eabi@11.19.1': resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==} cpu: [arm] @@ -2215,8 +2223,106 @@ packages: resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} engines: {node: '>=14.0.0'} - '@rolldown/pluginutils@1.0.0-rc.3': - resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + '@rolldown/binding-android-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.12': + resolution: {integrity: sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.12': + resolution: {integrity: sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12': + resolution: {integrity: sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': + resolution: {integrity: sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': + resolution: {integrity: sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.12': + resolution: {integrity: sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12': + resolution: {integrity: sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.12': + resolution: {integrity: sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-rc.12': + resolution: {integrity: sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==} + + '@rolldown/pluginutils@1.0.0-rc.7': + resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} @@ -3018,14 +3124,17 @@ packages: '@vanilla-extract/babel-plugin-debug-ids@1.2.2': resolution: {integrity: sha512-MeDWGICAF9zA/OZLOKwhoRlsUW+fiMwnfuOAqFVohL31Agj7Q/RBWAYweqjHLgFBCsdnr6XIfwjJnmb2znEWxw==} - '@vanilla-extract/compiler@0.3.4': - resolution: {integrity: sha512-W9HXf9EAccpE1vEIATvSoBVj/bQnmHfYHfDJjUN8dcOHW6oMcnoGTqweDM9I66BHqlNH4d0IsaeZKSViOv7K4w==} + '@vanilla-extract/compiler@0.6.0': + resolution: {integrity: sha512-FlZM8s/h1obGHdYSTo05iIXUr6hsNvoE/okv/e9Sq7GN+niofhUKyuZPSwZNVYMK49xxeWNH9mopOlGRRPV4mw==} '@vanilla-extract/css@1.18.0': resolution: {integrity: sha512-/p0dwOjr0o8gE5BRQ5O9P0u/2DjUd6Zfga2JGmE4KaY7ZITWMszTzk4x4CPlM5cKkRr2ZGzbE6XkuPNfp9shSQ==} - '@vanilla-extract/integration@8.0.7': - resolution: {integrity: sha512-ILob4F9cEHXpbWAVt3Y2iaQJpqYq/c/5TJC8Fz58C2XmX3QW2Y589krvViiyJhQfydCGK3EbwPQhVFjQaBeKfg==} + '@vanilla-extract/css@1.20.0': + resolution: {integrity: sha512-yKuajXFlghIjRZmEfy95z6MYj+mzJPoD3nbNLVAUB8Np6I1P9g5vBlznQPD+0A46osCn0za/wIvp/cg8HU3aig==} + + '@vanilla-extract/integration@8.0.9': + resolution: {integrity: sha512-NP+CSo5IYHDmkMMy5vAxY4R9i2+CAg4sxgvVaxuHiuY9q30i6dNUTujNNKZGW2urEkd4HVVI6NggeIyYjbGPwA==} '@vanilla-extract/private@1.0.9': resolution: {integrity: sha512-gT2jbfZuaaCLrAxwXbRgIhGhcXbRZCG3v4TTUnjw0EJ7ArdBRxkq4msNJkbuRkCgfIK5ATmprB5t9ljvLeFDEA==} @@ -3035,16 +3144,23 @@ packages: peerDependencies: '@vanilla-extract/css': ^1.0.0 - '@vanilla-extract/vite-plugin@5.1.4': - resolution: {integrity: sha512-fTYNKUK3n4ApkUf2FEcO7mpqNKEHf9kDGg8DXlkqHtPxgwPhjuaajmDfQCSBsNgnA2SLI+CB5EO6kLQuKsw2Rw==} + '@vanilla-extract/vite-plugin@5.2.1': + resolution: {integrity: sha512-1dmCgmTmls/c4G+t453vZIzZ+82ftr+JC2J48C1drVkiwtZ7DscYSIko9Ci0CyDptBLWz5EO9fWnqzfHnns8tg==} peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - '@vitejs/plugin-react@5.1.4': - resolution: {integrity: sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==} + '@vitejs/plugin-react@6.0.1': + resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true '@vitest/coverage-v8@4.1.0': resolution: {integrity: sha512-nDWulKeik2bL2Va/Wl4x7DLuTKAXa906iRFooIRPR+huHkcvp9QDkPQ2RJdmjOFrqOqvNfoSQLF68deE3xC3CQ==} @@ -3547,6 +3663,10 @@ packages: emojibase@15.3.1: resolution: {integrity: sha512-GNsjHnG2J3Ktg684Fs/vZR/6XpOSkZPMAv85EHrr6br2RN2cJNwdS4am/3YSK3y+/gOv2kmoK3GGdahXdMxg2g==} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + enhanced-resolve@5.20.0: resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==} engines: {node: '>=10.13.0'} @@ -3684,6 +3804,11 @@ packages: eslint-import-resolver-webpack: optional: true + eslint-plugin-depend@1.5.0: + resolution: {integrity: sha512-i3UeLYmclf1Icp35+6W7CR4Bp2PIpDgBuf/mpmXK5UeLkZlvYJ21VuQKKHHAIBKRTPivPGX/gZl5JGno1o9Y0A==} + peerDependencies: + eslint: '>=8.40.0' + eslint-plugin-es-x@7.8.0: resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -4436,6 +4561,80 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -4538,8 +4737,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - miniflare@4.20260310.0: - resolution: {integrity: sha512-uC5vNPenFpDSj5aUU3wGSABG6UUqMr+Xs1m4AkCrTHo37F4Z6xcQw5BXqViTfPDVT/zcYH1UgTVoXhr1l6ZMXw==} + miniflare@4.20260317.3: + resolution: {integrity: sha512-tK78D3X4q30/SXqVwMhWrUfH+ffRou9dJLC+jkhNy5zh1I7i7T4JH6xihOvYxdCSBavJ5fQXaaxDJz6orh09BA==} engines: {node: '>=18.0.0'} hasBin: true @@ -4560,6 +4759,9 @@ packages: modern-ahocorasick@1.1.0: resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} + module-replacements@2.11.0: + resolution: {integrity: sha512-j5sNQm3VCpQQ7nTqGeOZtoJtV3uKERgCBm9QRhmGRiXiqkf7iRFOkfxdJRZWLkqYY8PNf4cDQF/WfXUYLENrRA==} + motion-dom@12.35.2: resolution: {integrity: sha512-pWXFMTwvGDbx1Fe9YL5HZebv2NhvGBzRtiNUv58aoK7+XrsuaydQ0JGRKK2r+bTKlwgSWwWxHbP5249Qr/BNpg==} @@ -4739,6 +4941,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} @@ -4868,10 +5074,6 @@ packages: react: '*' react-dom: '*' - react-refresh@0.18.0: - resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} - engines: {node: '>=0.10.0'} - react-router-dom@6.30.3: resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==} engines: {node: '>=14.0.0'} @@ -4951,6 +5153,11 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rolldown@1.0.0-rc.12: + resolution: {integrity: sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.59.0: resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -5418,8 +5625,8 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite-plugin-compression2@2.5.0: - resolution: {integrity: sha512-bHxtBibPxxSn5eZSe0IAzvYucP/hg8Bz8ppjbH7lndU5kIHT+92qTkB4z9xWYfnyV0YHuir1SjOuyO0fzU4Vgg==} + vite-plugin-compression2@2.5.3: + resolution: {integrity: sha512-ItPgqQWkcnBbVw7is9OKwiZ8v6+ju9rYROl5Lp6QfQDEx/d55AwJQb/KLpsQqsU9HoigYBsZ8tK6I02UwJNvEw==} vite-plugin-pwa@1.2.0: resolution: {integrity: sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==} @@ -5433,11 +5640,11 @@ packages: '@vite-pwa/assets-generator': optional: true - vite-plugin-static-copy@3.2.0: - resolution: {integrity: sha512-g2k9z8B/1Bx7D4wnFjPLx9dyYGrqWMLTpwTtPHhcU+ElNZP2O4+4OsyaficiDClus0dzVhdGvoGFYMJxoXZ12Q==} - engines: {node: ^18.0.0 || >=20.0.0} + vite-plugin-static-copy@4.0.0: + resolution: {integrity: sha512-TTf6cVTV4M2pH2Wfr3zhevdRsIQezfm2ltDkSfkjqvvdryJHYQyNoPISvuytX3r9jFZV0yVeMYyGTsAvAH2XLw==} + engines: {node: ^22.0.0 || >=24.0.0} peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 vite-plugin-svgr@4.5.0: resolution: {integrity: sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==} @@ -5489,6 +5696,49 @@ packages: yaml: optional: true + vite@8.0.3: + resolution: {integrity: sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: '>=0.25.0' + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vitest@4.1.0: resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -5639,17 +5889,17 @@ packages: workbox-window@7.4.0: resolution: {integrity: sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==} - workerd@1.20260310.1: - resolution: {integrity: sha512-yawXhypXXHtArikJj15HOMknNGikpBbSg2ZDe6lddUbqZnJXuCVSkgc/0ArUeVMG1jbbGvpst+REFtKwILvRTQ==} + workerd@1.20260317.1: + resolution: {integrity: sha512-ZuEq1OdrJBS+NV+L5HMYPCzVn49a2O60slQiiLpG44jqtlOo+S167fWC76kEXteXLLLydeuRrluRel7WdOUa4g==} engines: {node: '>=16'} hasBin: true - wrangler@4.72.0: - resolution: {integrity: sha512-bKkb8150JGzJZJWiNB2nu/33smVfawmfYiecA6rW4XH7xS23/jqMbgpdelM34W/7a1IhR66qeQGVqTRXROtAZg==} - engines: {node: '>=20.0.0'} + wrangler@4.78.0: + resolution: {integrity: sha512-He/vUhk4ih0D0eFmtNnlbT6Od8j+BEokaSR+oYjbVsH0SWIrIch+eHqfLRSBjBQaOoh6HCNxcafcIkBm2u0Hag==} + engines: {node: '>=20.3.0'} hasBin: true peerDependencies: - '@cloudflare/workers-types': ^4.20260310.1 + '@cloudflare/workers-types': ^4.20260317.1 peerDependenciesMeta: '@cloudflare/workers-types': optional: true @@ -6229,16 +6479,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 @@ -6424,38 +6664,38 @@ snapshots: '@cloudflare/kv-asset-handler@0.4.2': {} - '@cloudflare/unenv-preset@2.15.0(unenv@2.0.0-rc.24)(workerd@1.20260310.1)': + '@cloudflare/unenv-preset@2.16.0(unenv@2.0.0-rc.24)(workerd@1.20260317.1)': dependencies: unenv: 2.0.0-rc.24 optionalDependencies: - workerd: 1.20260310.1 + workerd: 1.20260317.1 - '@cloudflare/vite-plugin@1.27.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workerd@1.20260310.1)(wrangler@4.72.0)': + '@cloudflare/vite-plugin@1.30.2(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workerd@1.20260317.1)(wrangler@4.78.0)': dependencies: - '@cloudflare/unenv-preset': 2.15.0(unenv@2.0.0-rc.24)(workerd@1.20260310.1) - miniflare: 4.20260310.0 + '@cloudflare/unenv-preset': 2.16.0(unenv@2.0.0-rc.24)(workerd@1.20260317.1) + miniflare: 4.20260317.3 unenv: 2.0.0-rc.24 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) - wrangler: 4.72.0 + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + wrangler: 4.78.0 ws: 8.18.0 transitivePeerDependencies: - bufferutil - utf-8-validate - workerd - '@cloudflare/workerd-darwin-64@1.20260310.1': + '@cloudflare/workerd-darwin-64@1.20260317.1': optional: true - '@cloudflare/workerd-darwin-arm64@1.20260310.1': + '@cloudflare/workerd-darwin-arm64@1.20260317.1': optional: true - '@cloudflare/workerd-linux-64@1.20260310.1': + '@cloudflare/workerd-linux-64@1.20260317.1': optional: true - '@cloudflare/workerd-linux-arm64@1.20260310.1': + '@cloudflare/workerd-linux-arm64@1.20260317.1': optional: true - '@cloudflare/workerd-windows-64@1.20260310.1': + '@cloudflare/workerd-windows-64@1.20260317.1': optional: true '@cspotcode/source-map-support@0.8.1': @@ -6486,6 +6726,12 @@ snapshots: '@csstools/css-tokenizer@4.0.0': {} + '@e18e/eslint-plugin@0.3.0(eslint@9.39.3(jiti@2.6.1))': + dependencies: + eslint-plugin-depend: 1.5.0(eslint@9.39.3(jiti@2.6.1)) + optionalDependencies: + eslint: 9.39.3(jiti@2.6.1) + '@emnapi/core@1.8.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -6911,6 +7157,8 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 + '@oxc-project/types@0.122.0': {} + '@oxc-resolver/binding-android-arm-eabi@11.19.1': optional: true @@ -7957,7 +8205,56 @@ snapshots: '@remix-run/router@1.23.2': {} - '@rolldown/pluginutils@1.0.0-rc.3': {} + '@rolldown/binding-android-arm64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.12': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.12': + optional: true + + '@rolldown/pluginutils@1.0.0-rc.12': {} + + '@rolldown/pluginutils@1.0.0-rc.7': {} '@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@4.59.0)': dependencies: @@ -8440,19 +8737,23 @@ snapshots: '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 + optional: true '@types/babel__generator@7.27.0': dependencies: '@babel/types': 7.29.0 + optional: true '@types/babel__template@7.4.4': dependencies: '@babel/parser': 7.29.0 '@babel/types': 7.29.0 + optional: true '@types/babel__traverse@7.28.0': dependencies: '@babel/types': 7.29.0 + optional: true '@types/chai@5.2.3': dependencies: @@ -8671,15 +8972,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@vanilla-extract/compiler@0.3.4(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)': + '@vanilla-extract/compiler@0.6.0(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2)': dependencies: - '@vanilla-extract/css': 1.18.0 - '@vanilla-extract/integration': 8.0.7 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) - vite-node: 3.2.4(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + '@vanilla-extract/css': 1.20.0 + '@vanilla-extract/integration': 8.0.9 + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' + - '@vitejs/devtools' - babel-plugin-macros + - esbuild - jiti - less - lightningcss @@ -8709,12 +9012,29 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros - '@vanilla-extract/integration@8.0.7': + '@vanilla-extract/css@1.20.0': + dependencies: + '@emotion/hash': 0.9.2 + '@vanilla-extract/private': 1.0.9 + css-what: 6.2.2 + cssesc: 3.0.0 + csstype: 3.2.3 + dedent: 1.7.2 + deep-object-diff: 1.1.9 + deepmerge: 4.3.1 + lru-cache: 10.4.3 + media-query-parser: 2.0.2 + modern-ahocorasick: 1.1.0 + picocolors: 1.1.1 + transitivePeerDependencies: + - babel-plugin-macros + + '@vanilla-extract/integration@8.0.9': dependencies: '@babel/core': 7.29.0 '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@vanilla-extract/babel-plugin-debug-ids': 1.2.2 - '@vanilla-extract/css': 1.18.0 + '@vanilla-extract/css': 1.20.0 dedent: 1.7.2 esbuild: 0.27.3 eval: 0.1.8 @@ -8731,14 +9051,16 @@ snapshots: dependencies: '@vanilla-extract/css': 1.18.0 - '@vanilla-extract/vite-plugin@5.1.4(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(yaml@2.8.2)': + '@vanilla-extract/vite-plugin@5.2.1(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(yaml@2.8.2)': dependencies: - '@vanilla-extract/compiler': 0.3.4(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) - '@vanilla-extract/integration': 8.0.7 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + '@vanilla-extract/compiler': 0.6.0(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2) + '@vanilla-extract/integration': 8.0.9 + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' + - '@vitejs/devtools' - babel-plugin-macros + - esbuild - jiti - less - lightningcss @@ -8751,17 +9073,10 @@ snapshots: - tsx - yaml - '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))': + '@vitejs/plugin-react@6.0.1(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))': dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) - '@rolldown/pluginutils': 1.0.0-rc.3 - '@types/babel__core': 7.20.5 - react-refresh: 0.18.0 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) - transitivePeerDependencies: - - supports-color + '@rolldown/pluginutils': 1.0.0-rc.7 + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) '@vitest/coverage-v8@4.1.0(vitest@4.1.0)': dependencies: @@ -8775,7 +9090,7 @@ snapshots: obug: 2.1.1 std-env: 4.0.0 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + vitest: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) '@vitest/expect@4.1.0': dependencies: @@ -8786,13 +9101,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))': + '@vitest/mocker@4.1.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) '@vitest/pretty-format@4.1.0': dependencies: @@ -8821,7 +9136,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + vitest: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) '@vitest/utils@4.1.0': dependencies: @@ -8868,7 +9183,7 @@ snapshots: anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.1 + picomatch: 2.3.2 argparse@2.0.1: {} @@ -9280,6 +9595,8 @@ snapshots: emojibase@15.3.1: {} + empathic@2.0.0: {} + enhanced-resolve@5.20.0: dependencies: graceful-fs: 4.2.11 @@ -9509,6 +9826,13 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-depend@1.5.0(eslint@9.39.3(jiti@2.6.1)): + dependencies: + empathic: 2.0.0 + eslint: 9.39.3(jiti@2.6.1) + module-replacements: 2.11.0 + semver: 7.7.4 + eslint-plugin-es-x@7.8.0(eslint@9.39.3(jiti@2.6.1)): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) @@ -9762,9 +10086,9 @@ snapshots: dependencies: walk-up-path: 4.0.0 - fdir@6.5.0(picomatch@4.0.3): + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: - picomatch: 4.0.3 + picomatch: 4.0.4 fflate@0.8.2: {} @@ -10361,6 +10685,55 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + lines-and-columns@1.2.4: {} linkify-react@4.3.2(linkifyjs@4.3.2)(react@18.3.1): @@ -10463,12 +10836,12 @@ snapshots: min-indent@1.0.1: {} - miniflare@4.20260310.0: + miniflare@4.20260317.3: dependencies: '@cspotcode/source-map-support': 0.8.1 sharp: 0.34.5 undici: 7.24.3 - workerd: 1.20260310.1 + workerd: 1.20260317.1 ws: 8.18.0 youch: 4.1.0-beta.10 transitivePeerDependencies: @@ -10492,6 +10865,8 @@ snapshots: modern-ahocorasick@1.1.0: {} + module-replacements@2.11.0: {} + motion-dom@12.35.2: dependencies: motion-utils: 12.29.2 @@ -10680,6 +11055,8 @@ snapshots: picomatch@4.0.3: {} + picomatch@4.0.4: {} + pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -10832,8 +11209,6 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-refresh@0.18.0: {} - react-router-dom@6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@remix-run/router': 1.23.2 @@ -10852,7 +11227,7 @@ snapshots: readdirp@3.6.0: dependencies: - picomatch: 2.3.1 + picomatch: 2.3.2 redent@3.0.0: dependencies: @@ -10925,6 +11300,27 @@ snapshots: reusify@1.1.0: {} + rolldown@1.0.0-rc.12: + dependencies: + '@oxc-project/types': 0.122.0 + '@rolldown/pluginutils': 1.0.0-rc.12 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.12 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.12 + '@rolldown/binding-darwin-x64': 1.0.0-rc.12 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.12 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.12 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.12 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.12 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.12 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.12 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.12 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.12 + rollup@4.59.0: dependencies: '@types/estree': 1.0.8 @@ -11293,8 +11689,8 @@ snapshots: tinyglobby@0.2.15: dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 tinyrainbow@3.1.0: {} @@ -11481,13 +11877,13 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - vite-node@3.2.4(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2): + vite-node@3.2.4(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -11502,59 +11898,59 @@ snapshots: - tsx - yaml - vite-plugin-compression2@2.5.0(rollup@4.59.0): + vite-plugin-compression2@2.5.3(rollup@4.59.0): dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.59.0) tar-mini: 0.2.0 transitivePeerDependencies: - rollup - vite-plugin-pwa@1.2.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0): + vite-plugin-pwa@1.2.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) workbox-build: 7.4.0(@types/babel__core@7.20.5) workbox-window: 7.4.0 transitivePeerDependencies: - supports-color - vite-plugin-static-copy@3.2.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): + vite-plugin-static-copy@4.0.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): dependencies: chokidar: 3.6.0 p-map: 7.0.4 picocolors: 1.1.1 tinyglobby: 0.2.15 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) - vite-plugin-svgr@4.5.0(rollup@4.59.0)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): + vite-plugin-svgr@4.5.0(rollup@4.59.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.59.0) '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) transitivePeerDependencies: - rollup - supports-color - typescript - vite-plugin-top-level-await@1.6.0(@swc/helpers@0.5.19)(rollup@4.59.0)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): + vite-plugin-top-level-await@1.6.0(@swc/helpers@0.5.19)(rollup@4.59.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): dependencies: '@rollup/plugin-virtual': 3.0.2(rollup@4.59.0) '@swc/core': 1.15.18(@swc/helpers@0.5.19) '@swc/wasm': 1.15.18 uuid: 10.0.0 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) transitivePeerDependencies: - '@swc/helpers' - rollup - vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2): + vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2): dependencies: esbuild: 0.27.3 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 postcss: 8.5.8 rollup: 4.59.0 tinyglobby: 0.2.15 @@ -11562,13 +11958,29 @@ snapshots: '@types/node': 24.10.13 fsevents: 2.3.3 jiti: 2.6.1 + lightningcss: 1.32.0 + terser: 5.46.1 + yaml: 2.8.2 + + vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.8 + rolldown: 1.0.0-rc.12 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.10.13 + esbuild: 0.27.3 + fsevents: 2.3.3 + jiti: 2.6.1 terser: 5.46.1 yaml: 2.8.2 - vitest@4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): + vitest@4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + '@vitest/mocker': 4.1.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -11585,7 +11997,7 @@ snapshots: tinyexec: 1.0.4 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.10.13 @@ -11794,24 +12206,24 @@ snapshots: '@types/trusted-types': 2.0.7 workbox-core: 7.4.0 - workerd@1.20260310.1: + workerd@1.20260317.1: optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20260310.1 - '@cloudflare/workerd-darwin-arm64': 1.20260310.1 - '@cloudflare/workerd-linux-64': 1.20260310.1 - '@cloudflare/workerd-linux-arm64': 1.20260310.1 - '@cloudflare/workerd-windows-64': 1.20260310.1 + '@cloudflare/workerd-darwin-64': 1.20260317.1 + '@cloudflare/workerd-darwin-arm64': 1.20260317.1 + '@cloudflare/workerd-linux-64': 1.20260317.1 + '@cloudflare/workerd-linux-arm64': 1.20260317.1 + '@cloudflare/workerd-windows-64': 1.20260317.1 - wrangler@4.72.0: + wrangler@4.78.0: dependencies: '@cloudflare/kv-asset-handler': 0.4.2 - '@cloudflare/unenv-preset': 2.15.0(unenv@2.0.0-rc.24)(workerd@1.20260310.1) + '@cloudflare/unenv-preset': 2.16.0(unenv@2.0.0-rc.24)(workerd@1.20260317.1) blake3-wasm: 2.1.5 esbuild: 0.27.3 - miniflare: 4.20260310.0 + miniflare: 4.20260317.3 path-to-regexp: 6.3.0 unenv: 2.0.0-rc.24 - workerd: 1.20260310.1 + workerd: 1.20260317.1 optionalDependencies: fsevents: 2.3.3 transitivePeerDependencies: diff --git a/scripts/import-rewrites.test.js b/scripts/import-rewrites.test.js new file mode 100644 index 000000000..6b65f2c6d --- /dev/null +++ b/scripts/import-rewrites.test.js @@ -0,0 +1,73 @@ +import fs from 'node:fs/promises'; +import os from 'node:os'; +import path from 'node:path'; + +import { afterEach, describe, expect, it } from 'vitest'; + +import { + getMatrixModuleSpecifierFromDeclarationFile, + loadAliasMapFromTsconfig, + rewriteSourceImports, +} from './utils/import-rewrites.js'; + +const tempDirs = []; + +async function makeTempProject() { + const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'sable-import-rewrites-')); + tempDirs.push(dir); + return dir; +} + +afterEach(async () => { + await Promise.all(tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true }))); +}); + +describe('loadAliasMapFromTsconfig + rewriteSourceImports', () => { + it('rewrites relative imports using tsconfig path aliases', async () => { + const projectRoot = await makeTempProject(); + await fs.writeFile( + path.join(projectRoot, 'tsconfig.web.json'), + JSON.stringify( + { + compilerOptions: { + baseUrl: '.', + paths: { + '$components/*': ['src/app/components/*'], + '$types/*': ['src/types/*'], + }, + }, + }, + null, + 2 + ) + ); + + const aliases = await loadAliasMapFromTsconfig( + path.join(projectRoot, 'tsconfig.web.json'), + projectRoot + ); + + const filePath = path.join(projectRoot, 'src/app/pages/Home.tsx'); + const sourceCode = [ + "import { Header } from '../components/Header';", + "import { MatrixClient } from 'matrix-js-sdk/lib/client';", + '', + ].join('\n'); + + const result = rewriteSourceImports(filePath, sourceCode, aliases, projectRoot); + + expect(result.changed).toBe(true); + expect(result.updatedCode).toContain("from '$components/Header'"); + expect(result.updatedCode).toContain("from '$types/matrix-sdk'"); + }); +}); + +describe('getMatrixModuleSpecifierFromDeclarationFile', () => { + it('normalizes matrix-js-sdk declaration paths to bare module specifiers', () => { + const declarationFile = String.raw`C:\repo\node_modules\matrix-js-sdk\lib\models\room.d.ts`; + + expect(getMatrixModuleSpecifierFromDeclarationFile(declarationFile)).toBe( + 'matrix-js-sdk/lib/models/room' + ); + }); +}); diff --git a/scripts/migrate-matrix-sdk-imports.js b/scripts/migrate-matrix-sdk-imports.js new file mode 100644 index 000000000..d3417dd20 --- /dev/null +++ b/scripts/migrate-matrix-sdk-imports.js @@ -0,0 +1,234 @@ +#!/usr/bin/env node +/* eslint-disable no-console */ + +import fs from 'node:fs/promises'; +import path from 'node:path'; +import process from 'node:process'; + +import ts from 'typescript'; + +import { createTextHelpers } from './utils/console-style.js'; +import { + DEFAULT_ROOTS, + applyTextReplacements, + collectSourceFiles, + getMatrixModuleSpecifierFromDeclarationFile, + renderMatrixImportGroups, + toPosix, +} from './utils/import-rewrites.js'; + +const MATRIX_BOUNDARY_SPECIFIER = '$types/matrix-sdk'; + +function parseArgs(argv) { + let write = false; + const roots = []; + let index = 0; + + while (index < argv.length) { + const arg = argv[index]; + if (arg === '--write') { + write = true; + } else if (arg === '--root' && argv[index + 1]) { + roots.push(argv[index + 1]); + index += 1; + } else if (arg.startsWith('--root=')) { + roots.push(arg.slice('--root='.length)); + } else if (arg === '--help' || arg === '-h') { + console.log( + [ + 'Usage: node scripts/migrate-matrix-sdk-imports.js [--write] [--root ]', + '', + 'Default mode is dry-run.', + '--write Apply changes to files.', + '--root Root directory to scan (repeatable). Default: src', + ].join('\n') + ); + process.exit(0); + } + + index += 1; + } + + return { + write, + roots: roots.length > 0 ? roots : DEFAULT_ROOTS, + }; +} + +function loadProgram(projectRoot) { + const tsconfigPath = path.join(projectRoot, 'tsconfig.web.json'); + const configResult = ts.readConfigFile(tsconfigPath, ts.sys.readFile); + + if (configResult.error) { + const message = ts.flattenDiagnosticMessageText(configResult.error.messageText, '\n'); + throw new Error(`Failed to read tsconfig.web.json: ${message}`); + } + + const parsedConfig = ts.parseJsonConfigFileContent( + configResult.config, + ts.sys, + projectRoot, + undefined, + tsconfigPath + ); + + if (parsedConfig.errors.length > 0) { + const message = parsedConfig.errors + .map((error) => ts.flattenDiagnosticMessageText(error.messageText, '\n')) + .join('\n'); + throw new Error(`Failed to parse tsconfig.web.json:\n${message}`); + } + + return ts.createProgram({ + rootNames: parsedConfig.fileNames, + options: parsedConfig.options, + }); +} + +function isWithinRoots(filePath, rootPaths) { + return rootPaths.some((rootPath) => { + const relativePath = path.relative(rootPath, filePath); + return ( + relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath)) + ); + }); +} + +function getDeclarationModuleSpecifier(checker, specifier) { + const importedSymbol = checker.getSymbolAtLocation(specifier.name); + if (!importedSymbol) return null; + + const resolvedSymbol = + importedSymbol.flags & ts.SymbolFlags.Alias + ? checker.getAliasedSymbol(importedSymbol) + : importedSymbol; + const declaration = resolvedSymbol.declarations?.[0]; + if (!declaration) return null; + + return getMatrixModuleSpecifierFromDeclarationFile(declaration.getSourceFile().fileName); +} + +function getImportEntry(specifier) { + return { + importedName: specifier.propertyName?.text ?? specifier.name.text, + localName: specifier.name.text, + }; +} + +function buildReplacementText(checker, importDeclaration) { + const importClause = importDeclaration.importClause; + if ( + !importClause || + !importClause.namedBindings || + !ts.isNamedImports(importClause.namedBindings) + ) { + return null; + } + + const groups = new Map(); + + for (const specifier of importClause.namedBindings.elements) { + const moduleSpecifier = getDeclarationModuleSpecifier(checker, specifier); + if (!moduleSpecifier) { + return null; + } + + const group = groups.get(moduleSpecifier) ?? { values: [], types: [] }; + const bucket = importClause.isTypeOnly || specifier.isTypeOnly ? group.types : group.values; + bucket.push(getImportEntry(specifier)); + groups.set(moduleSpecifier, group); + } + + return renderMatrixImportGroups(groups).join('\n'); +} + +function collectReplacements(sourceFile, checker) { + const replacements = []; + + function visit(node) { + if ( + ts.isImportDeclaration(node) && + ts.isStringLiteral(node.moduleSpecifier) && + node.moduleSpecifier.text === MATRIX_BOUNDARY_SPECIFIER + ) { + const replacementText = buildReplacementText(checker, node); + if (replacementText) { + replacements.push({ + start: node.getStart(sourceFile), + end: node.getEnd(), + value: replacementText, + }); + } + } + + ts.forEachChild(node, visit); + } + + visit(sourceFile); + return replacements.sort((left, right) => right.start - left.start); +} + +async function main() { + const projectRoot = process.cwd(); + const { write, roots } = parseArgs(process.argv.slice(2)); + const targetRoots = roots.map((root) => path.resolve(projectRoot, root)); + const sourceFiles = ( + await Promise.all( + targetRoots.map(async (root) => { + try { + const stat = await fs.stat(root); + if (!stat.isDirectory()) return []; + return collectSourceFiles(root); + } catch { + return []; + } + }) + ) + ).flat(); + + const sourceFileSet = new Set(sourceFiles.map((filePath) => path.normalize(filePath))); + const program = loadProgram(projectRoot); + const checker = program.getTypeChecker(); + const { dim, green } = createTextHelpers(); + + const changes = []; + + for (const sourceFile of program.getSourceFiles()) { + const filePath = path.normalize(sourceFile.fileName); + if (!sourceFileSet.has(filePath) || !isWithinRoots(filePath, targetRoots)) continue; + + const replacements = collectReplacements(sourceFile, checker); + if (replacements.length === 0) continue; + + const originalCode = sourceFile.getFullText(); + const updatedCode = applyTextReplacements(originalCode, replacements); + + if (write) { + await fs.writeFile(filePath, updatedCode, 'utf8'); + } + + changes.push({ + file: toPosix(path.relative(projectRoot, filePath)), + replacements: replacements.length, + }); + } + + changes + .sort((left, right) => left.file.localeCompare(right.file)) + .forEach((change) => { + console.log( + `${dim(change.file)}: ${green(`${change.replacements} matrix import rewrite(s)`)}` + ); + }); + + const mode = write ? 'Applied' : 'Dry run'; + console.log(`${mode}: ${changes.length} files.`); + if (!write) { + console.log('Re-run with --write to apply changes.'); + } +} + +main().catch((error) => { + console.error(error instanceof Error ? error.message : String(error)); + process.exit(1); +}); diff --git a/scripts/normalize-imports.js b/scripts/normalize-imports.js index 74f9c4a91..98989a4b6 100644 --- a/scripts/normalize-imports.js +++ b/scripts/normalize-imports.js @@ -4,20 +4,14 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import process from 'node:process'; -import ts from 'typescript'; import { createTextHelpers } from './utils/console-style.js'; - -const DEFAULT_ROOTS = ['src']; -const SKIP_DIRS = new Set(['.git', '.hg', '.svn', 'node_modules', 'dist', 'coverage']); -const SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mts', '.cts', '.mjs', '.cjs']); -const MATRIX_IMPORT_BOUNDARY_FILES = new Set([ - path.normalize('src/types/matrix-sdk.ts'), - path.normalize('src/types/matrix-sdk-events.d.ts'), -]); - -function toPosix(inputPath) { - return inputPath.split(path.sep).join('/'); -} +import { + DEFAULT_ROOTS, + collectSourceFiles, + loadAliasMapFromTsconfig, + rewriteSourceImports, + toPosix, +} from './utils/import-rewrites.js'; function parseArgs(argv) { let write = false; @@ -55,190 +49,17 @@ function parseArgs(argv) { }; } -async function loadAliasMap(viteConfigPath, projectRoot) { - const viteConfig = await fs.readFile(viteConfigPath, 'utf8'); - const regex = /(\$[A-Za-z0-9_]+)\s*:\s*path\.resolve\(__dirname,\s*'([^']+)'\s*\)/g; - const aliasMap = []; - let match = regex.exec(viteConfig); - - while (match) { - const alias = match[1]; - const relativePath = match[2]; - aliasMap.push({ - alias, - absolutePath: path.resolve(projectRoot, relativePath), - }); - match = regex.exec(viteConfig); - } - - aliasMap.sort((a, b) => b.absolutePath.length - a.absolutePath.length); - return aliasMap; -} - -async function collectSourceFiles(rootDir) { - const files = []; - - async function walk(currentDir) { - const entries = await fs.readdir(currentDir, { withFileTypes: true }); - await Promise.all( - entries.map(async (entry) => { - if (entry.name.startsWith('.') && entry.name !== '.eslintrc') return; - if (entry.isDirectory()) { - if (SKIP_DIRS.has(entry.name)) return; - await walk(path.join(currentDir, entry.name)); - return; - } - - if (!entry.isFile()) return; - const filePath = path.join(currentDir, entry.name); - const ext = path.extname(entry.name); - if (!SOURCE_EXTENSIONS.has(ext)) return; - files.push(filePath); - }) - ); - } - - await walk(rootDir); - return files; -} - -function splitSpecifier(specifier) { - const match = specifier.match(/^([^?#]+)([?#].*)?$/); - if (!match) { - return { bare: specifier, suffix: '' }; - } - return { - bare: match[1], - suffix: match[2] ?? '', - }; -} - -function findMatchingAlias(absoluteTargetPath, aliases) { - return aliases.find(({ absolutePath }) => { - const rel = path.relative(absolutePath, absoluteTargetPath); - return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel)); - }); -} - -function getRewrittenSpecifier(filePath, specifier, aliases, projectRoot) { - const normalizedFilePath = path.normalize(path.relative(projectRoot, filePath)); - const { bare, suffix } = splitSpecifier(specifier); - - if ( - !MATRIX_IMPORT_BOUNDARY_FILES.has(normalizedFilePath) && - (bare === 'matrix-js-sdk' || bare.startsWith('matrix-js-sdk/')) - ) { - return `$types/matrix-sdk${suffix}`; - } - - if (!/^\.\.(?:\/|$)/.test(bare)) { - return null; - } - - const absoluteTargetPath = path.resolve(path.dirname(filePath), bare); - const matchedAlias = findMatchingAlias(absoluteTargetPath, aliases); - if (!matchedAlias) return null; - - const aliasRelativePath = toPosix(path.relative(matchedAlias.absolutePath, absoluteTargetPath)); - const aliasImport = aliasRelativePath - ? `${matchedAlias.alias}/${aliasRelativePath}` - : matchedAlias.alias; - return `${aliasImport}${suffix}`; -} - -function queueReplacement(sourceFile, literalNode, replacements, aliases, filePath, projectRoot) { - const specifier = literalNode.text; - const rewrittenSpecifier = getRewrittenSpecifier(filePath, specifier, aliases, projectRoot); - if (!rewrittenSpecifier || rewrittenSpecifier === specifier) return; - - replacements.push({ - start: literalNode.getStart(sourceFile) + 1, - end: literalNode.getEnd() - 1, - original: specifier, - value: rewrittenSpecifier, - }); -} - -function rewriteFileImports(filePath, sourceCode, aliases, projectRoot) { - const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true); - const replacements = []; - - function visit(node) { - if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) { - queueReplacement( - sourceFile, - node.moduleSpecifier, - replacements, - aliases, - filePath, - projectRoot - ); - } else if ( - ts.isExportDeclaration(node) && - node.moduleSpecifier && - ts.isStringLiteral(node.moduleSpecifier) - ) { - queueReplacement( - sourceFile, - node.moduleSpecifier, - replacements, - aliases, - filePath, - projectRoot - ); - } else if (ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument)) { - const { literal } = node.argument; - if (ts.isStringLiteral(literal)) { - queueReplacement(sourceFile, literal, replacements, aliases, filePath, projectRoot); - } - } else if (ts.isCallExpression(node) && node.arguments.length > 0) { - const firstArg = node.arguments[0]; - if (ts.isStringLiteral(firstArg)) { - const isDynamicImport = node.expression.kind === ts.SyntaxKind.ImportKeyword; - const isRequire = ts.isIdentifier(node.expression) && node.expression.text === 'require'; - if (isDynamicImport || isRequire) { - queueReplacement(sourceFile, firstArg, replacements, aliases, filePath, projectRoot); - } - } - } - - ts.forEachChild(node, visit); - } - - visit(sourceFile); - if (replacements.length === 0) { - return { changed: false, updatedCode: sourceCode, replacements: 0 }; - } - - const uniqueReplacements = Array.from( - new Map(replacements.map((r) => [`${r.start}:${r.end}`, r])).values() - ).sort((a, b) => b.start - a.start); - - const updatedCode = uniqueReplacements.reduce( - (code, replacement) => - code.slice(0, replacement.start) + replacement.value + code.slice(replacement.end), - sourceCode - ); - - return { - changed: updatedCode !== sourceCode, - updatedCode, - replacements: uniqueReplacements.length, - edits: uniqueReplacements.map((replacement) => ({ - from: replacement.original, - to: replacement.value, - })), - }; -} - async function main() { const projectRoot = process.cwd(); const { write, roots } = parseArgs(process.argv.slice(2)); - const aliases = await loadAliasMap(path.join(projectRoot, 'vite.config.ts'), projectRoot); + const aliases = await loadAliasMapFromTsconfig( + path.join(projectRoot, 'tsconfig.web.json'), + projectRoot + ); const { dim, red, green } = createTextHelpers(); if (aliases.length === 0) { - throw new Error('No aliases found in vite.config.ts'); + throw new Error('No aliases found in tsconfig.web.json'); } const targetRoots = roots.map((root) => path.resolve(projectRoot, root)); @@ -259,7 +80,7 @@ async function main() { const fileResults = await Promise.all( sourceFiles.map(async (filePath) => { const sourceCode = await fs.readFile(filePath, 'utf8'); - const { changed, updatedCode, replacements, edits } = rewriteFileImports( + const { changed, updatedCode, replacements, edits } = rewriteSourceImports( filePath, sourceCode, aliases, diff --git a/scripts/utils/import-rewrites.js b/scripts/utils/import-rewrites.js new file mode 100644 index 000000000..35ca000ba --- /dev/null +++ b/scripts/utils/import-rewrites.js @@ -0,0 +1,280 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; + +import ts from 'typescript'; + +export const DEFAULT_ROOTS = ['src']; +export const SKIP_DIRS = new Set(['.git', '.hg', '.svn', 'node_modules', 'dist', 'coverage']); +export const SOURCE_EXTENSIONS = new Set([ + '.ts', + '.tsx', + '.js', + '.jsx', + '.mts', + '.cts', + '.mjs', + '.cjs', +]); +export const MATRIX_IMPORT_BOUNDARY_FILES = new Set([ + path.normalize('src/types/matrix-sdk.ts'), + path.normalize('src/types/matrix-sdk-events.d.ts'), +]); + +export function toPosix(inputPath) { + return inputPath.split(path.sep).join('/'); +} + +function normalizeAliasPattern(pattern) { + return pattern.replace(/\/\*$/, ''); +} + +function getConfigErrorMessage(error) { + return ts.flattenDiagnosticMessageText(error.messageText, '\n'); +} + +export async function loadAliasMapFromTsconfig(tsconfigPath, projectRoot) { + const configResult = ts.readConfigFile(tsconfigPath, ts.sys.readFile); + if (configResult.error) { + throw new Error( + `Failed to read ${path.basename(tsconfigPath)}: ${getConfigErrorMessage(configResult.error)}` + ); + } + + const compilerOptions = configResult.config.compilerOptions ?? {}; + const baseUrl = compilerOptions.baseUrl ?? '.'; + const paths = compilerOptions.paths ?? {}; + + const aliasMap = [ + ...new Map( + Object.entries(paths) + .map(([aliasPattern, targets]) => { + if (!Array.isArray(targets) || targets.length === 0) return null; + + const alias = normalizeAliasPattern(aliasPattern); + const targetPattern = normalizeAliasPattern(targets[0]); + const absolutePath = path.resolve(projectRoot, baseUrl, targetPattern); + + return [`${alias}:${absolutePath}`, { alias, absolutePath }]; + }) + .filter(Boolean) + ).values(), + ]; + + aliasMap.sort((a, b) => b.absolutePath.length - a.absolutePath.length); + return aliasMap; +} + +export async function collectSourceFiles(rootDir) { + const files = []; + + async function walk(currentDir) { + const entries = await fs.readdir(currentDir, { withFileTypes: true }); + await Promise.all( + entries.map(async (entry) => { + if (entry.name.startsWith('.') && entry.name !== '.eslintrc') return; + if (entry.isDirectory()) { + if (SKIP_DIRS.has(entry.name)) return; + await walk(path.join(currentDir, entry.name)); + return; + } + + if (!entry.isFile()) return; + const filePath = path.join(currentDir, entry.name); + if (!SOURCE_EXTENSIONS.has(path.extname(entry.name))) return; + files.push(filePath); + }) + ); + } + + await walk(rootDir); + return files; +} + +function splitSpecifier(specifier) { + const match = specifier.match(/^([^?#]+)([?#].*)?$/); + if (!match) { + return { bare: specifier, suffix: '' }; + } + + return { + bare: match[1], + suffix: match[2] ?? '', + }; +} + +function findMatchingAlias(absoluteTargetPath, aliases) { + return aliases.find(({ absolutePath }) => { + const rel = path.relative(absolutePath, absoluteTargetPath); + return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel)); + }); +} + +function getRewrittenSpecifier(filePath, specifier, aliases, projectRoot) { + const normalizedFilePath = path.normalize(path.relative(projectRoot, filePath)); + const { bare, suffix } = splitSpecifier(specifier); + + if ( + !MATRIX_IMPORT_BOUNDARY_FILES.has(normalizedFilePath) && + (bare === 'matrix-js-sdk' || bare.startsWith('matrix-js-sdk/')) + ) { + return `$types/matrix-sdk${suffix}`; + } + + if (!/^\.\.(?:\/|$)/.test(bare)) { + return null; + } + + const absoluteTargetPath = path.resolve(path.dirname(filePath), bare); + const matchedAlias = findMatchingAlias(absoluteTargetPath, aliases); + if (!matchedAlias) return null; + + const aliasRelativePath = toPosix(path.relative(matchedAlias.absolutePath, absoluteTargetPath)); + const aliasImport = aliasRelativePath + ? `${matchedAlias.alias}/${aliasRelativePath}` + : matchedAlias.alias; + return `${aliasImport}${suffix}`; +} + +function queueReplacement(sourceFile, literalNode, replacements, aliases, filePath, projectRoot) { + const specifier = literalNode.text; + const rewrittenSpecifier = getRewrittenSpecifier(filePath, specifier, aliases, projectRoot); + if (!rewrittenSpecifier || rewrittenSpecifier === specifier) return; + + replacements.push({ + start: literalNode.getStart(sourceFile) + 1, + end: literalNode.getEnd() - 1, + original: specifier, + value: rewrittenSpecifier, + }); +} + +export function applyTextReplacements(sourceCode, replacements) { + return replacements.reduce( + (code, replacement) => + code.slice(0, replacement.start) + replacement.value + code.slice(replacement.end), + sourceCode + ); +} + +export function rewriteSourceImports(filePath, sourceCode, aliases, projectRoot) { + const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true); + const replacements = []; + + function visit(node) { + if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) { + queueReplacement( + sourceFile, + node.moduleSpecifier, + replacements, + aliases, + filePath, + projectRoot + ); + } else if ( + ts.isExportDeclaration(node) && + node.moduleSpecifier && + ts.isStringLiteral(node.moduleSpecifier) + ) { + queueReplacement( + sourceFile, + node.moduleSpecifier, + replacements, + aliases, + filePath, + projectRoot + ); + } else if (ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument)) { + const { literal } = node.argument; + if (ts.isStringLiteral(literal)) { + queueReplacement(sourceFile, literal, replacements, aliases, filePath, projectRoot); + } + } else if (ts.isCallExpression(node) && node.arguments.length > 0) { + const firstArg = node.arguments[0]; + if (ts.isStringLiteral(firstArg)) { + const isDynamicImport = node.expression.kind === ts.SyntaxKind.ImportKeyword; + const isRequire = ts.isIdentifier(node.expression) && node.expression.text === 'require'; + if (isDynamicImport || isRequire) { + queueReplacement(sourceFile, firstArg, replacements, aliases, filePath, projectRoot); + } + } + } + + ts.forEachChild(node, visit); + } + + visit(sourceFile); + if (replacements.length === 0) { + return { changed: false, updatedCode: sourceCode, replacements: 0, edits: [] }; + } + + const uniqueReplacements = [ + ...new Map( + replacements.map((replacement) => [`${replacement.start}:${replacement.end}`, replacement]) + ).values(), + ].toSorted((a, b) => b.start - a.start); + + const updatedCode = applyTextReplacements(sourceCode, uniqueReplacements); + + return { + changed: updatedCode !== sourceCode, + updatedCode, + replacements: uniqueReplacements.length, + edits: uniqueReplacements.map((replacement) => ({ + from: replacement.original, + to: replacement.value, + })), + }; +} + +function stripDeclarationExtension(relativePath) { + return relativePath + .replace(/\.d\.[cm]?ts$/i, '') + .replace(/\.[cm]?tsx?$/i, '') + .replace(/\.[cm]?js$/i, ''); +} + +export function getMatrixModuleSpecifierFromDeclarationFile(declarationFile) { + const normalizedFile = toPosix(declarationFile); + const marker = '/node_modules/matrix-js-sdk/'; + const markerIndex = normalizedFile.lastIndexOf(marker); + + if (markerIndex === -1) return null; + + const relativePath = normalizedFile.slice(markerIndex + marker.length); + return `matrix-js-sdk/${stripDeclarationExtension(relativePath)}`; +} + +function sortSpecifiers(specifiers) { + return [...specifiers].toSorted((left, right) => + left.importedName.localeCompare(right.importedName) + ); +} + +function formatSpecifier({ importedName, localName }) { + return importedName === localName ? importedName : `${importedName} as ${localName}`; +} + +export function renderMatrixImportGroups(groups) { + const lines = []; + + [...groups.entries()] + .toSorted(([left], [right]) => left.localeCompare(right)) + .forEach(([moduleSpecifier, group]) => { + const valueSpecifiers = sortSpecifiers(group.values); + const typeSpecifiers = sortSpecifiers(group.types); + + if (valueSpecifiers.length > 0) { + lines.push( + `import { ${valueSpecifiers.map(formatSpecifier).join(', ')} } from '${moduleSpecifier}';` + ); + } + + if (typeSpecifiers.length > 0) { + lines.push( + `import type { ${typeSpecifiers.map(formatSpecifier).join(', ')} } from '${moduleSpecifier}';` + ); + } + }); + + return lines; +} diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 383678e1a..15ca5ea34 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -130,8 +130,9 @@ export const toMatrixCustomHTML = ( // strip nicknames if needed if (opts.stripNickname && opts.nickNameReplacement) { - opts.nickNameReplacement?.keys().forEach((key) => { - const replacement = opts.nickNameReplacement!.get(key) ?? ''; + const { nickNameReplacement } = opts; + [...nickNameReplacement.keys()].forEach((key) => { + const replacement = nickNameReplacement.get(key) ?? ''; line = line.replaceAll(key, replacement); }); } @@ -215,7 +216,7 @@ export const toPlainText = ( if (Text.isText(node)) { if (stripNickname && nickNameReplacement) { let { text } = node; - nickNameReplacement?.keys().forEach((key) => { + [...nickNameReplacement.keys()].forEach((key) => { const replacement = nickNameReplacement.get(key) ?? ''; text = text.replaceAll(key, replacement); }); diff --git a/src/app/pages/Router.tsx b/src/app/pages/Router.tsx index d81890da1..15fecbda9 100644 --- a/src/app/pages/Router.tsx +++ b/src/app/pages/Router.tsx @@ -95,7 +95,10 @@ const getFirstSession = () => { return getFallbackSession(); }; -export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize) => { +export const createRouter = ( + clientConfig: ClientConfig, + screenSize: ScreenSize +): ReturnType => { const { hashRouter } = clientConfig; const mobile = screenSize === ScreenSize.Mobile; diff --git a/tsconfig.json b/tsconfig.json index a18b41f91..9535ab48c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,36 +1,15 @@ { - "compilerOptions": { - "sourceMap": true, - "jsx": "react-jsx", - "target": "ES2022", - "module": "ES2022", - "allowJs": true, - "strict": true, - "strictNullChecks": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "baseUrl": ".", - "paths": { - "$hooks/*": ["src/app/hooks/*"], - "$plugins/*": ["src/app/plugins/*"], - "$components/*": ["src/app/components/*"], - "$features/*": ["src/app/features/*"], - "$state/*": ["src/app/state/*"], - "$styles/*": ["src/app/styles/*"], - "$utils/*": ["src/app/utils/*"], - "$pages/*": ["src/app/pages/*"], - "$types/*": ["src/types/*"], - "$public/*": ["public/*"], - "$client/*": ["src/client/*"] - }, - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "noEmit": true, - "resolveJsonModule": true, - "outDir": "dist", - "skipLibCheck": true, - "lib": ["ES2022", "DOM"] + "typeAcquisition": { + "enable": false }, - "exclude": ["node_modules", "dist"], - "include": ["src", "vite.config.ts", "vitest.config.ts"] + "exclude": ["node_modules", "dist", "coverage", "public"], + "files": [], + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.web.json" + } + ] } diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 000000000..5f946f066 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "lib": ["ESNext"], + "types": ["node"], + "allowJs": true, + "checkJs": false, + "strict": true, + "strictNullChecks": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "composite": true, + "noEmit": true, + "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.node.tsbuildinfo" + }, + "include": [ + "build.config.ts", + "eslint.config.js", + "vite.config.ts", + "vitest.config.ts", + "scripts/**/*.js" + ], + "exclude": ["node_modules", "dist", "coverage"] +} diff --git a/tsconfig.web.json b/tsconfig.web.json new file mode 100644 index 000000000..bf24cd67c --- /dev/null +++ b/tsconfig.web.json @@ -0,0 +1,52 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "target": "ESNext", + "module": "ESNext", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "allowJs": true, + "checkJs": false, + "strict": true, + "strictNullChecks": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "composite": true, + "noEmit": true, + "noImplicitAny": true, + "alwaysStrict": true, + "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.web.tsbuildinfo", + "baseUrl": ".", + "paths": { + "$hooks": ["src/app/hooks"], + "$hooks/*": ["src/app/hooks/*"], + "$plugins": ["src/app/plugins"], + "$plugins/*": ["src/app/plugins/*"], + "$components": ["src/app/components"], + "$components/*": ["src/app/components/*"], + "$features": ["src/app/features"], + "$features/*": ["src/app/features/*"], + "$state": ["src/app/state"], + "$state/*": ["src/app/state/*"], + "$styles": ["src/app/styles"], + "$styles/*": ["src/app/styles/*"], + "$utils": ["src/app/utils"], + "$utils/*": ["src/app/utils/*"], + "$pages": ["src/app/pages"], + "$pages/*": ["src/app/pages/*"], + "$generated": ["src/app/generated"], + "$generated/*": ["src/app/generated/*"], + "$types": ["src/types"], + "$types/*": ["src/types/*"], + "$public": ["public"], + "$public/*": ["public/*"], + "$client": ["src/client"], + "$client/*": ["src/client/*"] + } + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "src/**/*.js", "src/**/*.jsx"], + "exclude": ["node_modules", "dist", "coverage"] +} diff --git a/vite.config.ts b/vite.config.ts index a130df507..e42303bbc 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -133,19 +133,7 @@ export default defineConfig(({ command }) => ({ IS_RELEASE_TAG: JSON.stringify(isReleaseTag), }, resolve: { - alias: { - $hooks: path.resolve(__dirname, 'src/app/hooks'), - $plugins: path.resolve(__dirname, 'src/app/plugins'), - $components: path.resolve(__dirname, 'src/app/components'), - $features: path.resolve(__dirname, 'src/app/features'), - $state: path.resolve(__dirname, 'src/app/state'), - $styles: path.resolve(__dirname, 'src/app/styles'), - $utils: path.resolve(__dirname, 'src/app/utils'), - $pages: path.resolve(__dirname, 'src/app/pages'), - $types: path.resolve(__dirname, 'src/types'), - $public: path.resolve(__dirname, 'public'), - $client: path.resolve(__dirname, 'src/client'), - }, + tsconfigPaths: true, }, server: { port: 8080, diff --git a/vitest.config.ts b/vitest.config.ts index fedea1151..f5f2dabe6 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,26 +1,13 @@ import { defineConfig } from 'vitest/config'; import react from '@vitejs/plugin-react'; import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; -import path from 'path'; // Standalone Vitest config — intentionally excludes Cloudflare, PWA, compression, // and other production-only Vite plugins that don't apply to unit tests. export default defineConfig({ plugins: [react(), vanillaExtractPlugin()], resolve: { - alias: { - $hooks: path.resolve(__dirname, 'src/app/hooks'), - $plugins: path.resolve(__dirname, 'src/app/plugins'), - $components: path.resolve(__dirname, 'src/app/components'), - $features: path.resolve(__dirname, 'src/app/features'), - $state: path.resolve(__dirname, 'src/app/state'), - $styles: path.resolve(__dirname, 'src/app/styles'), - $utils: path.resolve(__dirname, 'src/app/utils'), - $pages: path.resolve(__dirname, 'src/app/pages'), - $types: path.resolve(__dirname, 'src/types'), - $public: path.resolve(__dirname, 'public'), - $client: path.resolve(__dirname, 'src/client'), - }, + tsconfigPaths: true, }, define: { APP_VERSION: JSON.stringify('test'), @@ -31,7 +18,7 @@ export default defineConfig({ environment: 'jsdom', globals: true, setupFiles: ['./src/test/setup.ts'], - include: ['src/**/*.{test,spec}.{ts,tsx}'], + include: ['src/**/*.{test,spec}.{ts,tsx}', 'scripts/**/*.{test,spec}.{js,ts}'], coverage: { provider: 'v8', reporter: ['text', 'html', 'lcov'], From 83119ad433d24f7950be0293ef44004099326dac Mon Sep 17 00:00:00 2001 From: hazre Date: Sat, 28 Mar 2026 17:29:14 +0100 Subject: [PATCH 02/11] fix: make root tsconfig editor-facing --- .github/workflows/cloudflare-web-preview.yml | 4 ++ .github/workflows/sentry-preview-issues.yml | 2 + eslint.config.js | 5 +- package.json | 2 +- scripts/migrate-matrix-sdk-imports.js | 6 +- scripts/normalize-imports.js | 4 +- tsconfig.build.json | 14 +++++ tsconfig.json | 60 ++++++++++++++++---- tsconfig.web.json | 52 ----------------- 9 files changed, 79 insertions(+), 70 deletions(-) create mode 100644 tsconfig.build.json delete mode 100644 tsconfig.web.json diff --git a/.github/workflows/cloudflare-web-preview.yml b/.github/workflows/cloudflare-web-preview.yml index 8b93a4bb9..db6611ff2 100644 --- a/.github/workflows/cloudflare-web-preview.yml +++ b/.github/workflows/cloudflare-web-preview.yml @@ -9,6 +9,8 @@ on: - 'package-lock.json' - 'vite.config.ts' - 'tsconfig.json' + - 'tsconfig.build.json' + - 'tsconfig.node.json' - '.github/workflows/cloudflare-web-preview.yml' - '.github/actions/setup/**' push: @@ -21,6 +23,8 @@ on: - 'package-lock.json' - 'vite.config.ts' - 'tsconfig.json' + - 'tsconfig.build.json' + - 'tsconfig.node.json' - '.github/workflows/cloudflare-web-preview.yml' - '.github/actions/setup/**' diff --git a/.github/workflows/sentry-preview-issues.yml b/.github/workflows/sentry-preview-issues.yml index c81787e74..31d748925 100644 --- a/.github/workflows/sentry-preview-issues.yml +++ b/.github/workflows/sentry-preview-issues.yml @@ -9,6 +9,8 @@ on: - 'package.json' - 'vite.config.ts' - 'tsconfig.json' + - 'tsconfig.build.json' + - 'tsconfig.node.json' workflow_dispatch: inputs: pr_number: diff --git a/eslint.config.js b/eslint.config.js index dc2a2ebc6..27f5642d9 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -111,7 +111,7 @@ const projectOverrides = defineConfig([ 'import-x/resolver-next': [ createTypeScriptImportResolver({ alwaysTryTypes: true, - project: ['tsconfig.web.json', 'tsconfig.node.json'], + project: ['tsconfig.json', 'tsconfig.node.json'], }), ], }, @@ -157,7 +157,8 @@ const projectOverrides = defineConfig([ files: tsFiles, languageOptions: { parserOptions: { - projectService: true, + projectService: false, + project: ['tsconfig.json', 'tsconfig.node.json'], tsconfigRootDir: import.meta.dirname, }, }, diff --git a/package.json b/package.json index 86ea3ff21..8074cbe1c 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "lint:fix": "eslint . --fix", "fmt": "prettier --write .", "fmt:check": "prettier --check .", - "typecheck": "tsc -b", + "typecheck": "tsc -b tsconfig.build.json", "test": "vitest", "test:ui": "vitest --ui", "test:run": "vitest run", diff --git a/scripts/migrate-matrix-sdk-imports.js b/scripts/migrate-matrix-sdk-imports.js index d3417dd20..4bbedacf2 100644 --- a/scripts/migrate-matrix-sdk-imports.js +++ b/scripts/migrate-matrix-sdk-imports.js @@ -56,12 +56,12 @@ function parseArgs(argv) { } function loadProgram(projectRoot) { - const tsconfigPath = path.join(projectRoot, 'tsconfig.web.json'); + const tsconfigPath = path.join(projectRoot, 'tsconfig.json'); const configResult = ts.readConfigFile(tsconfigPath, ts.sys.readFile); if (configResult.error) { const message = ts.flattenDiagnosticMessageText(configResult.error.messageText, '\n'); - throw new Error(`Failed to read tsconfig.web.json: ${message}`); + throw new Error(`Failed to read tsconfig.json: ${message}`); } const parsedConfig = ts.parseJsonConfigFileContent( @@ -76,7 +76,7 @@ function loadProgram(projectRoot) { const message = parsedConfig.errors .map((error) => ts.flattenDiagnosticMessageText(error.messageText, '\n')) .join('\n'); - throw new Error(`Failed to parse tsconfig.web.json:\n${message}`); + throw new Error(`Failed to parse tsconfig.json:\n${message}`); } return ts.createProgram({ diff --git a/scripts/normalize-imports.js b/scripts/normalize-imports.js index 98989a4b6..cd091748e 100644 --- a/scripts/normalize-imports.js +++ b/scripts/normalize-imports.js @@ -53,13 +53,13 @@ async function main() { const projectRoot = process.cwd(); const { write, roots } = parseArgs(process.argv.slice(2)); const aliases = await loadAliasMapFromTsconfig( - path.join(projectRoot, 'tsconfig.web.json'), + path.join(projectRoot, 'tsconfig.json'), projectRoot ); const { dim, red, green } = createTextHelpers(); if (aliases.length === 0) { - throw new Error('No aliases found in tsconfig.web.json'); + throw new Error('No aliases found in tsconfig.json'); } const targetRoots = roots.map((root) => path.resolve(projectRoot, root)); diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 000000000..b08da7b51 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,14 @@ +{ + "typeAcquisition": { + "enable": false + }, + "files": [], + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.json" + } + ] +} diff --git a/tsconfig.json b/tsconfig.json index 9535ab48c..508446624 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,55 @@ { + "compilerOptions": { + "jsx": "react-jsx", + "target": "ESNext", + "module": "ESNext", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "allowJs": true, + "checkJs": false, + "strict": true, + "strictNullChecks": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "composite": true, + "noEmit": true, + "noImplicitAny": true, + "alwaysStrict": true, + "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.tsbuildinfo", + "baseUrl": ".", + "paths": { + "$hooks": ["src/app/hooks"], + "$hooks/*": ["src/app/hooks/*"], + "$plugins": ["src/app/plugins"], + "$plugins/*": ["src/app/plugins/*"], + "$components": ["src/app/components"], + "$components/*": ["src/app/components/*"], + "$features": ["src/app/features"], + "$features/*": ["src/app/features/*"], + "$state": ["src/app/state"], + "$state/*": ["src/app/state/*"], + "$styles": ["src/app/styles"], + "$styles/*": ["src/app/styles/*"], + "$utils": ["src/app/utils"], + "$utils/*": ["src/app/utils/*"], + "$pages": ["src/app/pages"], + "$pages/*": ["src/app/pages/*"], + "$generated": ["src/app/generated"], + "$generated/*": ["src/app/generated/*"], + "$types": ["src/types"], + "$types/*": ["src/types/*"], + "$public": ["public"], + "$public/*": ["public/*"], + "$client": ["src/client"], + "$client/*": ["src/client/*"] + } + }, "typeAcquisition": { "enable": false }, - "exclude": ["node_modules", "dist", "coverage", "public"], - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.web.json" - } - ] + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "src/**/*.js", "src/**/*.jsx"], + "exclude": ["node_modules", "dist", "coverage"] } diff --git a/tsconfig.web.json b/tsconfig.web.json deleted file mode 100644 index bf24cd67c..000000000 --- a/tsconfig.web.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "compilerOptions": { - "jsx": "react-jsx", - "target": "ESNext", - "module": "ESNext", - "lib": ["ESNext", "DOM", "DOM.Iterable"], - "allowJs": true, - "checkJs": false, - "strict": true, - "strictNullChecks": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "composite": true, - "noEmit": true, - "noImplicitAny": true, - "alwaysStrict": true, - "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.web.tsbuildinfo", - "baseUrl": ".", - "paths": { - "$hooks": ["src/app/hooks"], - "$hooks/*": ["src/app/hooks/*"], - "$plugins": ["src/app/plugins"], - "$plugins/*": ["src/app/plugins/*"], - "$components": ["src/app/components"], - "$components/*": ["src/app/components/*"], - "$features": ["src/app/features"], - "$features/*": ["src/app/features/*"], - "$state": ["src/app/state"], - "$state/*": ["src/app/state/*"], - "$styles": ["src/app/styles"], - "$styles/*": ["src/app/styles/*"], - "$utils": ["src/app/utils"], - "$utils/*": ["src/app/utils/*"], - "$pages": ["src/app/pages"], - "$pages/*": ["src/app/pages/*"], - "$generated": ["src/app/generated"], - "$generated/*": ["src/app/generated/*"], - "$types": ["src/types"], - "$types/*": ["src/types/*"], - "$public": ["public"], - "$public/*": ["public/*"], - "$client": ["src/client"], - "$client/*": ["src/client/*"] - } - }, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "src/**/*.js", "src/**/*.jsx"], - "exclude": ["node_modules", "dist", "coverage"] -} From 08f0234223366374fcf9f2375c05feeab0da762d Mon Sep 17 00:00:00 2001 From: hazre Date: Sun, 29 Mar 2026 15:12:07 +0200 Subject: [PATCH 03/11] chore: simplify tsconfig settings --- .vscode/settings.json | 6 +++++- tsconfig.build.json | 3 --- tsconfig.json | 12 ++++-------- tsconfig.node.json | 4 +--- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 29e56e92a..87d72b7ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,15 @@ { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", - "typescript.tsdk": "node_modules/typescript/lib", + "js/ts.tsdk.path": "node_modules/typescript/lib", "[jsonc]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "editor.formatOnSaveMode": "file", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" } } diff --git a/tsconfig.build.json b/tsconfig.build.json index b08da7b51..1195be209 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,7 +1,4 @@ { - "typeAcquisition": { - "enable": false - }, "files": [], "references": [ { diff --git a/tsconfig.json b/tsconfig.json index 508446624..35f50caf8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,20 +4,19 @@ "target": "ESNext", "module": "ESNext", "lib": ["ESNext", "DOM", "DOM.Iterable"], - "allowJs": true, + "allowJs": false, "checkJs": false, "strict": true, - "strictNullChecks": true, "esModuleInterop": true, - "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "composite": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + // "verbatimModuleSyntax": true, "noEmit": true, - "noImplicitAny": true, - "alwaysStrict": true, "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.tsbuildinfo", "baseUrl": ".", "paths": { @@ -47,9 +46,6 @@ "$client/*": ["src/client/*"] } }, - "typeAcquisition": { - "enable": false - }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "src/**/*.js", "src/**/*.jsx"], "exclude": ["node_modules", "dist", "coverage"] } diff --git a/tsconfig.node.json b/tsconfig.node.json index 5f946f066..bf9811ea3 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -5,11 +5,9 @@ "lib": ["ESNext"], "types": ["node"], "allowJs": true, - "checkJs": false, + "checkJs": true, "strict": true, - "strictNullChecks": true, "esModuleInterop": true, - "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "skipLibCheck": true, "moduleResolution": "bundler", From a900bada22bdc2923d48b2fe9630ce4daf9eb733 Mon Sep 17 00:00:00 2001 From: hazre Date: Sun, 29 Mar 2026 15:39:54 +0200 Subject: [PATCH 04/11] fix: restore typecheck under nodenext --- scripts/import-rewrites.test.js | 1 + scripts/install-knope.js | 43 +++++++- scripts/migrate-matrix-sdk-imports.js | 68 +++++++++++++ scripts/normalize-imports.js | 20 ++++ scripts/utils/console-style.js | 38 +++++++ scripts/utils/import-rewrites.js | 140 +++++++++++++++++++++++--- src/app/utils/bgColorImg.d.ts | 3 + src/client/secretStorageKeys.d.ts | 8 ++ tsconfig.node.json | 8 +- vite.config.ts | 17 +++- 10 files changed, 325 insertions(+), 21 deletions(-) create mode 100644 src/app/utils/bgColorImg.d.ts create mode 100644 src/client/secretStorageKeys.d.ts diff --git a/scripts/import-rewrites.test.js b/scripts/import-rewrites.test.js index 6b65f2c6d..65348b81f 100644 --- a/scripts/import-rewrites.test.js +++ b/scripts/import-rewrites.test.js @@ -10,6 +10,7 @@ import { rewriteSourceImports, } from './utils/import-rewrites.js'; +/** @type {string[]} */ const tempDirs = []; async function makeTempProject() { diff --git a/scripts/install-knope.js b/scripts/install-knope.js index cbda39e57..4b8d0118a 100644 --- a/scripts/install-knope.js +++ b/scripts/install-knope.js @@ -11,6 +11,11 @@ import { PrefixedLogger, createTextHelpers } from './utils/console-style.js'; const __dirname = dirname(fileURLToPath(import.meta.url)); const VERSION = '0.22.3'; +/** + * @typedef {'linux-x64' | 'linux-arm64' | 'darwin-x64' | 'darwin-arm64' | 'win32-x64'} SupportedTargetKey + */ + +/** @type {Record} */ const TARGETS = { 'linux-x64': 'x86_64-unknown-linux-musl', 'linux-arm64': 'aarch64-unknown-linux-musl', @@ -19,11 +24,19 @@ const TARGETS = { 'win32-x64': 'x86_64-pc-windows-msvc', }; +/** + * @param {string | null | undefined} output + * @returns {string | null} + */ function parseKnopeVersion(output) { const version = output?.trim().replace(/^knope\s+/, ''); return version || null; } +/** + * @param {string} command + * @returns {string | null} + */ function getKnopeVersion(command) { const result = spawnSync(command, ['--version'], { encoding: 'utf8' }); if (result.status !== 0) { @@ -32,17 +45,30 @@ function getKnopeVersion(command) { return parseKnopeVersion(result.stdout); } +/** + * @param {Buffer} buffer + * @returns {string} + */ function readNullTerminatedString(buffer) { const nulIndex = buffer.indexOf(0); const end = nulIndex === -1 ? buffer.length : nulIndex; return buffer.toString('utf8', 0, end); } +/** + * @param {string} entryName + * @returns {string} + */ function getTarBasename(entryName) { const segments = entryName.split('/').filter(Boolean); return segments.at(-1) ?? ''; } +/** + * @param {Buffer} tarBuffer + * @param {string} expectedBasename + * @returns {Buffer} + */ function extractRegularFileFromTar(tarBuffer, expectedBasename) { let offset = 0; const regularEntries = []; @@ -87,6 +113,9 @@ function extractRegularFileFromTar(tarBuffer, expectedBasename) { ); } +/** + * @returns {string | null} + */ function getSystemKnopePath() { const which = spawnSync(process.platform === 'win32' ? 'where' : 'which', ['knope'], { encoding: 'utf8', @@ -102,7 +131,16 @@ function getSystemKnopePath() { ); } +/** + * @param {string} candidatePath + * @param {string} rootPath + * @returns {boolean} + */ function isPathWithin(candidatePath, rootPath) { + /** + * @param {string} value + * @returns {string} + */ const toComparablePath = (value) => { const resolved = resolve(value); return process.platform === 'win32' ? resolved.toLowerCase() : resolved; @@ -120,7 +158,10 @@ if (process.env.GITHUB_ACTIONS && process.env.CI) { process.exit(0); } -const target = TARGETS[`${process.platform}-${process.arch}`]; +const targetKey = `${process.platform}-${process.arch}`; +const target = Object.hasOwn(TARGETS, targetKey) + ? TARGETS[/** @type {SupportedTargetKey} */ (targetKey)] + : undefined; if (!target) { const supported = Object.keys(TARGETS).join(', '); logger.error( diff --git a/scripts/migrate-matrix-sdk-imports.js b/scripts/migrate-matrix-sdk-imports.js index 4bbedacf2..ab0934874 100644 --- a/scripts/migrate-matrix-sdk-imports.js +++ b/scripts/migrate-matrix-sdk-imports.js @@ -19,6 +19,40 @@ import { const MATRIX_BOUNDARY_SPECIFIER = '$types/matrix-sdk'; +/** + * @typedef {{ + * write: boolean; + * roots: string[]; + * }} CliArgs + */ + +/** + * @typedef {{ + * importedName: string; + * localName: string; + * }} ImportEntry + */ + +/** + * @typedef {{ + * values: ImportEntry[]; + * types: ImportEntry[]; + * }} MatrixImportGroup + */ + +/** + * @typedef {{ + * start: number; + * end: number; + * original: string; + * value: string; + * }} Replacement + */ + +/** + * @param {string[]} argv + * @returns {CliArgs} + */ function parseArgs(argv) { let write = false; const roots = []; @@ -55,6 +89,10 @@ function parseArgs(argv) { }; } +/** + * @param {string} projectRoot + * @returns {import('typescript').Program} + */ function loadProgram(projectRoot) { const tsconfigPath = path.join(projectRoot, 'tsconfig.json'); const configResult = ts.readConfigFile(tsconfigPath, ts.sys.readFile); @@ -85,6 +123,11 @@ function loadProgram(projectRoot) { }); } +/** + * @param {string} filePath + * @param {string[]} rootPaths + * @returns {boolean} + */ function isWithinRoots(filePath, rootPaths) { return rootPaths.some((rootPath) => { const relativePath = path.relative(rootPath, filePath); @@ -94,6 +137,11 @@ function isWithinRoots(filePath, rootPaths) { }); } +/** + * @param {import('typescript').TypeChecker} checker + * @param {import('typescript').ImportSpecifier} specifier + * @returns {string | null} + */ function getDeclarationModuleSpecifier(checker, specifier) { const importedSymbol = checker.getSymbolAtLocation(specifier.name); if (!importedSymbol) return null; @@ -108,6 +156,10 @@ function getDeclarationModuleSpecifier(checker, specifier) { return getMatrixModuleSpecifierFromDeclarationFile(declaration.getSourceFile().fileName); } +/** + * @param {import('typescript').ImportSpecifier} specifier + * @returns {ImportEntry} + */ function getImportEntry(specifier) { return { importedName: specifier.propertyName?.text ?? specifier.name.text, @@ -115,6 +167,11 @@ function getImportEntry(specifier) { }; } +/** + * @param {import('typescript').TypeChecker} checker + * @param {import('typescript').ImportDeclaration} importDeclaration + * @returns {string | null} + */ function buildReplacementText(checker, importDeclaration) { const importClause = importDeclaration.importClause; if ( @@ -125,6 +182,7 @@ function buildReplacementText(checker, importDeclaration) { return null; } + /** @type {Map} */ const groups = new Map(); for (const specifier of importClause.namedBindings.elements) { @@ -142,9 +200,18 @@ function buildReplacementText(checker, importDeclaration) { return renderMatrixImportGroups(groups).join('\n'); } +/** + * @param {import('typescript').SourceFile} sourceFile + * @param {import('typescript').TypeChecker} checker + * @returns {Replacement[]} + */ function collectReplacements(sourceFile, checker) { + /** @type {Replacement[]} */ const replacements = []; + /** + * @param {import('typescript').Node} node + */ function visit(node) { if ( ts.isImportDeclaration(node) && @@ -156,6 +223,7 @@ function collectReplacements(sourceFile, checker) { replacements.push({ start: node.getStart(sourceFile), end: node.getEnd(), + original: '', value: replacementText, }); } diff --git a/scripts/normalize-imports.js b/scripts/normalize-imports.js index cd091748e..a8dc36b1c 100644 --- a/scripts/normalize-imports.js +++ b/scripts/normalize-imports.js @@ -13,6 +13,25 @@ import { toPosix, } from './utils/import-rewrites.js'; +/** + * @typedef {{ + * write: boolean; + * roots: string[]; + * }} CliArgs + */ + +/** + * @typedef {{ + * file: string; + * replacements: number; + * edits: { from: string; to: string }[]; + * }} FileResult + */ + +/** + * @param {string[]} argv + * @returns {CliArgs} + */ function parseArgs(argv) { let write = false; const roots = []; @@ -101,6 +120,7 @@ async function main() { }) ); + /** @type {FileResult[]} */ const changedFiles = fileResults.filter((result) => result !== null); const filesChanged = changedFiles.length; const importRewrites = changedFiles.reduce((total, result) => total + result.replacements, 0); diff --git a/scripts/utils/console-style.js b/scripts/utils/console-style.js index 96ed5bf3e..7819168e7 100644 --- a/scripts/utils/console-style.js +++ b/scripts/utils/console-style.js @@ -1,6 +1,17 @@ /* eslint-disable no-console */ import process from 'node:process'; +/** + * @typedef {object} TextHelperOptions + * @property {boolean} [useColor] + */ + +/** + * @typedef {TextHelperOptions & { + * prefixColor?: string; + * }} LoggerOptions + */ + export const ANSI = { reset: '\x1b[0m', red: '\x1b[31m', @@ -14,16 +25,33 @@ export function shouldUseColor() { return Boolean(process.stdout.isTTY); } +/** + * @param {string} text + * @param {string} color + * @param {boolean} enabled + * @returns {string} + */ export function styleText(text, color, enabled) { if (!enabled) return text; return `${color}${text}${ANSI.reset}`; } +/** + * @param {TextHelperOptions} [options] + */ export function createTextHelpers(options = {}) { const useColor = options.useColor ?? shouldUseColor(); + /** + * @param {string} text + * @param {string} color + * @returns {string} + */ const style = (text, color) => styleText(text, color, useColor); + /** @param {string} text */ const dim = (text) => styleText(text, ANSI.dim, useColor); + /** @param {string} text */ const red = (text) => styleText(text, ANSI.red, useColor); + /** @param {string} text */ const green = (text) => styleText(text, ANSI.green, useColor); return { useColor, @@ -35,20 +63,30 @@ export function createTextHelpers(options = {}) { } export class PrefixedLogger { + /** + * @param {string} prefix + * @param {LoggerOptions} [options] + */ constructor(prefix, options = {}) { this.prefix = prefix; this.useColor = options.useColor ?? shouldUseColor(); this.prefixColor = options.prefixColor ?? ANSI.dim; } + /** + * @param {string} message + * @returns {string} + */ withPrefix(message) { return `${styleText(this.prefix, this.prefixColor, this.useColor)} ${message}`; } + /** @param {string} message */ info(message) { console.log(this.withPrefix(message)); } + /** @param {string} message */ error(message) { console.error(this.withPrefix(message)); } diff --git a/scripts/utils/import-rewrites.js b/scripts/utils/import-rewrites.js index 35ca000ba..5f4be69b0 100644 --- a/scripts/utils/import-rewrites.js +++ b/scripts/utils/import-rewrites.js @@ -3,6 +3,36 @@ import path from 'node:path'; import ts from 'typescript'; +/** + * @typedef {{ + * alias: string; + * absolutePath: string; + * }} AliasEntry + */ + +/** + * @typedef {{ + * start: number; + * end: number; + * original: string; + * value: string; + * }} TextReplacement + */ + +/** + * @typedef {{ + * importedName: string; + * localName: string; + * }} MatrixImportSpecifier + */ + +/** + * @typedef {{ + * values: MatrixImportSpecifier[]; + * types: MatrixImportSpecifier[]; + * }} MatrixImportGroup + */ + export const DEFAULT_ROOTS = ['src']; export const SKIP_DIRS = new Set(['.git', '.hg', '.svn', 'node_modules', 'dist', 'coverage']); export const SOURCE_EXTENSIONS = new Set([ @@ -20,18 +50,35 @@ export const MATRIX_IMPORT_BOUNDARY_FILES = new Set([ path.normalize('src/types/matrix-sdk-events.d.ts'), ]); +/** + * @param {string} inputPath + * @returns {string} + */ export function toPosix(inputPath) { return inputPath.split(path.sep).join('/'); } +/** + * @param {string} pattern + * @returns {string} + */ function normalizeAliasPattern(pattern) { return pattern.replace(/\/\*$/, ''); } +/** + * @param {import('typescript').Diagnostic} error + * @returns {string} + */ function getConfigErrorMessage(error) { return ts.flattenDiagnosticMessageText(error.messageText, '\n'); } +/** + * @param {string} tsconfigPath + * @param {string} projectRoot + * @returns {Promise} + */ export async function loadAliasMapFromTsconfig(tsconfigPath, projectRoot) { const configResult = ts.readConfigFile(tsconfigPath, ts.sys.readFile); if (configResult.error) { @@ -44,29 +91,35 @@ export async function loadAliasMapFromTsconfig(tsconfigPath, projectRoot) { const baseUrl = compilerOptions.baseUrl ?? '.'; const paths = compilerOptions.paths ?? {}; - const aliasMap = [ - ...new Map( - Object.entries(paths) - .map(([aliasPattern, targets]) => { - if (!Array.isArray(targets) || targets.length === 0) return null; + /** @type {Map} */ + const aliasEntries = new Map(); + for (const [aliasPattern, targets] of Object.entries(paths)) { + if (!Array.isArray(targets) || targets.length === 0) continue; - const alias = normalizeAliasPattern(aliasPattern); - const targetPattern = normalizeAliasPattern(targets[0]); - const absolutePath = path.resolve(projectRoot, baseUrl, targetPattern); + const alias = normalizeAliasPattern(aliasPattern); + const targetPattern = normalizeAliasPattern(targets[0]); + const absolutePath = path.resolve(projectRoot, baseUrl, targetPattern); + aliasEntries.set(`${alias}:${absolutePath}`, { alias, absolutePath }); + } - return [`${alias}:${absolutePath}`, { alias, absolutePath }]; - }) - .filter(Boolean) - ).values(), - ]; + const aliasMap = [...aliasEntries.values()]; aliasMap.sort((a, b) => b.absolutePath.length - a.absolutePath.length); return aliasMap; } +/** + * @param {string} rootDir + * @returns {Promise} + */ export async function collectSourceFiles(rootDir) { + /** @type {string[]} */ const files = []; + /** + * @param {string} currentDir + * @returns {Promise} + */ async function walk(currentDir) { const entries = await fs.readdir(currentDir, { withFileTypes: true }); await Promise.all( @@ -90,6 +143,10 @@ export async function collectSourceFiles(rootDir) { return files; } +/** + * @param {string} specifier + * @returns {{ bare: string; suffix: string }} + */ function splitSpecifier(specifier) { const match = specifier.match(/^([^?#]+)([?#].*)?$/); if (!match) { @@ -102,6 +159,11 @@ function splitSpecifier(specifier) { }; } +/** + * @param {string} absoluteTargetPath + * @param {AliasEntry[]} aliases + * @returns {AliasEntry | undefined} + */ function findMatchingAlias(absoluteTargetPath, aliases) { return aliases.find(({ absolutePath }) => { const rel = path.relative(absolutePath, absoluteTargetPath); @@ -109,6 +171,13 @@ function findMatchingAlias(absoluteTargetPath, aliases) { }); } +/** + * @param {string} filePath + * @param {string} specifier + * @param {AliasEntry[]} aliases + * @param {string} projectRoot + * @returns {string | null} + */ function getRewrittenSpecifier(filePath, specifier, aliases, projectRoot) { const normalizedFilePath = path.normalize(path.relative(projectRoot, filePath)); const { bare, suffix } = splitSpecifier(specifier); @@ -135,6 +204,14 @@ function getRewrittenSpecifier(filePath, specifier, aliases, projectRoot) { return `${aliasImport}${suffix}`; } +/** + * @param {import('typescript').SourceFile} sourceFile + * @param {import('typescript').StringLiteral} literalNode + * @param {TextReplacement[]} replacements + * @param {AliasEntry[]} aliases + * @param {string} filePath + * @param {string} projectRoot + */ function queueReplacement(sourceFile, literalNode, replacements, aliases, filePath, projectRoot) { const specifier = literalNode.text; const rewrittenSpecifier = getRewrittenSpecifier(filePath, specifier, aliases, projectRoot); @@ -148,6 +225,11 @@ function queueReplacement(sourceFile, literalNode, replacements, aliases, filePa }); } +/** + * @param {string} sourceCode + * @param {TextReplacement[]} replacements + * @returns {string} + */ export function applyTextReplacements(sourceCode, replacements) { return replacements.reduce( (code, replacement) => @@ -156,10 +238,20 @@ export function applyTextReplacements(sourceCode, replacements) { ); } +/** + * @param {string} filePath + * @param {string} sourceCode + * @param {AliasEntry[]} aliases + * @param {string} projectRoot + */ export function rewriteSourceImports(filePath, sourceCode, aliases, projectRoot) { const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true); + /** @type {TextReplacement[]} */ const replacements = []; + /** + * @param {import('typescript').Node} node + */ function visit(node) { if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) { queueReplacement( @@ -207,6 +299,7 @@ export function rewriteSourceImports(filePath, sourceCode, aliases, projectRoot) return { changed: false, updatedCode: sourceCode, replacements: 0, edits: [] }; } + /** @type {TextReplacement[]} */ const uniqueReplacements = [ ...new Map( replacements.map((replacement) => [`${replacement.start}:${replacement.end}`, replacement]) @@ -226,6 +319,10 @@ export function rewriteSourceImports(filePath, sourceCode, aliases, projectRoot) }; } +/** + * @param {string} relativePath + * @returns {string} + */ function stripDeclarationExtension(relativePath) { return relativePath .replace(/\.d\.[cm]?ts$/i, '') @@ -233,6 +330,10 @@ function stripDeclarationExtension(relativePath) { .replace(/\.[cm]?js$/i, ''); } +/** + * @param {string} declarationFile + * @returns {string | null} + */ export function getMatrixModuleSpecifierFromDeclarationFile(declarationFile) { const normalizedFile = toPosix(declarationFile); const marker = '/node_modules/matrix-js-sdk/'; @@ -244,17 +345,30 @@ export function getMatrixModuleSpecifierFromDeclarationFile(declarationFile) { return `matrix-js-sdk/${stripDeclarationExtension(relativePath)}`; } +/** + * @param {MatrixImportSpecifier[]} specifiers + * @returns {MatrixImportSpecifier[]} + */ function sortSpecifiers(specifiers) { return [...specifiers].toSorted((left, right) => left.importedName.localeCompare(right.importedName) ); } +/** + * @param {MatrixImportSpecifier} specifier + * @returns {string} + */ function formatSpecifier({ importedName, localName }) { return importedName === localName ? importedName : `${importedName} as ${localName}`; } +/** + * @param {Map} groups + * @returns {string[]} + */ export function renderMatrixImportGroups(groups) { + /** @type {string[]} */ const lines = []; [...groups.entries()] diff --git a/src/app/utils/bgColorImg.d.ts b/src/app/utils/bgColorImg.d.ts new file mode 100644 index 000000000..f38db24f9 --- /dev/null +++ b/src/app/utils/bgColorImg.d.ts @@ -0,0 +1,3 @@ +declare function bgColorImg(img: HTMLImageElement): string; + +export default bgColorImg; diff --git a/src/client/secretStorageKeys.d.ts b/src/client/secretStorageKeys.d.ts new file mode 100644 index 000000000..9b14490f6 --- /dev/null +++ b/src/client/secretStorageKeys.d.ts @@ -0,0 +1,8 @@ +import type { CryptoCallbacks } from '$types/matrix-sdk'; + +export function storePrivateKey(keyId: string, privateKey: Uint8Array): void; +export function clearSecretStorageKeys(): void; +export const cryptoCallbacks: Pick< + CryptoCallbacks, + 'getSecretStorageKey' | 'cacheSecretStorageKey' +>; diff --git a/tsconfig.node.json b/tsconfig.node.json index bf9811ea3..8278dad8d 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,17 +1,21 @@ { "compilerOptions": { "target": "ESNext", - "module": "ESNext", + "module": "NodeNext", "lib": ["ESNext"], "types": ["node"], "allowJs": true, "checkJs": true, "strict": true, "esModuleInterop": true, + "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "skipLibCheck": true, - "moduleResolution": "bundler", + "moduleResolution": "NodeNext", "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "erasableSyntaxOnly": true, + "verbatimModuleSyntax": true, "composite": true, "noEmit": true, "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.node.tsbuildinfo" diff --git a/vite.config.ts b/vite.config.ts index e42303bbc..c59789218 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,14 +1,16 @@ import { defineConfig } from 'vite'; import type { ViteDevServer, PluginOption } from 'vite'; import { execSync } from 'child_process'; +import type { RollupInjectOptions } from '@rollup/plugin-inject'; import react from '@vitejs/plugin-react'; import svgr from 'vite-plugin-svgr'; import { wasm } from '@rollup/plugin-wasm'; import { viteStaticCopy } from 'vite-plugin-static-copy'; import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; -import inject from '@rollup/plugin-inject'; -import topLevelAwait from 'vite-plugin-top-level-await'; +import * as injectModule from '@rollup/plugin-inject'; +import * as topLevelAwaitModule from 'vite-plugin-top-level-await'; +import type { Options as TopLevelAwaitOptions } from 'vite-plugin-top-level-await'; import { VitePWA } from 'vite-plugin-pwa'; import { compression, defineAlgorithm } from 'vite-plugin-compression2'; import { constants as zlibConstants } from 'zlib'; @@ -17,7 +19,12 @@ import path from 'path'; import { cloudflare } from '@cloudflare/vite-plugin'; import { createRequire } from 'module'; import { sentryVitePlugin } from '@sentry/vite-plugin'; -import buildConfig from './build.config'; +import buildConfig from './build.config.ts'; + +const inject = injectModule.default as unknown as (options?: RollupInjectOptions) => PluginOption; +const topLevelAwait = topLevelAwaitModule.default as unknown as ( + options?: TopLevelAwaitOptions +) => PluginOption; const packageJson = JSON.parse( fs.readFileSync(path.resolve(__dirname, 'package.json'), 'utf8') @@ -150,7 +157,7 @@ export default defineConfig(({ command }) => ({ // The export name of top-level await promise for each chunk module promiseExportName: '__tla', // The function to generate import names of top-level await promise in each chunk module - promiseImportName: (i) => `__tla_${i}`, + promiseImportName: (i: number) => `__tla_${i}`, }), viteStaticCopy(copyFiles), vanillaExtractPlugin({ identifiers: 'debug' }), @@ -237,7 +244,7 @@ export default defineConfig(({ command }) => ({ sourcemap: true, copyPublicDir: false, rollupOptions: { - plugins: [inject({ Buffer: ['buffer', 'Buffer'] }) as PluginOption], + plugins: [inject({ Buffer: ['buffer', 'Buffer'] })], }, }, })); From 3f6f637ba509cca4b9c44e2087aece07243d558f Mon Sep 17 00:00:00 2001 From: hazre Date: Sun, 29 Mar 2026 15:45:30 +0200 Subject: [PATCH 05/11] chore: enable verbatim module syntax --- src/app/components/AccountDataEditor.tsx | 4 +- src/app/components/ActionUIA.tsx | 4 +- src/app/components/AuthFlowsLoader.tsx | 8 ++-- src/app/components/BackRouteHandler.tsx | 2 +- src/app/components/BackupRestore.tsx | 6 +-- src/app/components/CallEmbedProvider.tsx | 4 +- src/app/components/ClientConfigLoader.tsx | 4 +- src/app/components/ConfirmPasswordMatch.tsx | 2 +- src/app/components/DeviceVerification.tsx | 8 ++-- .../components/DeviceVerificationSetup.tsx | 4 +- .../components/DeviceVerificationStatus.ts | 6 +-- .../components/GlobalKeyboardShortcuts.tsx | 2 +- src/app/components/HexColorPickerPopOut.tsx | 4 +- src/app/components/JoinRulesSwitcher.tsx | 6 +-- src/app/components/ManualVerification.tsx | 6 +-- src/app/components/Modal500.tsx | 2 +- src/app/components/Pdf-viewer/PdfViewer.tsx | 4 +- src/app/components/RenderMessageContent.tsx | 4 +- .../components/RoomNotificationSwitcher.tsx | 4 +- src/app/components/RoomSummaryLoader.tsx | 8 ++-- src/app/components/RoomUnreadProvider.tsx | 4 +- src/app/components/SecretStorage.tsx | 7 +++- src/app/components/ServerConfigsLoader.tsx | 10 +++-- src/app/components/SpecVersionsLoader.tsx | 4 +- .../components/SupportedUIAFlowsLoader.tsx | 4 +- src/app/components/SwipeableChatWrapper.tsx | 2 +- .../components/SwipeableMessageWrapper.tsx | 2 +- .../components/SwipeableOverlayWrapper.tsx | 2 +- src/app/components/UIAFlowOverlay.tsx | 2 +- src/app/components/UseStateProvider.tsx | 2 +- .../components/UserRoomProfileRenderer.tsx | 2 +- .../create-room/AdditionalCreatorInput.tsx | 10 ++--- .../create-room/CreateRoomAccessSelector.tsx | 2 +- .../create-room/CreateRoomAliasInput.tsx | 6 +-- .../create-room/CreateRoomTypeSelector.tsx | 2 +- .../create-room/RoomVersionSelector.tsx | 4 +- src/app/components/create-room/utils.ts | 10 ++--- src/app/components/cutout-card/CutoutCard.tsx | 2 +- src/app/components/editor/Editor.tsx | 16 ++++---- src/app/components/editor/Elements.tsx | 11 +++-- src/app/components/editor/Toolbar.tsx | 8 ++-- .../editor/autocomplete/AutocompleteMenu.tsx | 4 +- .../autocomplete/AutocompleteNotice.tsx | 2 +- .../autocomplete/BaseAutocompleteMenu.tsx | 2 +- .../autocomplete/EmoticonAutocomplete.tsx | 14 +++---- .../autocomplete/RoomMentionAutocomplete.tsx | 10 ++--- .../autocomplete/UserMentionAutocomplete.tsx | 14 ++++--- .../editor/autocomplete/autocompleteQuery.ts | 2 +- src/app/components/editor/input.ts | 30 +++++++------- src/app/components/editor/keyboard.ts | 2 +- src/app/components/editor/output.ts | 6 +-- src/app/components/editor/slate.d.ts | 8 ++-- src/app/components/editor/utils.ts | 23 +++++++---- src/app/components/emoji-board/EmojiBoard.tsx | 22 +++++----- .../emoji-board/components/Group.tsx | 2 +- .../emoji-board/components/Item.tsx | 8 ++-- .../emoji-board/components/Layout.tsx | 2 +- .../emoji-board/components/Preview.tsx | 2 +- .../emoji-board/components/SearchInput.tsx | 2 +- .../emoji-board/components/Sidebar.tsx | 4 +- .../emoji-board/components/Tabs.tsx | 2 +- .../emoji-board/useEmojiGroupIcons.ts | 2 +- .../components/event-history/EventHistory.tsx | 6 +-- .../components/event-readers/EventReaders.tsx | 2 +- .../image-pack-view/ImagePackContent.tsx | 12 +++--- .../image-pack-view/ImagePackView.tsx | 2 +- .../components/image-pack-view/ImageTile.tsx | 6 +-- .../components/image-pack-view/PackMeta.tsx | 4 +- .../image-pack-view/RoomImagePack.tsx | 4 +- .../image-pack-view/UsageSwitcher.tsx | 15 ++++++- .../image-pack-view/UserImagePack.tsx | 2 +- .../components/image-viewer/ImageViewer.tsx | 2 +- src/app/components/info-card/InfoCard.tsx | 4 +- .../invite-user-prompt/InviteUserPrompt.tsx | 10 ++--- .../join-address-prompt/JoinAddressPrompt.tsx | 2 +- .../knock-room-prompt/KnockRoomPrompt.tsx | 4 +- .../leave-room-prompt/LeaveRoomPrompt.tsx | 2 +- .../leave-space-prompt/LeaveSpacePrompt.tsx | 2 +- src/app/components/media/Image.tsx | 2 +- src/app/components/media/MediaControls.tsx | 2 +- src/app/components/media/Video.tsx | 2 +- src/app/components/member-tile/MemberTile.tsx | 4 +- src/app/components/message/FileHeader.tsx | 4 +- .../components/message/MsgTypeRenderers.tsx | 26 ++++++------ src/app/components/message/Reaction.tsx | 2 +- src/app/components/message/RenderBody.tsx | 8 ++-- src/app/components/message/Reply.tsx | 11 +++-- src/app/components/message/Time.tsx | 2 +- .../message/attachment/Attachment.css.ts | 2 +- .../message/content/AudioContent.tsx | 8 ++-- .../message/content/EventContent.tsx | 4 +- .../message/content/FileContent.tsx | 6 +-- .../message/content/ImageContent.tsx | 6 +-- .../message/content/ThumbnailContent.tsx | 4 +- .../message/content/VideoContent.tsx | 8 ++-- src/app/components/message/layout/Bubble.tsx | 4 +- src/app/components/message/layout/Compact.tsx | 2 +- src/app/components/message/layout/Modern.tsx | 2 +- .../components/message/layout/layout.css.ts | 2 +- .../message/modals/MessageDelete.tsx | 4 +- .../message/modals/MessageEditHistory.tsx | 4 +- .../message/modals/MessageForward.tsx | 2 +- .../message/modals/MessageReactions.tsx | 4 +- .../message/modals/MessageReadRecipts.tsx | 4 +- .../message/modals/MessageReport.tsx | 4 +- .../message/modals/MessageSource.tsx | 4 +- .../placeholder/CompactPlaceholder.tsx | 2 +- .../placeholder/DefaultPlaceholder.tsx | 4 +- .../placeholder/LinePlaceholder.css.ts | 6 +-- src/app/components/nav/NavCategory.tsx | 2 +- src/app/components/nav/NavCategoryHeader.tsx | 2 +- src/app/components/nav/NavEmptyLayout.tsx | 2 +- src/app/components/nav/NavItem.tsx | 2 +- src/app/components/nav/NavItemContent.tsx | 2 +- src/app/components/nav/NavItemOptions.tsx | 2 +- src/app/components/nav/styles.css.ts | 14 +++++-- .../NotificationBanner.tsx | 4 +- src/app/components/page/Page.tsx | 2 +- src/app/components/page/style.css.ts | 2 +- .../password-input/PasswordInput.tsx | 2 +- src/app/components/power/PowerSelector.tsx | 6 +-- src/app/components/power/style.css.ts | 2 +- src/app/components/presence/Presence.tsx | 6 +-- .../components/room-avatar/AvatarImage.tsx | 2 +- src/app/components/room-avatar/RoomAvatar.tsx | 4 +- src/app/components/room-card/RoomCard.tsx | 4 +- src/app/components/room-intro/RoomIntro.tsx | 4 +- .../ScrollTopContainer.tsx | 2 +- .../components/sequence-card/SequenceCard.tsx | 4 +- src/app/components/sequence-card/style.css.ts | 2 +- .../components/setting-tile/SettingTile.tsx | 2 +- src/app/components/sidebar/Sidebar.css.ts | 2 +- src/app/components/sidebar/SidebarContent.tsx | 2 +- src/app/components/sidebar/SidebarItem.tsx | 2 +- .../components/sidebar/SidebarUnreadBadge.tsx | 6 ++- .../components/splash-screen/SplashScreen.tsx | 2 +- .../components/stacked-avatar/styles.css.ts | 6 +-- src/app/components/text-viewer/TextViewer.tsx | 2 +- src/app/components/time-date/PickerColumn.tsx | 2 +- src/app/components/uia-stages/DummyStage.tsx | 2 +- src/app/components/uia-stages/EmailStage.tsx | 10 ++--- .../components/uia-stages/PasswordStage.tsx | 4 +- .../components/uia-stages/ReCaptchaStage.tsx | 2 +- .../uia-stages/RegistrationTokenStage.tsx | 4 +- src/app/components/uia-stages/SSOStage.tsx | 2 +- src/app/components/uia-stages/TermsStage.tsx | 2 +- src/app/components/uia-stages/types.ts | 4 +- .../components/unread-badge/UnreadBadge.tsx | 2 +- .../components/upload-board/UploadBoard.tsx | 9 +++- .../upload-card/CompactUploadCardRenderer.tsx | 9 +++- .../components/upload-card/UploadCard.css.ts | 2 +- src/app/components/upload-card/UploadCard.tsx | 2 +- .../upload-card/UploadCardRenderer.tsx | 16 +++++--- .../upload-card/UploadDescriptionEditor.tsx | 6 +-- .../components/url-preview/ClientPreview.tsx | 2 +- .../components/url-preview/UrlPreviewCard.tsx | 2 +- src/app/components/user-avatar/UserAvatar.tsx | 2 +- .../components/user-profile/CreatorChip.tsx | 4 +- src/app/components/user-profile/PowerChip.tsx | 4 +- src/app/components/user-profile/UserChips.tsx | 8 ++-- src/app/components/user-profile/UserHero.tsx | 2 +- .../user-profile/UserRoomProfile.tsx | 10 ++--- .../components/virtualizer/VirtualTile.tsx | 2 +- src/app/features/add-existing/AddExisting.tsx | 12 ++++-- src/app/features/call-status/CallControl.tsx | 2 +- src/app/features/call-status/CallRoomName.tsx | 2 +- src/app/features/call-status/CallStatus.tsx | 2 +- src/app/features/call-status/LiveChip.tsx | 8 ++-- src/app/features/call-status/MemberGlance.tsx | 4 +- .../features/call-status/MemberSpeaking.tsx | 2 +- src/app/features/call/CallControls.tsx | 6 +-- src/app/features/call/CallMemberCard.tsx | 5 ++- .../common-settings/cosmetics/Cosmetics.tsx | 14 +++---- .../developer-tools/DevelopTools.tsx | 4 +- .../developer-tools/SendRoomEvent.tsx | 4 +- .../developer-tools/StateEventEditor.tsx | 6 +-- .../emojis-stickers/EmojisStickers.tsx | 2 +- .../emojis-stickers/RoomPacks.tsx | 10 ++--- .../common-settings/general/RoomAddress.tsx | 6 +-- .../general/RoomEncryption.tsx | 4 +- .../general/RoomHistoryVisibility.tsx | 10 ++--- .../common-settings/general/RoomJoinRules.tsx | 8 ++-- .../common-settings/general/RoomProfile.tsx | 8 ++-- .../common-settings/general/RoomPublish.tsx | 6 +-- .../common-settings/general/RoomUpgrade.tsx | 6 +-- .../common-settings/members/Members.tsx | 14 ++++--- .../permissions/PermissionGroups.tsx | 6 +-- .../common-settings/permissions/Powers.tsx | 8 ++-- .../permissions/PowersEditor.tsx | 18 +++++--- .../common-settings/permissions/types.ts | 2 +- src/app/features/create-chat/CreateChat.tsx | 4 +- src/app/features/create-room/CreateRoom.tsx | 6 +-- .../features/create-room/CreateRoomModal.tsx | 2 +- src/app/features/create-space/CreateSpace.tsx | 6 +-- .../create-space/CreateSpaceModal.tsx | 2 +- src/app/features/lobby/DnD.tsx | 4 +- src/app/features/lobby/HierarchyItemMenu.tsx | 10 ++--- src/app/features/lobby/Lobby.tsx | 22 ++++++---- src/app/features/lobby/LobbyHeader.tsx | 6 +-- src/app/features/lobby/RoomItem.tsx | 6 +-- src/app/features/lobby/SpaceHierarchyItem.tsx | 14 +++---- .../features/lobby/SpaceHierarchyNavItem.tsx | 8 ++-- src/app/features/lobby/SpaceItem.tsx | 8 ++-- src/app/features/lobby/SpaceNavItem.tsx | 6 +-- .../features/message-search/MessageSearch.tsx | 6 +-- .../features/message-search/SearchFilters.tsx | 14 ++++--- .../features/message-search/SearchInput.tsx | 2 +- .../message-search/SearchResultGroup.tsx | 12 +++--- .../message-search/useMessageSearch.ts | 12 +++--- src/app/features/room-nav/RoomNavItem.tsx | 6 +-- src/app/features/room-nav/RoomNavUser.tsx | 4 +- .../features/room-settings/RoomSettings.tsx | 2 +- .../room-settings/RoomSettingsRenderer.tsx | 2 +- .../abbreviations/RoomAbbreviations.tsx | 6 +-- .../permissions/usePermissionItems.ts | 2 +- src/app/features/room/CommandAutocomplete.tsx | 12 +++--- src/app/features/room/MembersDrawer.tsx | 14 ++++--- src/app/features/room/RoomCallButton.tsx | 2 +- src/app/features/room/RoomInput.tsx | 41 +++++++++++-------- .../features/room/RoomInputPlaceholder.tsx | 2 +- src/app/features/room/RoomTimeline.css.ts | 2 +- src/app/features/room/RoomTimeline.tsx | 12 +++--- src/app/features/room/RoomViewFollowing.tsx | 2 +- src/app/features/room/RoomViewHeader.tsx | 8 ++-- src/app/features/room/RoomViewTyping.tsx | 2 +- src/app/features/room/ThreadBrowser.tsx | 12 +++--- src/app/features/room/ThreadDrawer.tsx | 16 ++++---- .../features/room/jump-to-time/JumpToTime.tsx | 6 +-- .../room/message/EncryptedContent.tsx | 4 +- src/app/features/room/message/Message.tsx | 26 ++++++------ .../features/room/message/MessageEditor.tsx | 26 ++++++------ src/app/features/room/message/Reactions.tsx | 5 +-- src/app/features/room/msgContent.ts | 6 +-- .../room/reaction-viewer/ReactionViewer.tsx | 2 +- .../room/room-pin-menu/RoomPinMenu.tsx | 21 ++++++---- .../schedule-send/SchedulePickerDialog.tsx | 4 +- .../schedule-send/ScheduledMessagesList.tsx | 2 +- src/app/features/search/Search.tsx | 14 ++++--- .../Persona/PerMessageProfileEditor.tsx | 4 +- .../Persona/PerMessageProfileOverview.tsx | 2 +- src/app/features/settings/Settings.tsx | 2 +- .../settings/account/AnimalCosmetics.tsx | 2 +- .../features/settings/account/BioEditor.tsx | 6 +-- .../settings/account/IgnoredUserList.tsx | 2 +- src/app/features/settings/account/Profile.tsx | 10 ++--- .../settings/account/PronounEditor.tsx | 4 +- .../settings/account/StatusEditor.tsx | 2 +- .../settings/account/TimezoneEditor.tsx | 2 +- .../features/settings/cosmetics/Cosmetics.tsx | 6 +-- .../features/settings/cosmetics/Themes.tsx | 11 +++-- .../developer-tools/DebugLogViewer.tsx | 17 ++++++-- .../settings/developer-tools/DevelopTools.tsx | 2 +- .../developer-tools/SentrySettings.tsx | 2 +- .../developer-tools/SyncDiagnostics.tsx | 2 +- .../features/settings/devices/DeviceTile.tsx | 4 +- .../features/settings/devices/LocalBackup.tsx | 2 +- .../settings/devices/OtherDevices.tsx | 4 +- .../settings/devices/Verification.tsx | 10 ++--- .../emojis-stickers/EmojisStickers.tsx | 2 +- .../settings/emojis-stickers/GlobalPacks.tsx | 12 +++--- src/app/features/settings/general/General.tsx | 16 ++++---- .../settings/notifications/AllMessages.tsx | 6 +-- .../notifications/KeywordMessages.tsx | 12 ++++-- .../notifications/NotificationLevelsHint.tsx | 15 ++++++- .../NotificationModeSwitcher.tsx | 6 +-- .../notifications/PushNotifications.tsx | 4 +- .../notifications/SpecialMessages.tsx | 6 +-- .../notifications/SystemNotification.tsx | 2 +- src/app/features/space-nav/SpaceNavItem.tsx | 6 +-- .../features/space-settings/SpaceSettings.tsx | 2 +- .../space-settings/SpaceSettingsRenderer.tsx | 2 +- .../permissions/usePermissionItems.ts | 2 +- .../features/widgets/GenericWidgetDriver.ts | 10 ++--- .../features/widgets/IntegrationManager.tsx | 2 +- src/app/features/widgets/WidgetIframe.tsx | 16 +++++--- src/app/features/widgets/WidgetsDrawer.tsx | 6 +-- .../hooks/timeline/useProcessedTimeline.ts | 2 +- src/app/hooks/timeline/useTimelineActions.ts | 12 ++++-- .../timeline/useTimelineEventRenderer.tsx | 28 ++++++------- .../hooks/timeline/useTimelineSync.test.tsx | 2 +- src/app/hooks/timeline/useTimelineSync.ts | 24 +++++++---- src/app/hooks/types.ts | 2 +- src/app/hooks/useAccountData.ts | 2 +- src/app/hooks/useAccountDataCallback.ts | 2 +- src/app/hooks/useAppVisibility.ts | 2 +- src/app/hooks/useAsyncCallback.ts | 9 +++- src/app/hooks/useAsyncSearch.ts | 12 +++--- src/app/hooks/useAuthFlows.ts | 2 +- src/app/hooks/useAuthMetadata.ts | 2 +- src/app/hooks/useAutoDiscoveryInfo.ts | 2 +- src/app/hooks/useCall.ts | 4 +- src/app/hooks/useCallEmbed.ts | 8 ++-- src/app/hooks/useCallSpeakers.ts | 2 +- src/app/hooks/useCapabilities.ts | 2 +- src/app/hooks/useCategoryHandler.ts | 2 +- src/app/hooks/useCommands.ts | 12 +++--- src/app/hooks/useCrossSigning.ts | 2 +- src/app/hooks/useDateFormat.ts | 2 +- src/app/hooks/useDeviceList.ts | 2 +- src/app/hooks/useDeviceVerificationStatus.ts | 2 +- src/app/hooks/useDirectUsers.ts | 2 +- src/app/hooks/useFileDrop.ts | 9 +++- src/app/hooks/useFilePasteHandler.ts | 2 +- src/app/hooks/useGetRoom.ts | 2 +- src/app/hooks/useGroupDMMembers.ts | 2 +- src/app/hooks/useImagePackRooms.ts | 2 +- src/app/hooks/useImagePacks.ts | 6 +-- src/app/hooks/useIntegrationManager.ts | 2 +- src/app/hooks/useKeyBackup.ts | 8 ++-- src/app/hooks/useLivekitSupport.ts | 2 +- src/app/hooks/useLocalRoomSummary.ts | 2 +- src/app/hooks/useMatrixClient.ts | 2 +- src/app/hooks/useMatrixEventRenderer.ts | 2 +- src/app/hooks/useMemberEventParser.tsx | 8 ++-- src/app/hooks/useMemberFilter.ts | 2 +- src/app/hooks/useMemberPowerCompare.ts | 2 +- src/app/hooks/useMemberPowerTag.ts | 10 ++--- src/app/hooks/useMemberSort.ts | 2 +- src/app/hooks/useMembership.ts | 2 +- src/app/hooks/useMentionClickHandler.ts | 4 +- src/app/hooks/useMessageSpacing.ts | 2 +- src/app/hooks/useMutualRooms.ts | 2 +- src/app/hooks/useNickname.ts | 2 +- src/app/hooks/useNotificationMode.ts | 2 +- src/app/hooks/useParsedLoginFlows.ts | 7 +++- src/app/hooks/usePasswordEmail.ts | 6 +-- src/app/hooks/usePerMessageProfile.ts | 4 +- src/app/hooks/usePowerLevelTags.ts | 6 +-- src/app/hooks/usePowerLevels.ts | 2 +- src/app/hooks/usePushRule.ts | 10 ++--- src/app/hooks/useRecentEmoji.ts | 4 +- src/app/hooks/useRegisterEmail.ts | 6 +-- src/app/hooks/useRoom.ts | 2 +- src/app/hooks/useRoomAbbreviations.ts | 4 +- src/app/hooks/useRoomAccountData.ts | 2 +- src/app/hooks/useRoomAliases.ts | 8 +++- src/app/hooks/useRoomCreators.ts | 4 +- src/app/hooks/useRoomCreatorsTag.ts | 2 +- src/app/hooks/useRoomEvent.ts | 6 +-- src/app/hooks/useRoomEventReaders.ts | 2 +- src/app/hooks/useRoomLatestRenderedEvent.ts | 7 +++- src/app/hooks/useRoomMembers.ts | 7 +++- src/app/hooks/useRoomMeta.ts | 7 +++- src/app/hooks/useRoomNavigate.ts | 2 +- src/app/hooks/useRoomPermissions.ts | 6 +-- src/app/hooks/useRoomPinnedEvents.ts | 2 +- src/app/hooks/useRoomState.ts | 6 +-- src/app/hooks/useRoomTypingMembers.ts | 4 +- src/app/hooks/useRoomWidgets.ts | 4 +- .../hooks/useRoomsNotificationPreferences.ts | 4 +- src/app/hooks/useSableCosmetics.ts | 2 +- src/app/hooks/useSecretStorage.ts | 4 +- src/app/hooks/useSessionProfiles.ts | 2 +- src/app/hooks/useSettingsSync.ts | 2 +- src/app/hooks/useSidebarItems.ts | 4 +- src/app/hooks/useSpace.ts | 2 +- src/app/hooks/useSpaceHierarchy.ts | 8 ++-- src/app/hooks/useSpecVersions.ts | 2 +- src/app/hooks/useSpoilerClickHandler.ts | 2 +- src/app/hooks/useStateEvent.ts | 4 +- src/app/hooks/useStateEventCallback.ts | 7 +++- src/app/hooks/useSyncState.ts | 2 +- src/app/hooks/useTextAreaCodeEditor.ts | 4 +- src/app/hooks/useTextAreaIntent.ts | 4 +- src/app/hooks/useTypingStatusUpdater.ts | 2 +- src/app/hooks/useUIAFlows.ts | 2 +- src/app/hooks/useUserPresence.ts | 2 +- src/app/hooks/useUserProfile.ts | 4 +- src/app/hooks/useVerificationRequest.ts | 12 +++--- src/app/i18n.ts | 2 +- src/app/pages/FeatureCheck.tsx | 2 +- src/app/pages/MobileFriendly.tsx | 2 +- src/app/pages/Router.tsx | 4 +- src/app/pages/ThemeManager.tsx | 2 +- src/app/pages/auth/SSOLogin.tsx | 2 +- src/app/pages/auth/ServerPicker.tsx | 10 ++--- src/app/pages/auth/login/Login.tsx | 2 +- .../pages/auth/login/PasswordLoginForm.tsx | 8 ++-- src/app/pages/auth/login/TokenLogin.tsx | 4 +- src/app/pages/auth/login/loginUtil.ts | 9 +++- .../auth/register/PasswordRegisterForm.tsx | 18 ++++---- src/app/pages/auth/register/Register.tsx | 2 +- src/app/pages/auth/register/registerUtil.ts | 10 ++--- .../auth/reset-password/PasswordResetForm.tsx | 8 ++-- .../auth/reset-password/ResetPassword.tsx | 2 +- .../auth/reset-password/resetPasswordUtil.ts | 7 +++- src/app/pages/client/AutoDiscovery.tsx | 4 +- .../pages/client/BackgroundNotifications.tsx | 8 ++-- src/app/pages/client/ClientBindAtoms.ts | 2 +- .../pages/client/ClientInitStorageAtom.tsx | 2 +- src/app/pages/client/ClientLayout.tsx | 2 +- src/app/pages/client/ClientNonUIFeatures.tsx | 4 +- .../ClientRoomsNotificationPreferences.tsx | 2 +- src/app/pages/client/ClientRoot.tsx | 13 ++++-- src/app/pages/client/SidebarNav.tsx | 2 +- src/app/pages/client/SpecVersions.tsx | 2 +- src/app/pages/client/SyncStatus.tsx | 2 +- src/app/pages/client/direct/Direct.tsx | 4 +- src/app/pages/client/direct/RoomProvider.tsx | 2 +- src/app/pages/client/explore/Explore.tsx | 2 +- src/app/pages/client/explore/Server.tsx | 12 +++--- src/app/pages/client/home/Home.tsx | 6 +-- src/app/pages/client/home/RoomProvider.tsx | 2 +- src/app/pages/client/inbox/Invites.tsx | 7 +++- src/app/pages/client/inbox/Notifications.tsx | 18 ++++---- .../client/sidebar/AccountSwitcherTab.tsx | 6 +-- src/app/pages/client/sidebar/CreateTab.tsx | 6 +-- .../pages/client/sidebar/DirectDMsList.tsx | 2 +- src/app/pages/client/sidebar/DirectTab.tsx | 15 ++++++- src/app/pages/client/sidebar/HomeTab.tsx | 15 ++++++- src/app/pages/client/sidebar/SpaceTabs.tsx | 18 ++++---- src/app/pages/client/space/RoomProvider.tsx | 2 +- src/app/pages/client/space/Space.tsx | 12 +++--- src/app/pages/client/space/SpaceProvider.tsx | 2 +- src/app/pages/pathSearchParam.ts | 2 +- src/app/pages/pathUtils.ts | 4 +- src/app/plugins/call/CallControl.ts | 8 +++- src/app/plugins/call/CallEmbed.ts | 16 ++++---- src/app/plugins/call/CallWidgetDriver.ts | 6 +-- src/app/plugins/call/hooks.ts | 10 ++--- src/app/plugins/custom-emoji/ImagePack.ts | 6 +-- .../plugins/custom-emoji/PackImageReader.ts | 4 +- .../plugins/custom-emoji/PackImagesReader.ts | 2 +- .../plugins/custom-emoji/PackMetaReader.ts | 2 +- .../plugins/custom-emoji/imagePackCache.ts | 2 +- src/app/plugins/custom-emoji/types.ts | 2 +- src/app/plugins/custom-emoji/utils.ts | 8 ++-- src/app/plugins/emoji.ts | 2 +- src/app/plugins/markdown/block/parser.ts | 2 +- src/app/plugins/markdown/block/rules.ts | 2 +- src/app/plugins/markdown/block/runner.ts | 2 +- src/app/plugins/markdown/block/type.ts | 2 +- src/app/plugins/markdown/inline/parser.ts | 2 +- src/app/plugins/markdown/inline/rules.ts | 2 +- src/app/plugins/markdown/inline/runner.ts | 4 +- src/app/plugins/markdown/inline/type.ts | 2 +- src/app/plugins/react-custom-html-parser.tsx | 16 ++++---- src/app/plugins/react-prism/ReactPrism.tsx | 2 +- src/app/plugins/recent-emoji.ts | 4 +- src/app/plugins/text-area/Operations.ts | 2 +- src/app/plugins/text-area/TextArea.ts | 2 +- .../plugins/text-area/TextAreaOperations.ts | 4 +- src/app/plugins/text-area/mods/Intent.ts | 4 +- src/app/plugins/utils.ts | 4 +- src/app/plugins/via-servers.ts | 6 +-- src/app/state/backupRestore.ts | 2 +- src/app/state/callEmbed.ts | 2 +- src/app/state/callPreferences.ts | 2 +- src/app/state/closedLobbyCategories.ts | 2 +- src/app/state/closedNavCategories.ts | 2 +- src/app/state/createRoomModal.ts | 2 +- src/app/state/hooks/callPreferences.ts | 2 +- src/app/state/hooks/closedLobbyCategories.ts | 2 +- src/app/state/hooks/closedNavCategories.ts | 2 +- src/app/state/hooks/createRoomModal.ts | 4 +- src/app/state/hooks/createSpaceModal.ts | 2 +- src/app/state/hooks/navToActivePath.ts | 2 +- src/app/state/hooks/openedSidebarFolder.ts | 2 +- src/app/state/hooks/roomList.ts | 6 +-- src/app/state/hooks/roomSettings.ts | 6 ++- src/app/state/hooks/settings.ts | 2 +- src/app/state/hooks/spaceSettings.ts | 6 ++- src/app/state/hooks/unread.ts | 4 +- src/app/state/hooks/useBindAtoms.ts | 2 +- src/app/state/hooks/userRoomProfile.ts | 6 +-- src/app/state/mDirectList.ts | 2 +- src/app/state/modal.ts | 2 +- src/app/state/navToActivePath.ts | 4 +- src/app/state/nicknames.ts | 2 +- src/app/state/openedSidebarFolder.ts | 2 +- src/app/state/room-list/inviteList.ts | 6 +-- src/app/state/room-list/roomList.ts | 4 +- src/app/state/room-list/utils.ts | 6 +-- src/app/state/room/roomInputDrafts.ts | 8 ++-- src/app/state/room/roomToParents.ts | 8 ++-- src/app/state/room/roomToUnread.ts | 18 ++++---- src/app/state/sessions.ts | 2 +- src/app/state/typingMembers.ts | 6 ++- src/app/state/upload.ts | 9 +++- src/app/state/userRoomProfile.ts | 2 +- src/app/styles/ContainerColor.css.ts | 6 +-- .../utils/addStickerToDefaultStickerPack.ts | 6 +-- src/app/utils/common.ts | 2 +- src/app/utils/delayedEvents.ts | 9 ++-- src/app/utils/keyboard.ts | 2 +- src/app/utils/matrix-crypto.ts | 2 +- src/app/utils/matrix-uia.ts | 2 +- src/app/utils/matrix.ts | 18 ++++---- src/app/utils/notifications.ts | 2 +- src/app/utils/room.ts | 30 +++++++------- src/app/utils/sanitize.ts | 2 +- src/app/utils/sendFeedbackToUser.ts | 2 +- src/app/utils/settingsSync.ts | 2 +- src/app/utils/sort.ts | 2 +- src/app/utils/timeline.ts | 2 +- src/client/initMatrix.ts | 16 +++++--- src/client/slidingSync.ts | 10 ++--- src/index.tsx | 2 +- src/types/matrix/common.ts | 4 +- src/types/matrix/room.ts | 2 +- tsconfig.json | 2 +- 501 files changed, 1492 insertions(+), 1215 deletions(-) diff --git a/src/app/components/AccountDataEditor.tsx b/src/app/components/AccountDataEditor.tsx index f8fd8445f..4639bcb73 100644 --- a/src/app/components/AccountDataEditor.tsx +++ b/src/app/components/AccountDataEditor.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { type FormEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Box, Text, @@ -14,7 +14,7 @@ import { Scroll, config, } from 'folds'; -import { MatrixError } from '$types/matrix-sdk'; +import { type MatrixError } from '$types/matrix-sdk'; import { Cursor } from '$plugins/text-area'; import { syntaxErrorPosition } from '$utils/dom'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; diff --git a/src/app/components/ActionUIA.tsx b/src/app/components/ActionUIA.tsx index caffb0329..16d30d73b 100644 --- a/src/app/components/ActionUIA.tsx +++ b/src/app/components/ActionUIA.tsx @@ -1,5 +1,5 @@ -import { ReactNode } from 'react'; -import { AuthDict, AuthType, IAuthData, UIAFlow } from '$types/matrix-sdk'; +import { type ReactNode } from 'react'; +import { type AuthDict, AuthType, type IAuthData, type UIAFlow } from '$types/matrix-sdk'; import { getUIAFlowForStages } from '$utils/matrix-uia'; import { useSupportedUIAFlows, useUIACompleted, useUIAFlow } from '$hooks/useUIAFlows'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/components/AuthFlowsLoader.tsx b/src/app/components/AuthFlowsLoader.tsx index 4ea21b92c..a4af0dd9b 100644 --- a/src/app/components/AuthFlowsLoader.tsx +++ b/src/app/components/AuthFlowsLoader.tsx @@ -1,12 +1,12 @@ -import { ReactNode, useCallback, useEffect, useMemo } from 'react'; -import { MatrixError, createClient } from '$types/matrix-sdk'; +import { type ReactNode, useCallback, useEffect, useMemo } from 'react'; +import { type MatrixError, createClient } from '$types/matrix-sdk'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useAutoDiscoveryInfo } from '$hooks/useAutoDiscoveryInfo'; import { promiseFulfilledResult, promiseRejectedResult } from '$utils/common'; import { - AuthFlows, + type AuthFlows, RegisterFlowStatus, - RegisterFlowsResponse, + type RegisterFlowsResponse, parseRegisterErrResp, } from '$hooks/useAuthFlows'; diff --git a/src/app/components/BackRouteHandler.tsx b/src/app/components/BackRouteHandler.tsx index a6e91bcd1..6ce06352f 100644 --- a/src/app/components/BackRouteHandler.tsx +++ b/src/app/components/BackRouteHandler.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useCallback } from 'react'; +import { type ReactNode, useCallback } from 'react'; import { useSetAtom } from 'jotai'; import { matchPath, useLocation, useNavigate } from 'react-router-dom'; import { diff --git a/src/app/components/BackupRestore.tsx b/src/app/components/BackupRestore.tsx index 78d65dff4..f19a8f298 100644 --- a/src/app/components/BackupRestore.tsx +++ b/src/app/components/BackupRestore.tsx @@ -1,6 +1,6 @@ -import { MouseEventHandler, useCallback, useState } from 'react'; +import { type MouseEventHandler, useCallback, useState } from 'react'; import { useAtom } from 'jotai'; -import { CryptoApi, KeyBackupInfo } from '$types/matrix-sdk'; +import { type CryptoApi, type KeyBackupInfo } from '$types/matrix-sdk'; import { Badge, Box, @@ -14,7 +14,7 @@ import { percent, PopOut, ProgressBar, - RectCords, + type RectCords, Spinner, Text, } from 'folds'; diff --git a/src/app/components/CallEmbedProvider.tsx b/src/app/components/CallEmbedProvider.tsx index fe2f84468..4e88b0217 100644 --- a/src/app/components/CallEmbedProvider.tsx +++ b/src/app/components/CallEmbedProvider.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useCallback, useRef } from 'react'; +import { type ReactNode, useCallback, useRef } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; import { useAutoJoinCall } from '$hooks/useAutoJoinCall'; import { @@ -9,7 +9,7 @@ import { useCallThemeSync, useCallMemberSoundSync, } from '$hooks/useCallEmbed'; -import { CallEmbed, useClientWidgetApiEvent, ElementWidgetActions } from '$plugins/call'; +import { type CallEmbed, useClientWidgetApiEvent, ElementWidgetActions } from '$plugins/call'; import { callChatAtom, callEmbedAtom } from '$state/callEmbed'; import { useSelectedRoom } from '$hooks/router/useSelectedRoom'; import { ScreenSize, useScreenSizeContext } from '$hooks/useScreenSize'; diff --git a/src/app/components/ClientConfigLoader.tsx b/src/app/components/ClientConfigLoader.tsx index 92af0c149..4c04f1560 100644 --- a/src/app/components/ClientConfigLoader.tsx +++ b/src/app/components/ClientConfigLoader.tsx @@ -1,6 +1,6 @@ -import { ReactNode, useCallback, useEffect, useState } from 'react'; +import { type ReactNode, useCallback, useEffect, useState } from 'react'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; -import { ClientConfig } from '$hooks/useClientConfig'; +import { type ClientConfig } from '$hooks/useClientConfig'; import { trimTrailingSlash } from '$utils/common'; const getClientConfig = async (): Promise => { diff --git a/src/app/components/ConfirmPasswordMatch.tsx b/src/app/components/ConfirmPasswordMatch.tsx index dea228924..a1ea3a5a6 100644 --- a/src/app/components/ConfirmPasswordMatch.tsx +++ b/src/app/components/ConfirmPasswordMatch.tsx @@ -1,4 +1,4 @@ -import { ReactNode, RefObject, useCallback, useRef, useState } from 'react'; +import { type ReactNode, type RefObject, useCallback, useRef, useState } from 'react'; import { useDebounce } from '$hooks/useDebounce'; type ConfirmPasswordMatchProps = { diff --git a/src/app/components/DeviceVerification.tsx b/src/app/components/DeviceVerification.tsx index fa29ae11e..4c718d66e 100644 --- a/src/app/components/DeviceVerification.tsx +++ b/src/app/components/DeviceVerification.tsx @@ -1,11 +1,11 @@ import { - ShowSasCallbacks, + type ShowSasCallbacks, VerificationPhase, - VerificationRequest, - Verifier, + type VerificationRequest, + type Verifier, VerificationMethod, } from '$types/matrix-sdk'; -import { CSSProperties, useCallback, useEffect, useState } from 'react'; +import { type CSSProperties, useCallback, useEffect, useState } from 'react'; import { Box, Button, diff --git a/src/app/components/DeviceVerificationSetup.tsx b/src/app/components/DeviceVerificationSetup.tsx index 78fe8ded2..c020eea50 100644 --- a/src/app/components/DeviceVerificationSetup.tsx +++ b/src/app/components/DeviceVerificationSetup.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, forwardRef, useCallback, useState } from 'react'; +import { type FormEventHandler, forwardRef, useCallback, useState } from 'react'; import { Dialog, Header, @@ -15,7 +15,7 @@ import { } from 'folds'; import FileSaver from 'file-saver'; import to from 'await-to-js'; -import { AuthDict, IAuthData, MatrixError, UIAuthCallback } from '$types/matrix-sdk'; +import { type AuthDict, type IAuthData, MatrixError, type UIAuthCallback } from '$types/matrix-sdk'; import { clearSecretStorageKeys } from '$client/secretStorageKeys'; import { ContainerColor } from '$styles/ContainerColor.css'; import { copyToClipboard } from '$utils/dom'; diff --git a/src/app/components/DeviceVerificationStatus.ts b/src/app/components/DeviceVerificationStatus.ts index f69c64ac9..6a5868125 100644 --- a/src/app/components/DeviceVerificationStatus.ts +++ b/src/app/components/DeviceVerificationStatus.ts @@ -1,8 +1,8 @@ -import { ReactNode } from 'react'; -import { CryptoApi } from '$types/matrix-sdk'; +import { type ReactNode } from 'react'; +import { type CryptoApi } from '$types/matrix-sdk'; import { useDeviceVerificationStatus, - VerificationStatus, + type VerificationStatus, } from '$hooks/useDeviceVerificationStatus'; type DeviceVerificationStatusProps = { diff --git a/src/app/components/GlobalKeyboardShortcuts.tsx b/src/app/components/GlobalKeyboardShortcuts.tsx index 0571e54a4..44daf7fd6 100644 --- a/src/app/components/GlobalKeyboardShortcuts.tsx +++ b/src/app/components/GlobalKeyboardShortcuts.tsx @@ -21,7 +21,7 @@ import { HOME_ROOM_PATH, DIRECT_ROOM_PATH, SPACE_ROOM_PATH } from '$pages/paths' import { getCanonicalAliasOrRoomId } from '$utils/matrix'; import { announce } from '$utils/announce'; import { roomIdToReplyDraftAtomFamily } from '$state/room/roomInputDrafts'; -import { Room } from 'matrix-js-sdk'; +import { type Room } from 'matrix-js-sdk'; export function GlobalKeyboardShortcuts() { const navigate = useNavigate(); diff --git a/src/app/components/HexColorPickerPopOut.tsx b/src/app/components/HexColorPickerPopOut.tsx index 25c5d661b..c111d90dd 100644 --- a/src/app/components/HexColorPickerPopOut.tsx +++ b/src/app/components/HexColorPickerPopOut.tsx @@ -1,6 +1,6 @@ import FocusTrap from 'focus-trap-react'; -import { Box, Button, config, Menu, PopOut, RectCords, Text } from 'folds'; -import { MouseEventHandler, ReactNode, useState } from 'react'; +import { Box, Button, config, Menu, PopOut, type RectCords, Text } from 'folds'; +import { type MouseEventHandler, type ReactNode, useState } from 'react'; import { stopPropagation } from '$utils/keyboard'; type HexColorPickerPopOutProps = { diff --git a/src/app/components/JoinRulesSwitcher.tsx b/src/app/components/JoinRulesSwitcher.tsx index 5b33b397d..e1c1eb05f 100644 --- a/src/app/components/JoinRulesSwitcher.tsx +++ b/src/app/components/JoinRulesSwitcher.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useMemo, useState } from 'react'; +import { type MouseEventHandler, useCallback, useMemo, useState } from 'react'; import { config, Box, @@ -6,8 +6,8 @@ import { Text, Icon, Icons, - IconSrc, - RectCords, + type IconSrc, + type RectCords, PopOut, Menu, Button, diff --git a/src/app/components/ManualVerification.tsx b/src/app/components/ManualVerification.tsx index 31903f957..cd087a3f6 100644 --- a/src/app/components/ManualVerification.tsx +++ b/src/app/components/ManualVerification.tsx @@ -1,11 +1,11 @@ -import { MouseEventHandler, ReactNode, useCallback, useState } from 'react'; +import { type MouseEventHandler, type ReactNode, useCallback, useState } from 'react'; import { Box, Text, Chip, Icon, Icons, - RectCords, + type RectCords, PopOut, Menu, config, @@ -13,7 +13,7 @@ import { color, } from 'folds'; import FocusTrap from 'focus-trap-react'; -import { SecretStorageKeyContent } from '$types/matrix/accountData'; +import { type SecretStorageKeyContent } from '$types/matrix/accountData'; import { storePrivateKey } from '$client/secretStorageKeys'; import { stopPropagation } from '$utils/keyboard'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/components/Modal500.tsx b/src/app/components/Modal500.tsx index 260baa6d8..32dcc2c3a 100644 --- a/src/app/components/Modal500.tsx +++ b/src/app/components/Modal500.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import FocusTrap from 'focus-trap-react'; import { Modal, Overlay, OverlayBackdrop, OverlayCenter } from 'folds'; import { stopPropagation } from '$utils/keyboard'; diff --git a/src/app/components/Pdf-viewer/PdfViewer.tsx b/src/app/components/Pdf-viewer/PdfViewer.tsx index 71ab77efb..1667319a9 100644 --- a/src/app/components/Pdf-viewer/PdfViewer.tsx +++ b/src/app/components/Pdf-viewer/PdfViewer.tsx @@ -1,6 +1,6 @@ /* eslint-disable no-param-reassign */ -import { FormEventHandler, MouseEventHandler, useEffect, useRef, useState } from 'react'; +import { type FormEventHandler, type MouseEventHandler, useEffect, useRef, useState } from 'react'; import classNames from 'classnames'; import { Box, @@ -13,7 +13,7 @@ import { Input, Menu, PopOut, - RectCords, + type RectCords, Scroll, Spinner, Text, diff --git a/src/app/components/RenderMessageContent.tsx b/src/app/components/RenderMessageContent.tsx index 6f3617858..5cbbed6fc 100644 --- a/src/app/components/RenderMessageContent.tsx +++ b/src/app/components/RenderMessageContent.tsx @@ -3,8 +3,8 @@ import { MsgType } from '$types/matrix-sdk'; import { testMatrixTo } from '$plugins/matrix-to'; import { useSetting } from '$state/hooks/settings'; import { settingsAtom, CaptionPosition } from '$state/settings'; -import { HTMLReactParserOptions } from 'html-react-parser'; -import { Opts } from 'linkifyjs'; +import { type HTMLReactParserOptions } from 'html-react-parser'; +import { type Opts } from 'linkifyjs'; import { Box, config } from 'folds'; import { AudioContent, diff --git a/src/app/components/RoomNotificationSwitcher.tsx b/src/app/components/RoomNotificationSwitcher.tsx index 0b5c9e383..708373c52 100644 --- a/src/app/components/RoomNotificationSwitcher.tsx +++ b/src/app/components/RoomNotificationSwitcher.tsx @@ -1,5 +1,5 @@ -import { Box, config, Icon, Menu, MenuItem, PopOut, RectCords, Text, toRem } from 'folds'; -import { MouseEventHandler, ReactNode, useMemo, useState } from 'react'; +import { Box, config, Icon, Menu, MenuItem, PopOut, type RectCords, Text, toRem } from 'folds'; +import { type MouseEventHandler, type ReactNode, useMemo, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { stopPropagation } from '$utils/keyboard'; import { diff --git a/src/app/components/RoomSummaryLoader.tsx b/src/app/components/RoomSummaryLoader.tsx index 93baa5721..0a8fb135e 100644 --- a/src/app/components/RoomSummaryLoader.tsx +++ b/src/app/components/RoomSummaryLoader.tsx @@ -1,9 +1,9 @@ -import { ReactNode, useCallback, useState } from 'react'; -import { MatrixClient, Room, IHierarchyRoom } from '$types/matrix-sdk'; +import { type ReactNode, useCallback, useState } from 'react'; +import { type MatrixClient, type Room, type IHierarchyRoom } from '$types/matrix-sdk'; import { useQuery } from '@tanstack/react-query'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { LocalRoomSummary, useLocalRoomSummary } from '$hooks/useLocalRoomSummary'; -import { AsyncState, AsyncStatus } from '$hooks/useAsyncCallback'; +import { type LocalRoomSummary, useLocalRoomSummary } from '$hooks/useLocalRoomSummary'; +import { type AsyncState, AsyncStatus } from '$hooks/useAsyncCallback'; export type IRoomSummary = Awaited>; diff --git a/src/app/components/RoomUnreadProvider.tsx b/src/app/components/RoomUnreadProvider.tsx index 5a1fc13a6..cfa4d8f66 100644 --- a/src/app/components/RoomUnreadProvider.tsx +++ b/src/app/components/RoomUnreadProvider.tsx @@ -1,5 +1,5 @@ -import { ReactElement } from 'react'; -import { Unread } from '$types/matrix/room'; +import { type ReactElement } from 'react'; +import { type Unread } from '$types/matrix/room'; import { useRoomUnread, useRoomsUnread } from '$state/hooks/unread'; import { roomToUnreadAtom } from '$state/room/roomToUnread'; diff --git a/src/app/components/SecretStorage.tsx b/src/app/components/SecretStorage.tsx index 07b2e15d5..3f8849247 100644 --- a/src/app/components/SecretStorage.tsx +++ b/src/app/components/SecretStorage.tsx @@ -1,7 +1,10 @@ -import { FormEventHandler, useCallback } from 'react'; +import { type FormEventHandler, useCallback } from 'react'; import { Box, Text, Button, Spinner, color } from 'folds'; import { decodeRecoveryKey, deriveRecoveryKeyFromPassphrase } from '$types/matrix-sdk'; -import { SecretStorageKeyContent, SecretStoragePassphraseContent } from '$types/matrix/accountData'; +import { + type SecretStorageKeyContent, + type SecretStoragePassphraseContent, +} from '$types/matrix/accountData'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useAlive } from '$hooks/useAlive'; diff --git a/src/app/components/ServerConfigsLoader.tsx b/src/app/components/ServerConfigsLoader.tsx index 3f7b395e5..7c212d1fd 100644 --- a/src/app/components/ServerConfigsLoader.tsx +++ b/src/app/components/ServerConfigsLoader.tsx @@ -1,8 +1,12 @@ -import { ReactNode, useCallback, useMemo } from 'react'; -import { Capabilities, validateAuthMetadata, ValidatedAuthMetadata } from '$types/matrix-sdk'; +import { type ReactNode, useCallback, useMemo } from 'react'; +import { + type Capabilities, + validateAuthMetadata, + type ValidatedAuthMetadata, +} from '$types/matrix-sdk'; import { AsyncStatus, useAsyncCallbackValue } from '$hooks/useAsyncCallback'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { MediaConfig } from '$hooks/useMediaConfig'; +import { type MediaConfig } from '$hooks/useMediaConfig'; import { promiseFulfilledResult } from '$utils/common'; import { createLogger } from '$utils/debug'; diff --git a/src/app/components/SpecVersionsLoader.tsx b/src/app/components/SpecVersionsLoader.tsx index 2bbbff272..2ac87f5d3 100644 --- a/src/app/components/SpecVersionsLoader.tsx +++ b/src/app/components/SpecVersionsLoader.tsx @@ -1,6 +1,6 @@ -import { ReactNode, useCallback, useEffect, useState } from 'react'; +import { type ReactNode, useCallback, useEffect, useState } from 'react'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; -import { SpecVersions, specVersions } from '../cs-api'; +import { type SpecVersions, specVersions } from '../cs-api'; type SpecVersionsLoaderProps = { baseUrl: string; diff --git a/src/app/components/SupportedUIAFlowsLoader.tsx b/src/app/components/SupportedUIAFlowsLoader.tsx index cd3f81499..4c839600f 100644 --- a/src/app/components/SupportedUIAFlowsLoader.tsx +++ b/src/app/components/SupportedUIAFlowsLoader.tsx @@ -1,5 +1,5 @@ -import { ReactNode } from 'react'; -import { UIAFlow } from '$types/matrix-sdk'; +import { type ReactNode } from 'react'; +import { type UIAFlow } from '$types/matrix-sdk'; import { useSupportedUIAFlows } from '$hooks/useUIAFlows'; export function SupportedUIAFlowsLoader({ diff --git a/src/app/components/SwipeableChatWrapper.tsx b/src/app/components/SwipeableChatWrapper.tsx index 2eba0d011..050fa440c 100644 --- a/src/app/components/SwipeableChatWrapper.tsx +++ b/src/app/components/SwipeableChatWrapper.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { motion, useMotionValue, useSpring } from 'framer-motion'; import { useDrag } from '@use-gesture/react'; import { useAtomValue } from 'jotai'; diff --git a/src/app/components/SwipeableMessageWrapper.tsx b/src/app/components/SwipeableMessageWrapper.tsx index 4b219355c..e697fc24b 100644 --- a/src/app/components/SwipeableMessageWrapper.tsx +++ b/src/app/components/SwipeableMessageWrapper.tsx @@ -1,6 +1,6 @@ import { useMotionValue, useSpring, useTransform, motion } from 'framer-motion'; import { useDrag } from '@use-gesture/react'; -import { ReactNode, useMemo, useState } from 'react'; +import { type ReactNode, useMemo, useState } from 'react'; import { useAtomValue } from 'jotai'; import { config, Icon, Icons } from 'folds'; import { mobileOrTablet } from '$utils/user-agent'; diff --git a/src/app/components/SwipeableOverlayWrapper.tsx b/src/app/components/SwipeableOverlayWrapper.tsx index 15521bb12..0c06de91c 100644 --- a/src/app/components/SwipeableOverlayWrapper.tsx +++ b/src/app/components/SwipeableOverlayWrapper.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { motion, useMotionValue, useSpring } from 'framer-motion'; import { useDrag } from '@use-gesture/react'; import { useAtomValue } from 'jotai'; diff --git a/src/app/components/UIAFlowOverlay.tsx b/src/app/components/UIAFlowOverlay.tsx index 85211a0f0..57ea24be9 100644 --- a/src/app/components/UIAFlowOverlay.tsx +++ b/src/app/components/UIAFlowOverlay.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { Overlay, OverlayBackdrop, diff --git a/src/app/components/UseStateProvider.tsx b/src/app/components/UseStateProvider.tsx index 21e5b3cad..cb62b7903 100644 --- a/src/app/components/UseStateProvider.tsx +++ b/src/app/components/UseStateProvider.tsx @@ -1,4 +1,4 @@ -import { Dispatch, ReactElement, SetStateAction, useState } from 'react'; +import { type Dispatch, type ReactElement, type SetStateAction, useState } from 'react'; type UseStateProviderProps = { initial: T | (() => T); diff --git a/src/app/components/UserRoomProfileRenderer.tsx b/src/app/components/UserRoomProfileRenderer.tsx index 97489d277..f2e0780ae 100644 --- a/src/app/components/UserRoomProfileRenderer.tsx +++ b/src/app/components/UserRoomProfileRenderer.tsx @@ -1,7 +1,7 @@ import { Menu, PopOut, toRem } from 'folds'; import FocusTrap from 'focus-trap-react'; import { useCloseUserRoomProfile, useUserRoomProfileState } from '$state/hooks/userRoomProfile'; -import { UserRoomProfileState } from '$state/userRoomProfile'; +import { type UserRoomProfileState } from '$state/userRoomProfile'; import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom'; import { stopPropagation } from '$utils/keyboard'; import { SpaceProvider } from '$hooks/useSpace'; diff --git a/src/app/components/create-room/AdditionalCreatorInput.tsx b/src/app/components/create-room/AdditionalCreatorInput.tsx index f362122a0..4ef005125 100644 --- a/src/app/components/create-room/AdditionalCreatorInput.tsx +++ b/src/app/components/create-room/AdditionalCreatorInput.tsx @@ -10,7 +10,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Scroll, Text, toRem, @@ -18,9 +18,9 @@ import { import { isKeyHotkey } from 'is-hotkey'; import FocusTrap from 'focus-trap-react'; import { - ChangeEventHandler, - KeyboardEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type KeyboardEventHandler, + type MouseEventHandler, useMemo, useState, } from 'react'; @@ -28,7 +28,7 @@ import { getMxIdLocalPart, getMxIdServer, isUserId } from '$utils/matrix'; import { useDirectUsers } from '$hooks/useDirectUsers'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { stopPropagation } from '$utils/keyboard'; -import { useAsyncSearch, UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; +import { useAsyncSearch, type UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; import { highlightText, makeHighlightRegex } from '$plugins/react-custom-html-parser'; import { SettingTile } from '$components/setting-tile'; diff --git a/src/app/components/create-room/CreateRoomAccessSelector.tsx b/src/app/components/create-room/CreateRoomAccessSelector.tsx index 6dd049835..f20c03955 100644 --- a/src/app/components/create-room/CreateRoomAccessSelector.tsx +++ b/src/app/components/create-room/CreateRoomAccessSelector.tsx @@ -1,4 +1,4 @@ -import { Box, Text, Icon, Icons, config, IconSrc } from 'folds'; +import { Box, Text, Icon, Icons, config, type IconSrc } from 'folds'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; import { CreateRoomAccess } from './types'; diff --git a/src/app/components/create-room/CreateRoomAliasInput.tsx b/src/app/components/create-room/CreateRoomAliasInput.tsx index 0460717a5..570edb0bb 100644 --- a/src/app/components/create-room/CreateRoomAliasInput.tsx +++ b/src/app/components/create-room/CreateRoomAliasInput.tsx @@ -1,6 +1,6 @@ import { - FormEventHandler, - KeyboardEventHandler, + type FormEventHandler, + type KeyboardEventHandler, useCallback, useEffect, useRef, @@ -12,7 +12,7 @@ import { isKeyHotkey } from 'is-hotkey'; import { getMxIdServer } from '$utils/matrix'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { replaceSpaceWithDash } from '$utils/common'; -import { AsyncState, AsyncStatus, useAsync } from '$hooks/useAsyncCallback'; +import { type AsyncState, AsyncStatus, useAsync } from '$hooks/useAsyncCallback'; import { useDebounce } from '$hooks/useDebounce'; export function CreateRoomAliasInput({ disabled }: { disabled?: boolean }) { diff --git a/src/app/components/create-room/CreateRoomTypeSelector.tsx b/src/app/components/create-room/CreateRoomTypeSelector.tsx index 42468a03d..c47bb4f0c 100644 --- a/src/app/components/create-room/CreateRoomTypeSelector.tsx +++ b/src/app/components/create-room/CreateRoomTypeSelector.tsx @@ -1,4 +1,4 @@ -import { Box, Text, Icon, Icons, config, IconSrc } from 'folds'; +import { Box, Text, Icon, Icons, config, type IconSrc } from 'folds'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; import { BetaNoticeBadge } from '$components/BetaNoticeBadge'; diff --git a/src/app/components/create-room/RoomVersionSelector.tsx b/src/app/components/create-room/RoomVersionSelector.tsx index a86b1d2df..c3d7fe3af 100644 --- a/src/app/components/create-room/RoomVersionSelector.tsx +++ b/src/app/components/create-room/RoomVersionSelector.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useState } from 'react'; +import { type MouseEventHandler, useState } from 'react'; import { Box, Button, @@ -8,7 +8,7 @@ import { Icons, Menu, PopOut, - RectCords, + type RectCords, Text, toRem, } from 'folds'; diff --git a/src/app/components/create-room/utils.ts b/src/app/components/create-room/utils.ts index d03226823..2a47a1b13 100644 --- a/src/app/components/create-room/utils.ts +++ b/src/app/components/create-room/utils.ts @@ -1,11 +1,11 @@ import { - ICreateRoomOpts, - ICreateRoomStateEvent, + type ICreateRoomOpts, + type ICreateRoomStateEvent, JoinRule, - MatrixClient, + type MatrixClient, RestrictedAllowType, - Room, - RoomJoinRulesEventContent, + type Room, + type RoomJoinRulesEventContent, } from '$types/matrix-sdk'; import { RoomType, StateEvent } from '$types/matrix/room'; import { getViaServers } from '$plugins/via-servers'; diff --git a/src/app/components/cutout-card/CutoutCard.tsx b/src/app/components/cutout-card/CutoutCard.tsx index 5a6c2ae3d..24860264f 100644 --- a/src/app/components/cutout-card/CutoutCard.tsx +++ b/src/app/components/cutout-card/CutoutCard.tsx @@ -1,4 +1,4 @@ -import { as, ContainerColor as TContainerColor } from 'folds'; +import { as, type ContainerColor as TContainerColor } from 'folds'; import classNames from 'classnames'; import { ContainerColor } from '$styles/ContainerColor.css'; import * as css from './CutoutCard.css'; diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index 7595fd46d..2b6c902b6 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -1,8 +1,8 @@ /* eslint-disable no-param-reassign */ import { - ClipboardEventHandler, - KeyboardEventHandler, - ReactNode, + type ClipboardEventHandler, + type KeyboardEventHandler, + type ReactNode, forwardRef, useCallback, useEffect, @@ -11,21 +11,21 @@ import { useState, } from 'react'; import { Box, Scroll, Text } from 'folds'; -import { Descendant, Editor, Node, createEditor } from 'slate'; +import { type Descendant, type Editor, Node, createEditor } from 'slate'; import { Slate, Editable, withReact, - RenderLeafProps, - RenderElementProps, - RenderPlaceholderProps, + type RenderLeafProps, + type RenderElementProps, + type RenderPlaceholderProps, ReactEditor, } from 'slate-react'; import { withHistory } from 'slate-history'; import { mobileOrTablet } from '$utils/user-agent'; import { BlockType } from './types'; import { RenderElement, RenderLeaf } from './Elements'; -import { CustomElement } from './slate'; +import { type CustomElement } from './slate'; import * as css from './Editor.css'; import { toggleKeyboardShortcut } from './keyboard'; diff --git a/src/app/components/editor/Elements.tsx b/src/app/components/editor/Elements.tsx index 7e3500810..bdf361788 100644 --- a/src/app/components/editor/Elements.tsx +++ b/src/app/components/editor/Elements.tsx @@ -1,7 +1,7 @@ import { Scroll, Text } from 'folds'; import { - RenderElementProps, - RenderLeafProps, + type RenderElementProps, + type RenderLeafProps, useFocused, useSelected, useSlate, @@ -15,7 +15,12 @@ import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { nicknamesAtom } from '$state/nicknames'; import { BlockType } from './types'; import { getBeginCommand } from './utils'; -import { CommandElement, EmoticonElement, LinkElement, MentionElement } from './slate'; +import { + type CommandElement, + type EmoticonElement, + type LinkElement, + type MentionElement, +} from './slate'; // Put this at the start and end of an inline component to work around this Chromium bug: // https://bugs.chromium.org/p/chromium/issues/detail?id=1249405 diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx index 62cd9356a..10c7c21d9 100644 --- a/src/app/components/editor/Toolbar.tsx +++ b/src/app/components/editor/Toolbar.tsx @@ -6,18 +6,18 @@ import { Icon, IconButton, Icons, - IconSrc, + type IconSrc, Line, Menu, PopOut, - RectCords, + type RectCords, Scroll, Text, Tooltip, TooltipProvider, toRem, } from 'folds'; -import { MouseEventHandler, ReactNode, useState } from 'react'; +import { type MouseEventHandler, type ReactNode, useState } from 'react'; import { ReactEditor, useSlate } from 'slate-react'; import { isMacOS } from '$utils/user-agent'; import { KeySymbol } from '$utils/key-symbol'; @@ -25,7 +25,7 @@ import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { stopPropagation } from '$utils/keyboard'; import { floatingToolbar } from '$styles/overrides/Composer.css'; -import { HeadingLevel } from './slate'; +import { type HeadingLevel } from './slate'; import { BlockType, MarkType } from './types'; import * as css from './Editor.css'; import { diff --git a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx index fdb4b570d..63091cb29 100644 --- a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx +++ b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx @@ -1,11 +1,11 @@ -import { ReactNode, useEffect, useRef, useState } from 'react'; +import { type ReactNode, useEffect, useRef, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { isKeyHotkey } from 'is-hotkey'; import { Header, Menu, Scroll, config } from 'folds'; import { preventScrollWithArrowKey, stopPropagation } from '$utils/keyboard'; import { useAlive } from '$hooks/useAlive'; -import { Editor } from 'slate'; +import { type Editor } from 'slate'; import { ReactEditor } from 'slate-react'; import * as css from './AutocompleteMenu.css'; import { BaseAutocompleteMenu } from './BaseAutocompleteMenu'; diff --git a/src/app/components/editor/autocomplete/AutocompleteNotice.tsx b/src/app/components/editor/autocomplete/AutocompleteNotice.tsx index a9b21e8cf..859d8048f 100644 --- a/src/app/components/editor/autocomplete/AutocompleteNotice.tsx +++ b/src/app/components/editor/autocomplete/AutocompleteNotice.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { Header, Menu } from 'folds'; import { BaseAutocompleteMenu } from './BaseAutocompleteMenu'; import * as css from './AutocompleteMenu.css'; diff --git a/src/app/components/editor/autocomplete/BaseAutocompleteMenu.tsx b/src/app/components/editor/autocomplete/BaseAutocompleteMenu.tsx index 9f1bf316f..9d6de8d03 100644 --- a/src/app/components/editor/autocomplete/BaseAutocompleteMenu.tsx +++ b/src/app/components/editor/autocomplete/BaseAutocompleteMenu.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import * as css from './AutocompleteMenu.css'; type BaseAutocompleteMenuProps = { diff --git a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx index b4c8e8f46..e6317e040 100644 --- a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx @@ -1,25 +1,25 @@ -import { KeyboardEvent as ReactKeyboardEvent, useEffect, useMemo } from 'react'; -import { Editor } from 'slate'; +import { type KeyboardEvent as ReactKeyboardEvent, useEffect, useMemo } from 'react'; +import { type Editor } from 'slate'; import { ReactEditor } from 'slate-react'; import { Box, MenuItem, Text, toRem } from 'folds'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; +import { type UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; import { onTabPress } from '$utils/keyboard'; import { useRecentEmoji } from '$hooks/useRecentEmoji'; import { useRelevantImagePacks } from '$hooks/useImagePacks'; -import { IEmoji, emojis } from '$plugins/emoji'; +import { type IEmoji, emojis } from '$plugins/emoji'; import { useKeyDown } from '$hooks/useKeyDown'; import { mxcUrlToHttp } from '$utils/matrix'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; -import { ImageUsage, PackImageReader } from '$plugins/custom-emoji'; +import { ImageUsage, type PackImageReader } from '$plugins/custom-emoji'; import { getEmoticonSearchStr } from '$plugins/utils'; import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { createEmoticonElement, moveCursor, replaceWithElement } from '$components/editor/utils'; import { AutocompleteMenu } from './AutocompleteMenu'; -import { AutocompleteQuery } from './autocompleteQuery'; +import { type AutocompleteQuery } from './autocompleteQuery'; type EmoticonCompleteHandler = (key: string, shortcode: string) => void; diff --git a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx index 9ad67aad4..d7799d0b9 100644 --- a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx @@ -1,14 +1,14 @@ -import { KeyboardEvent as ReactKeyboardEvent, useCallback, useEffect } from 'react'; -import { Editor } from 'slate'; +import { type KeyboardEvent as ReactKeyboardEvent, useCallback, useEffect } from 'react'; +import { type Editor } from 'slate'; import { ReactEditor } from 'slate-react'; import { Avatar, Icon, Icons, MenuItem, Text } from 'folds'; -import { JoinRule, MatrixClient } from '$types/matrix-sdk'; +import { JoinRule, type MatrixClient } from '$types/matrix-sdk'; import { useAtomValue } from 'jotai'; import { getDirectRoomAvatarUrl } from '$utils/room'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { getMxIdServer, isRoomAlias } from '$utils/matrix'; -import { UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; +import { type UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; import { onTabPress } from '$utils/keyboard'; import { useKeyDown } from '$hooks/useKeyDown'; import { mDirectAtom } from '$state/mDirectList'; @@ -18,7 +18,7 @@ import { RoomAvatar, RoomIcon } from '$components/room-avatar'; import { getViaServers } from '$plugins/via-servers'; import { createMentionElement, moveCursor, replaceWithElement } from '$components/editor/utils'; import { AutocompleteMenu } from './AutocompleteMenu'; -import { AutocompleteQuery } from './autocompleteQuery'; +import { type AutocompleteQuery } from './autocompleteQuery'; type MentionAutoCompleteHandler = (roomAliasOrId: string, name: string) => void; diff --git a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx index e38838070..afd1c909d 100644 --- a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx @@ -1,12 +1,16 @@ -import { useEffect, KeyboardEvent as ReactKeyboardEvent } from 'react'; -import { Editor } from 'slate'; +import { useEffect, type KeyboardEvent as ReactKeyboardEvent } from 'react'; +import { type Editor } from 'slate'; import { ReactEditor } from 'slate-react'; import { Avatar, Icon, Icons, MenuItem, Text } from 'folds'; -import { MatrixClient, Room, RoomMember } from '$types/matrix-sdk'; +import { type MatrixClient, type Room, type RoomMember } from '$types/matrix-sdk'; import { useRoomMembers } from '$hooks/useRoomMembers'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { SearchItemStrGetter, UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; +import { + type SearchItemStrGetter, + type UseAsyncSearchOptions, + useAsyncSearch, +} from '$hooks/useAsyncSearch'; import { onTabPress } from '$utils/keyboard'; import { useKeyDown } from '$hooks/useKeyDown'; import { getMxIdLocalPart, getMxIdServer, isUserId } from '$utils/matrix'; @@ -18,7 +22,7 @@ import { useAtomValue } from 'jotai'; import { nicknamesAtom } from '$state/nicknames'; import { createMentionElement, moveCursor, replaceWithElement } from '$components/editor/utils'; import { AutocompleteMenu } from './AutocompleteMenu'; -import { AutocompleteQuery } from './autocompleteQuery'; +import { type AutocompleteQuery } from './autocompleteQuery'; type MentionAutoCompleteHandler = (userId: string, name: string) => void; diff --git a/src/app/components/editor/autocomplete/autocompleteQuery.ts b/src/app/components/editor/autocomplete/autocompleteQuery.ts index 5b8294afb..b1c86df9c 100644 --- a/src/app/components/editor/autocomplete/autocompleteQuery.ts +++ b/src/app/components/editor/autocomplete/autocompleteQuery.ts @@ -1,4 +1,4 @@ -import { BaseRange, Editor } from 'slate'; +import { type BaseRange, Editor } from 'slate'; export enum AutocompletePrefix { RoomMention = '#', diff --git a/src/app/components/editor/input.ts b/src/app/components/editor/input.ts index 27a6b68fc..8a919ab84 100644 --- a/src/app/components/editor/input.ts +++ b/src/app/components/editor/input.ts @@ -1,6 +1,6 @@ -import { Descendant, Text } from 'slate'; +import { type Descendant, Text } from 'slate'; import parse from 'html-dom-parser'; -import { ChildNode, Element, isText, isTag } from 'domhandler'; +import { type ChildNode, type Element, isText, isTag } from 'domhandler'; import { sanitizeCustomHtml } from '$utils/sanitize'; import { @@ -12,19 +12,19 @@ import { import { escapeMarkdownInlineSequences, escapeMarkdownBlockSequences } from '$plugins/markdown'; import { BlockType, MarkType } from './types'; import { - BlockQuoteElement, - CodeBlockElement, - CodeLineElement, - EmoticonElement, - HeadingElement, - HeadingLevel, - HorizontalRuleElement, - InlineElement, - MentionElement, - OrderedListElement, - ParagraphElement, - SmallElement, - UnorderedListElement, + type BlockQuoteElement, + type CodeBlockElement, + type CodeLineElement, + type EmoticonElement, + type HeadingElement, + type HeadingLevel, + type HorizontalRuleElement, + type InlineElement, + type MentionElement, + type OrderedListElement, + type ParagraphElement, + type SmallElement, + type UnorderedListElement, } from './slate'; import { createEmoticonElement, createMentionElement } from './utils'; diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index a920a9050..ff9c796ed 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -1,5 +1,5 @@ import { isKeyHotkey } from 'is-hotkey'; -import { KeyboardEvent } from 'react'; +import { type KeyboardEvent } from 'react'; import { Editor, Element as SlateElement, Range, Transforms } from 'slate'; import { isAnyMarkActive, isBlockActive, removeAllMark, toggleBlock, toggleMark } from './utils'; import { BlockType, MarkType } from './types'; diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 15ca5ea34..2e21b4b61 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -1,5 +1,5 @@ -import { Descendant, Editor, Text } from 'slate'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type Descendant, type Editor, Text } from 'slate'; +import { type MatrixClient } from '$types/matrix-sdk'; import { sanitizeText } from '$utils/sanitize'; import { parseBlockMD, @@ -10,7 +10,7 @@ import { import { findAndReplace } from '$utils/findAndReplace'; import { sanitizeForRegex } from '$utils/regex'; import { isUserId } from '$utils/matrix'; -import { CustomElement } from './slate'; +import { type CustomElement } from './slate'; import { BlockType } from './types'; export type OutputOptions = { diff --git a/src/app/components/editor/slate.d.ts b/src/app/components/editor/slate.d.ts index 81d690fbc..255c459ae 100644 --- a/src/app/components/editor/slate.d.ts +++ b/src/app/components/editor/slate.d.ts @@ -1,7 +1,7 @@ -import { BaseEditor } from 'slate'; -import { ReactEditor } from 'slate-react'; -import { HistoryEditor } from 'slate-history'; -import { BlockType } from './types'; +import { type BaseEditor } from 'slate'; +import { type ReactEditor } from 'slate-react'; +import { type HistoryEditor } from 'slate-history'; +import { type BlockType } from './types'; export type HeadingLevel = 1 | 2 | 3; diff --git a/src/app/components/editor/utils.ts b/src/app/components/editor/utils.ts index 85ff437a1..de3928e89 100644 --- a/src/app/components/editor/utils.ts +++ b/src/app/components/editor/utils.ts @@ -1,12 +1,21 @@ -import { BasePoint, BaseRange, Editor, Element, Point, Range, Text, Transforms } from 'slate'; +import { + type BasePoint, + type BaseRange, + Editor, + Element, + Point, + Range, + Text, + Transforms, +} from 'slate'; import { BlockType, MarkType } from './types'; import { - CommandElement, - EmoticonElement, - FormattedText, - HeadingLevel, - LinkElement, - MentionElement, + type CommandElement, + type EmoticonElement, + type FormattedText, + type HeadingLevel, + type LinkElement, + type MentionElement, } from './slate'; const ALL_MARK_TYPE: MarkType[] = [ diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 193caf71d..ce43c387c 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -1,9 +1,9 @@ import { - ChangeEventHandler, - FocusEventHandler, - MouseEventHandler, - ReactNode, - RefObject, + type ChangeEventHandler, + type FocusEventHandler, + type MouseEventHandler, + type ReactNode, + type RefObject, useCallback, useEffect, useMemo, @@ -12,22 +12,22 @@ import { import { Box, config, Icons, Scroll } from 'folds'; import FocusTrap from 'focus-trap-react'; import { isKeyHotkey } from 'is-hotkey'; -import { Room } from '$types/matrix-sdk'; -import { atom, PrimitiveAtom, useAtom, useSetAtom } from 'jotai'; +import { type Room } from '$types/matrix-sdk'; +import { atom, type PrimitiveAtom, useAtom, useSetAtom } from 'jotai'; import { useVirtualizer } from '@tanstack/react-virtual'; -import { IEmoji, emojiGroups, emojis } from '$plugins/emoji'; +import { type IEmoji, emojiGroups, emojis } from '$plugins/emoji'; import { preventScrollWithArrowKey, stopPropagation } from '$utils/keyboard'; import { useRelevantImagePacks } from '$hooks/useImagePacks'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useRecentEmoji } from '$hooks/useRecentEmoji'; import { isUserId, mxcUrlToHttp } from '$utils/matrix'; import { editableActiveElement, targetFromEvent } from '$utils/dom'; -import { useAsyncSearch, UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; +import { useAsyncSearch, type UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; import { useDebounce } from '$hooks/useDebounce'; import { useThrottle } from '$hooks/useThrottle'; import { addRecentEmoji } from '$plugins/recent-emoji'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; -import { ImagePack, ImageUsage, PackImageReader } from '$plugins/custom-emoji'; +import { type ImagePack, ImageUsage, type PackImageReader } from '$plugins/custom-emoji'; import { getEmoticonSearchStr } from '$plugins/utils'; import { VirtualTile } from '$components/virtualizer'; import { useSetting } from '$state/hooks/settings'; @@ -43,7 +43,7 @@ import { NoStickerPacks, createPreviewDataAtom, Preview, - PreviewData, + type PreviewData, EmojiItem, StickerItem, CustomEmojiItem, diff --git a/src/app/components/emoji-board/components/Group.tsx b/src/app/components/emoji-board/components/Group.tsx index 293ac6145..97836e9d7 100644 --- a/src/app/components/emoji-board/components/Group.tsx +++ b/src/app/components/emoji-board/components/Group.tsx @@ -1,5 +1,5 @@ import { as, Box, Text } from 'folds'; -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import classNames from 'classnames'; import * as css from './styles.css'; diff --git a/src/app/components/emoji-board/components/Item.tsx b/src/app/components/emoji-board/components/Item.tsx index c593b5db0..895316d18 100644 --- a/src/app/components/emoji-board/components/Item.tsx +++ b/src/app/components/emoji-board/components/Item.tsx @@ -1,9 +1,9 @@ import { Box } from 'folds'; -import { MatrixClient } from '$types/matrix-sdk'; -import { PackImageReader } from '$plugins/custom-emoji'; -import { IEmoji } from '$plugins/emoji'; +import { type MatrixClient } from '$types/matrix-sdk'; +import { type PackImageReader } from '$plugins/custom-emoji'; +import { type IEmoji } from '$plugins/emoji'; import { mxcUrlToHttp } from '$utils/matrix'; -import { EmojiItemInfo, EmojiType } from '$components/emoji-board/types'; +import { type EmojiItemInfo, EmojiType } from '$components/emoji-board/types'; import * as css from './styles.css'; const ANIMATED_MIME_TYPES = new Set(['image/gif', 'image/apng']); diff --git a/src/app/components/emoji-board/components/Layout.tsx b/src/app/components/emoji-board/components/Layout.tsx index 286006896..8453f494b 100644 --- a/src/app/components/emoji-board/components/Layout.tsx +++ b/src/app/components/emoji-board/components/Layout.tsx @@ -1,5 +1,5 @@ import { as, Box, Line } from 'folds'; -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import classNames from 'classnames'; import * as css from './styles.css'; diff --git a/src/app/components/emoji-board/components/Preview.tsx b/src/app/components/emoji-board/components/Preview.tsx index 1f7cef289..65444a1cf 100644 --- a/src/app/components/emoji-board/components/Preview.tsx +++ b/src/app/components/emoji-board/components/Preview.tsx @@ -1,5 +1,5 @@ import { Box, Text } from 'folds'; -import { Atom, atom, useAtomValue } from 'jotai'; +import { type Atom, atom, useAtomValue } from 'jotai'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { mxcUrlToHttp } from '$utils/matrix'; diff --git a/src/app/components/emoji-board/components/SearchInput.tsx b/src/app/components/emoji-board/components/SearchInput.tsx index c3c80e939..8896d8ad9 100644 --- a/src/app/components/emoji-board/components/SearchInput.tsx +++ b/src/app/components/emoji-board/components/SearchInput.tsx @@ -1,4 +1,4 @@ -import { ChangeEventHandler, useRef } from 'react'; +import { type ChangeEventHandler, useRef } from 'react'; import { Input, Chip, Icon, Icons, Text } from 'folds'; import { mobileOrTablet } from '$utils/user-agent'; diff --git a/src/app/components/emoji-board/components/Sidebar.tsx b/src/app/components/emoji-board/components/Sidebar.tsx index 70bf87902..d03c9a4a4 100644 --- a/src/app/components/emoji-board/components/Sidebar.tsx +++ b/src/app/components/emoji-board/components/Sidebar.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { Box, Scroll, @@ -9,7 +9,7 @@ import { Text, IconButton, Icon, - IconSrc, + type IconSrc, Icons, } from 'folds'; import classNames from 'classnames'; diff --git a/src/app/components/emoji-board/components/Tabs.tsx b/src/app/components/emoji-board/components/Tabs.tsx index bef95c145..63546d651 100644 --- a/src/app/components/emoji-board/components/Tabs.tsx +++ b/src/app/components/emoji-board/components/Tabs.tsx @@ -1,4 +1,4 @@ -import { CSSProperties } from 'react'; +import { type CSSProperties } from 'react'; import { Badge, Box, Text } from 'folds'; import { EmojiBoardTab } from '$components/emoji-board/types'; diff --git a/src/app/components/emoji-board/useEmojiGroupIcons.ts b/src/app/components/emoji-board/useEmojiGroupIcons.ts index 0b59fbcd9..623885149 100644 --- a/src/app/components/emoji-board/useEmojiGroupIcons.ts +++ b/src/app/components/emoji-board/useEmojiGroupIcons.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { IconSrc, Icons } from 'folds'; +import { type IconSrc, Icons } from 'folds'; import { EmojiGroupId } from '$plugins/emoji'; diff --git a/src/app/components/event-history/EventHistory.tsx b/src/app/components/event-history/EventHistory.tsx index 955a2846f..a36d5c036 100644 --- a/src/app/components/event-history/EventHistory.tsx +++ b/src/app/components/event-history/EventHistory.tsx @@ -14,7 +14,7 @@ import { color, config, } from 'folds'; -import { IContent, MatrixEvent, Room } from '$types/matrix-sdk'; +import { type IContent, type MatrixEvent, type Room } from '$types/matrix-sdk'; import { getMemberDisplayName } from '$utils/room'; import { getMxIdLocalPart } from '$utils/matrix'; import { useMatrixClient } from '$hooks/useMatrixClient'; @@ -30,8 +30,8 @@ import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { useCallback, useMemo, useState } from 'react'; import { getReactCustomHtmlParser, LINKIFY_OPTS } from '$plugins/react-custom-html-parser'; -import { Opts as LinkifyOpts } from 'linkifyjs'; -import { HTMLReactParserOptions } from 'html-react-parser'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; +import { type HTMLReactParserOptions } from 'html-react-parser'; import { useSpoilerClickHandler } from '$hooks/useSpoilerClickHandler'; import { modalAtom, ModalType } from '$state/modal'; import { roomIdToReplyDraftAtomFamily } from '$state/room/roomInputDrafts'; diff --git a/src/app/components/event-readers/EventReaders.tsx b/src/app/components/event-readers/EventReaders.tsx index 6bb1737b4..b94efbb3e 100644 --- a/src/app/components/event-readers/EventReaders.tsx +++ b/src/app/components/event-readers/EventReaders.tsx @@ -12,7 +12,7 @@ import { as, config, } from 'folds'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useRoomEventReaders } from '$hooks/useRoomEventReaders'; import { getMemberDisplayName } from '$utils/room'; import { getMxIdLocalPart } from '$utils/matrix'; diff --git a/src/app/components/image-pack-view/ImagePackContent.tsx b/src/app/components/image-pack-view/ImagePackContent.tsx index 6f56d70f3..e89108254 100644 --- a/src/app/components/image-pack-view/ImagePackContent.tsx +++ b/src/app/components/image-pack-view/ImagePackContent.tsx @@ -1,18 +1,18 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { as, Box, Text, config, Button, Menu, Spinner } from 'folds'; import { - ImagePack, - ImageUsage, - PackContent, - PackImage, + type ImagePack, + type ImageUsage, + type PackContent, + type PackImage, PackImageReader, packMetaEqual, PackMetaReader, } from '$plugins/custom-emoji'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { useFilePicker } from '$hooks/useFilePicker'; -import { UploadSuccess } from '$state/upload'; -import { getImageInfo, TUploadContent } from '$utils/matrix'; +import { type UploadSuccess } from '$state/upload'; +import { getImageInfo, type TUploadContent } from '$utils/matrix'; import { getImageFileUrl, loadImageElement, renameFile } from '$utils/dom'; import { replaceSpaceWithDash, suffixRename } from '$utils/common'; import { getFileNameWithoutExt } from '$utils/mimeTypes'; diff --git a/src/app/components/image-pack-view/ImagePackView.tsx b/src/app/components/image-pack-view/ImagePackView.tsx index 304275e54..b79fd7b3b 100644 --- a/src/app/components/image-pack-view/ImagePackView.tsx +++ b/src/app/components/image-pack-view/ImagePackView.tsx @@ -1,5 +1,5 @@ import { Box, IconButton, Text, Icon, Icons, Scroll, Chip } from 'folds'; -import { PackAddress } from '$plugins/custom-emoji'; +import { type PackAddress } from '$plugins/custom-emoji'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { Page, PageHeader, PageContent } from '$components/page'; import { RoomImagePack } from './RoomImagePack'; diff --git a/src/app/components/image-pack-view/ImageTile.tsx b/src/app/components/image-pack-view/ImageTile.tsx index 2070f00e4..ee7e74fbe 100644 --- a/src/app/components/image-pack-view/ImageTile.tsx +++ b/src/app/components/image-pack-view/ImageTile.tsx @@ -1,10 +1,10 @@ -import { FormEventHandler, ReactNode, useMemo, useState } from 'react'; +import { type FormEventHandler, type ReactNode, useMemo, useState } from 'react'; import { Badge, Box, Button, Chip, Icon, Icons, Input, Text } from 'folds'; import { mxcUrlToHttp } from '$utils/matrix'; -import { ImageUsage, imageUsageEqual, PackImageReader } from '$plugins/custom-emoji'; +import { type ImageUsage, imageUsageEqual, PackImageReader } from '$plugins/custom-emoji'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useObjectURL } from '$hooks/useObjectURL'; -import { createUploadAtom, TUploadAtom } from '$state/upload'; +import { createUploadAtom, type TUploadAtom } from '$state/upload'; import { replaceSpaceWithDash } from '$utils/common'; import { SettingTile } from '$components/setting-tile'; import * as css from './style.css'; diff --git a/src/app/components/image-pack-view/PackMeta.tsx b/src/app/components/image-pack-view/PackMeta.tsx index 77e8a42f5..a45f75b49 100644 --- a/src/app/components/image-pack-view/PackMeta.tsx +++ b/src/app/components/image-pack-view/PackMeta.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useMemo, useState } from 'react'; +import { type FormEventHandler, useCallback, useMemo, useState } from 'react'; import { Box, Text, @@ -21,7 +21,7 @@ import { LINKIFY_OPTS } from '$plugins/react-custom-html-parser'; import { ContainerColor } from '$styles/ContainerColor.css'; import { useFilePicker } from '$hooks/useFilePicker'; import { useObjectURL } from '$hooks/useObjectURL'; -import { createUploadAtom, UploadSuccess } from '$state/upload'; +import { createUploadAtom, type UploadSuccess } from '$state/upload'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { PackMetaReader } from '$plugins/custom-emoji'; import { CompactUploadCardRenderer } from '$components/upload-card'; diff --git a/src/app/components/image-pack-view/RoomImagePack.tsx b/src/app/components/image-pack-view/RoomImagePack.tsx index 01f0f7dd7..1feb08e62 100644 --- a/src/app/components/image-pack-view/RoomImagePack.tsx +++ b/src/app/components/image-pack-view/RoomImagePack.tsx @@ -1,8 +1,8 @@ import { useCallback, useMemo } from 'react'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { usePowerLevels } from '$hooks/usePowerLevels'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { ImagePack, PackContent } from '$plugins/custom-emoji'; +import { ImagePack, type PackContent } from '$plugins/custom-emoji'; import { StateEvent } from '$types/matrix/room'; import { useRoomImagePack } from '$hooks/useImagePacks'; import { randomStr } from '$utils/common'; diff --git a/src/app/components/image-pack-view/UsageSwitcher.tsx b/src/app/components/image-pack-view/UsageSwitcher.tsx index 201a40aaa..4b022dc69 100644 --- a/src/app/components/image-pack-view/UsageSwitcher.tsx +++ b/src/app/components/image-pack-view/UsageSwitcher.tsx @@ -1,5 +1,16 @@ -import { MouseEventHandler, useMemo, useState } from 'react'; -import { Box, Button, config, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text } from 'folds'; +import { type MouseEventHandler, useMemo, useState } from 'react'; +import { + Box, + Button, + config, + Icon, + Icons, + Menu, + MenuItem, + PopOut, + type RectCords, + Text, +} from 'folds'; import FocusTrap from 'focus-trap-react'; import { ImageUsage } from '$plugins/custom-emoji'; import { stopPropagation } from '$utils/keyboard'; diff --git a/src/app/components/image-pack-view/UserImagePack.tsx b/src/app/components/image-pack-view/UserImagePack.tsx index a723b83ab..f16b34d1d 100644 --- a/src/app/components/image-pack-view/UserImagePack.tsx +++ b/src/app/components/image-pack-view/UserImagePack.tsx @@ -1,5 +1,5 @@ import { useCallback, useMemo } from 'react'; -import { ImagePack, PackContent } from '$plugins/custom-emoji'; +import { ImagePack, type PackContent } from '$plugins/custom-emoji'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { AccountDataEvent } from '$types/matrix/accountData'; import { useUserImagePack } from '$hooks/useImagePacks'; diff --git a/src/app/components/image-viewer/ImageViewer.tsx b/src/app/components/image-viewer/ImageViewer.tsx index 569b61df1..934f1ca57 100644 --- a/src/app/components/image-viewer/ImageViewer.tsx +++ b/src/app/components/image-viewer/ImageViewer.tsx @@ -1,4 +1,4 @@ -import { WheelEvent } from 'react'; +import { type WheelEvent } from 'react'; import FileSaver from 'file-saver'; import classNames from 'classnames'; import { Box, Chip, Header, Icon, IconButton, Icons, Text, as } from 'folds'; diff --git a/src/app/components/info-card/InfoCard.tsx b/src/app/components/info-card/InfoCard.tsx index 6070479ca..44761abba 100644 --- a/src/app/components/info-card/InfoCard.tsx +++ b/src/app/components/info-card/InfoCard.tsx @@ -1,5 +1,5 @@ -import { Box, ContainerColor, Text } from 'folds'; -import { ReactNode } from 'react'; +import { Box, type ContainerColor, Text } from 'folds'; +import { type ReactNode } from 'react'; import classNames from 'classnames'; import { BreakWord } from '$styles/Text.css'; import { ContainerColor as ContainerClr } from '$styles/ContainerColor.css'; diff --git a/src/app/components/invite-user-prompt/InviteUserPrompt.tsx b/src/app/components/invite-user-prompt/InviteUserPrompt.tsx index c8fbabef5..ef7bf65e5 100644 --- a/src/app/components/invite-user-prompt/InviteUserPrompt.tsx +++ b/src/app/components/invite-user-prompt/InviteUserPrompt.tsx @@ -1,7 +1,7 @@ import { - ChangeEventHandler, - FormEventHandler, - KeyboardEventHandler, + type ChangeEventHandler, + type FormEventHandler, + type KeyboardEventHandler, useCallback, useMemo, useRef, @@ -29,14 +29,14 @@ import { Scroll, MenuItem, } from 'folds'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { isKeyHotkey } from 'is-hotkey'; import FocusTrap from 'focus-trap-react'; import { stopPropagation } from '$utils/keyboard'; import { useDirectUsers } from '$hooks/useDirectUsers'; import { getMxIdLocalPart, getMxIdServer, isUserId } from '$utils/matrix'; import { Membership } from '$types/matrix/room'; -import { useAsyncSearch, UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; +import { useAsyncSearch, type UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; import { highlightText, makeHighlightRegex } from '$plugins/react-custom-html-parser'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/components/join-address-prompt/JoinAddressPrompt.tsx b/src/app/components/join-address-prompt/JoinAddressPrompt.tsx index d6a6478d2..956bf669b 100644 --- a/src/app/components/join-address-prompt/JoinAddressPrompt.tsx +++ b/src/app/components/join-address-prompt/JoinAddressPrompt.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useState } from 'react'; +import { type FormEventHandler, 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..1d0e8b4cf 100644 --- a/src/app/components/knock-room-prompt/KnockRoomPrompt.tsx +++ b/src/app/components/knock-room-prompt/KnockRoomPrompt.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, FormEventHandler } from 'react'; +import { useCallback, useEffect, type FormEventHandler } from 'react'; import FocusTrap from 'focus-trap-react'; import { Dialog, @@ -17,7 +17,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..de80ab323 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..96345bc0c 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..0fc4e5f33 100644 --- a/src/app/components/media/Image.tsx +++ b/src/app/components/media/Image.tsx @@ -1,4 +1,4 @@ -import { ImgHTMLAttributes, forwardRef } from 'react'; +import { type ImgHTMLAttributes, 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..ceb7d6c04 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..073b6b0d6 100644 --- a/src/app/components/media/Video.tsx +++ b/src/app/components/media/Video.tsx @@ -1,4 +1,4 @@ -import { VideoHTMLAttributes, forwardRef, useEffect, useRef } from 'react'; +import { type VideoHTMLAttributes, forwardRef, useEffect, useRef } from 'react'; import classNames from 'classnames'; import * as css from './media.css'; diff --git a/src/app/components/member-tile/MemberTile.tsx b/src/app/components/member-tile/MemberTile.tsx index 9af782eef..a983ab9f7 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, type Room, type 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..c800c4a08 100644 --- a/src/app/components/message/FileHeader.tsx +++ b/src/app/components/message/FileHeader.tsx @@ -1,6 +1,6 @@ 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, 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 6d1a63cce..6d85a4bb7 100644 --- a/src/app/components/message/MsgTypeRenderers.tsx +++ b/src/app/components/message/MsgTypeRenderers.tsx @@ -1,19 +1,19 @@ -import { CSSProperties, ReactNode, useMemo } from 'react'; +import { type CSSProperties, type ReactNode, useMemo } from 'react'; import { Box, Chip, Icon, Icons, Text, toRem } from 'folds'; -import { IContent } from '$types/matrix-sdk'; +import { type IContent } from '$types/matrix-sdk'; import { JUMBO_EMOJI_REG, URL_REG } from '$utils/regex'; import { trimReplyFromBody } from '$utils/room'; import { - IAudioContent, - IAudioInfo, - IEncryptedFile, - IFileContent, - IFileInfo, - IImageContent, - IImageInfo, - IThumbnailContent, - IVideoContent, - IVideoInfo, + type IAudioContent, + type IAudioInfo, + type IEncryptedFile, + type IFileContent, + type IFileInfo, + type IImageContent, + type IImageInfo, + type IThumbnailContent, + type IVideoContent, + type IVideoInfo, MATRIX_SPOILER_PROPERTY_NAME, MATRIX_SPOILER_REASON_PROPERTY_NAME, } from '$types/matrix/common'; @@ -21,7 +21,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 { diff --git a/src/app/components/message/Reaction.tsx b/src/app/components/message/Reaction.tsx index 155de11f4..f411adb24 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, type MatrixEvent, type 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 e26b237b0..4873d74f9 100644 --- a/src/app/components/message/RenderBody.tsx +++ b/src/app/components/message/RenderBody.tsx @@ -1,8 +1,8 @@ -import { MouseEventHandler, useEffect, useState } from 'react'; -import parse, { HTMLReactParserOptions } from 'html-react-parser'; +import { type MouseEventHandler, useEffect, useState } from 'react'; +import parse, { type HTMLReactParserOptions } from 'html-react-parser'; import Linkify from 'linkify-react'; -import { Opts } from 'linkifyjs'; -import { PopOut, RectCords, Text, Tooltip, TooltipProvider, toRem } from 'folds'; +import { type Opts } from 'linkifyjs'; +import { PopOut, type RectCords, 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'; diff --git a/src/app/components/message/Reply.tsx b/src/app/components/message/Reply.tsx index 3342b0d52..0ad20e216 100644 --- a/src/app/components/message/Reply.tsx +++ b/src/app/components/message/Reply.tsx @@ -1,6 +1,11 @@ -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 { Box, Chip, Icon, type IconSrc, Icons, Text, as, color, toRem } from 'folds'; +import { + type EventTimelineSet, + type IMentions, + type Room, + type SessionMembershipData, +} from '$types/matrix-sdk'; +import { type MouseEventHandler, type ReactNode, useCallback, useMemo } from 'react'; import { useQueryClient } from '@tanstack/react-query'; import classNames from 'classnames'; import parse from 'html-react-parser'; diff --git a/src/app/components/message/Time.tsx b/src/app/components/message/Time.tsx index dc190d93d..844a2f1b7 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..213ac1066 100644 --- a/src/app/components/message/attachment/Attachment.css.ts +++ b/src/app/components/message/attachment/Attachment.css.ts @@ -1,5 +1,5 @@ import { style } from '@vanilla-extract/css'; -import { RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { type RecipeVariants, 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..34fc1d3f3 100644 --- a/src/app/components/message/content/AudioContent.tsx +++ b/src/app/components/message/content/AudioContent.tsx @@ -1,13 +1,13 @@ /* eslint-disable jsx-a11y/media-has-caption */ -import { ReactNode, useCallback, useEffect, useRef, useState } from 'react'; +import { type ReactNode, 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 { - PlayTimeCallback, + type PlayTimeCallback, useMediaLoading, useMediaPlay, useMediaPlayTimeCallback, diff --git a/src/app/components/message/content/EventContent.tsx b/src/app/components/message/content/EventContent.tsx index 35449e1ba..bcdd8cb63 100644 --- a/src/app/components/message/content/EventContent.tsx +++ b/src/app/components/message/content/EventContent.tsx @@ -1,5 +1,5 @@ -import { Box, Icon, IconSrc } from 'folds'; -import { ReactNode } from 'react'; +import { Box, Icon, type IconSrc } from 'folds'; +import { type ReactNode } from 'react'; import { MessageLayout } from '$state/settings'; import { BubbleLayout, CompactLayout, ModernLayout } from '$components/message/layout'; diff --git a/src/app/components/message/content/FileContent.tsx b/src/app/components/message/content/FileContent.tsx index af802d46b..89c50ec52 100644 --- a/src/app/components/message/content/FileContent.tsx +++ b/src/app/components/message/content/FileContent.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useCallback, useState } from 'react'; +import { type ReactNode, useCallback, useState } from 'react'; import { Box, Button, @@ -15,9 +15,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'; diff --git a/src/app/components/message/content/ImageContent.tsx b/src/app/components/message/content/ImageContent.tsx index ad51d2a4f..ce53650c9 100644 --- a/src/app/components/message/content/ImageContent.tsx +++ b/src/app/components/message/content/ImageContent.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useCallback, useEffect, useState } from 'react'; +import { type ReactNode, useCallback, useEffect, useState } from 'react'; import { Badge, Box, @@ -22,8 +22,8 @@ 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, 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'; diff --git a/src/app/components/message/content/ThumbnailContent.tsx b/src/app/components/message/content/ThumbnailContent.tsx index 2d0510bed..15ec34020 100644 --- a/src/app/components/message/content/ThumbnailContent.tsx +++ b/src/app/components/message/content/ThumbnailContent.tsx @@ -1,5 +1,5 @@ -import { ReactNode, useCallback, useEffect } from 'react'; -import { IThumbnailContent } from '$types/matrix/common'; +import { type ReactNode, 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..6fbb42a04 100644 --- a/src/app/components/message/content/VideoContent.tsx +++ b/src/app/components/message/content/VideoContent.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useCallback, useEffect, useState } from 'react'; +import { type ReactNode, useCallback, useEffect, useState } from 'react'; import { Badge, Box, @@ -17,10 +17,10 @@ import { } from 'folds'; import classNames from 'classnames'; import { BlurhashCanvas } from 'react-blurhash'; -import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { type EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; import { - IThumbnailContent, - IVideoInfo, + type IThumbnailContent, + type IVideoInfo, MATRIX_BLUR_HASH_PROPERTY_NAME, } from '$types/matrix/common'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/components/message/layout/Bubble.tsx b/src/app/components/message/layout/Bubble.tsx index 21120da47..9ffeabe2d 100644 --- a/src/app/components/message/layout/Bubble.tsx +++ b/src/app/components/message/layout/Bubble.tsx @@ -1,6 +1,6 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import classNames from 'classnames'; -import { Box, ContainerColor, as, color } from 'folds'; +import { Box, type ContainerColor, 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..5e4b7fece 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..a2c6273a6 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 9928f15e6..ef391cf87 100644 --- a/src/app/components/message/layout/layout.css.ts +++ b/src/app/components/message/layout/layout.css.ts @@ -1,5 +1,5 @@ import { createVar, keyframes, style, styleVariants } from '@vanilla-extract/css'; -import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; +import { recipe, type RecipeVariants } 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..12c3b3546 100644 --- a/src/app/components/message/modals/MessageDelete.tsx +++ b/src/app/components/message/modals/MessageDelete.tsx @@ -1,5 +1,5 @@ -import { FormEventHandler, MouseEvent, useCallback, useEffect } from 'react'; -import { Room, MatrixEvent } from '$types/matrix-sdk'; +import { type FormEventHandler, type MouseEvent, useCallback, useEffect } from 'react'; +import { type Room, type 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..5057c82a2 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, type 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 7e29f3d49..b51e4869f 100644 --- a/src/app/components/message/modals/MessageForward.tsx +++ b/src/app/components/message/modals/MessageForward.tsx @@ -17,7 +17,7 @@ import { as, } from 'folds'; import { useAtomValue, useSetAtom } from 'jotai'; -import { JoinRule, MatrixEvent, Room } from '$types/matrix-sdk'; +import { JoinRule, type MatrixEvent, type Room } from '$types/matrix-sdk'; import { useEffect, useMemo, useState } from 'react'; import { allRoomsAtom } from '$state/room-list/roomList'; import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom'; diff --git a/src/app/components/message/modals/MessageReactions.tsx b/src/app/components/message/modals/MessageReactions.tsx index f2fa7a5bd..04a32b511 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, type 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..7252e696d 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..beae33e1e 100644 --- a/src/app/components/message/modals/MessageReport.tsx +++ b/src/app/components/message/modals/MessageReport.tsx @@ -1,5 +1,5 @@ -import { FormEventHandler, MouseEvent, useCallback, useEffect } from 'react'; -import { Room, MatrixEvent } from '$types/matrix-sdk'; +import { type FormEventHandler, type MouseEvent, useCallback, useEffect } from 'react'; +import { type Room, type 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..1deb28ebf 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, type MatrixEvent } from '$types/matrix-sdk'; import { useSetAtom } from 'jotai'; import { MenuItem, Icon, Icons, Text } from 'folds'; import { TextViewer } from '$components/text-viewer'; diff --git a/src/app/components/message/placeholder/CompactPlaceholder.tsx b/src/app/components/message/placeholder/CompactPlaceholder.tsx index c6e6dda00..961cf165e 100644 --- a/src/app/components/message/placeholder/CompactPlaceholder.tsx +++ b/src/app/components/message/placeholder/CompactPlaceholder.tsx @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { as, ContainerColor, toRem } from 'folds'; +import { as, type ContainerColor, 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..d0a73733f 100644 --- a/src/app/components/message/placeholder/DefaultPlaceholder.tsx +++ b/src/app/components/message/placeholder/DefaultPlaceholder.tsx @@ -1,5 +1,5 @@ -import { CSSProperties, useMemo } from 'react'; -import { Avatar, Box, ContainerColor, as, color, toRem } from 'folds'; +import { type CSSProperties, useMemo } from 'react'; +import { Avatar, Box, type ContainerColor, as, color, toRem } from 'folds'; import { randomNumberBetween } from '$utils/common'; import { ModernLayout } from '$components/message/layout'; import { LinePlaceholder } from './LinePlaceholder'; diff --git a/src/app/components/message/placeholder/LinePlaceholder.css.ts b/src/app/components/message/placeholder/LinePlaceholder.css.ts index 34ad76a3e..bcf69b7e5 100644 --- a/src/app/components/message/placeholder/LinePlaceholder.css.ts +++ b/src/app/components/message/placeholder/LinePlaceholder.css.ts @@ -1,6 +1,6 @@ -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 { recipe, type RecipeVariants } from '@vanilla-extract/recipes'; +import { type ContainerColor, 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..b03c0916a 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..1cbea5b10 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..cf21d6699 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..f3eefa4f5 100644 --- a/src/app/components/nav/NavItem.tsx +++ b/src/app/components/nav/NavItem.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import { ComponentProps, forwardRef } from 'react'; +import { type ComponentProps, forwardRef } from 'react'; import { Link } from 'react-router-dom'; import { as } from 'folds'; import * as css from './styles.css'; diff --git a/src/app/components/nav/NavItemContent.tsx b/src/app/components/nav/NavItemContent.tsx index eaf8f113e..4ca35cc0c 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..d43fc7ab0 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..cd02a25f4 100644 --- a/src/app/components/nav/styles.css.ts +++ b/src/app/components/nav/styles.css.ts @@ -1,6 +1,14 @@ -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, createVar, style } from '@vanilla-extract/css'; +import { type RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { + type ContainerColor, + 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..38b163863 100644 --- a/src/app/components/notification-banner/NotificationBanner.tsx +++ b/src/app/components/notification-banner/NotificationBanner.tsx @@ -1,8 +1,8 @@ import { useAtom } from 'jotai'; -import { ReactNode, useCallback, useEffect, useRef, useState } from 'react'; +import { type ReactNode, 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 { inAppBannerAtom, type InAppBannerNotification } 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..87534b479 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, type MutableRefObject, type 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..5241c11eb 100644 --- a/src/app/components/page/style.css.ts +++ b/src/app/components/page/style.css.ts @@ -1,5 +1,5 @@ import { style } from '@vanilla-extract/css'; -import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; +import { recipe, type RecipeVariants } 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..0fce3feda 100644 --- a/src/app/components/password-input/PasswordInput.tsx +++ b/src/app/components/password-input/PasswordInput.tsx @@ -1,4 +1,4 @@ -import { ComponentProps, forwardRef } from 'react'; +import { type ComponentProps, 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..5d6aa9d51 100644 --- a/src/app/components/power/PowerSelector.tsx +++ b/src/app/components/power/PowerSelector.tsx @@ -1,7 +1,7 @@ -import { forwardRef, MouseEventHandler, ReactNode, useState } from 'react'; +import { forwardRef, type MouseEventHandler, type ReactNode, 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 { Box, config, Menu, MenuItem, PopOut, Scroll, Text, toRem, type RectCords } from 'folds'; +import { getPowers, type PowerLevelTags } from '$hooks/usePowerLevelTags'; import { stopPropagation } from '$utils/keyboard'; import { PowerColorBadge } from './PowerColorBadge'; diff --git a/src/app/components/power/style.css.ts b/src/app/components/power/style.css.ts index 60737f8cb..7a076df3a 100644 --- a/src/app/components/power/style.css.ts +++ b/src/app/components/power/style.css.ts @@ -1,5 +1,5 @@ import { createVar, style } from '@vanilla-extract/css'; -import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; +import { recipe, type RecipeVariants } 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..8e3d3c7d1 100644 --- a/src/app/components/presence/Presence.tsx +++ b/src/app/components/presence/Presence.tsx @@ -3,14 +3,14 @@ import { Badge, Box, color, - ContainerColor, - MainColor, + type ContainerColor, + type MainColor, Text, Tooltip, TooltipProvider, toRem, } from 'folds'; -import { ReactNode, useId } from 'react'; +import { type ReactNode, 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..97c06bb48 100644 --- a/src/app/components/room-avatar/AvatarImage.tsx +++ b/src/app/components/room-avatar/AvatarImage.tsx @@ -1,5 +1,5 @@ import { AvatarImage as FoldsAvatarImage } from 'folds'; -import { ReactEventHandler, useState, useEffect } from 'react'; +import { type ReactEventHandler, 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 356d9dbc2..991000df4 100644 --- a/src/app/components/room-avatar/RoomAvatar.tsx +++ b/src/app/components/room-avatar/RoomAvatar.tsx @@ -1,6 +1,6 @@ -import { JoinRule } from '$types/matrix-sdk'; +import { type JoinRule } from '$types/matrix-sdk'; import { AvatarFallback, Icon, Icons, color } from 'folds'; -import { ComponentProps, ReactNode, forwardRef, useState } from 'react'; +import { type ComponentProps, type ReactNode, forwardRef, 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..a507b684c 100644 --- a/src/app/components/room-card/RoomCard.tsx +++ b/src/app/components/room-card/RoomCard.tsx @@ -1,5 +1,5 @@ -import { ReactNode, useCallback, useRef, useState } from 'react'; -import { JoinRule, MatrixError, Room } from '$types/matrix-sdk'; +import { type ReactNode, useCallback, useRef, useState } from 'react'; +import { JoinRule, type MatrixError, type Room } from '$types/matrix-sdk'; import { Avatar, Badge, diff --git a/src/app/components/room-intro/RoomIntro.tsx b/src/app/components/room-intro/RoomIntro.tsx index 3ad39546f..aaf0698f6 100644 --- a/src/app/components/room-intro/RoomIntro.tsx +++ b/src/app/components/room-intro/RoomIntro.tsx @@ -1,8 +1,8 @@ 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, 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..ecb204017 100644 --- a/src/app/components/scroll-top-container/ScrollTopContainer.tsx +++ b/src/app/components/scroll-top-container/ScrollTopContainer.tsx @@ -1,4 +1,4 @@ -import { RefObject, useCallback, useState } from 'react'; +import { type RefObject, 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 7738d93fb..8d3ebbcc9 100644 --- a/src/app/components/sequence-card/SequenceCard.tsx +++ b/src/app/components/sequence-card/SequenceCard.tsx @@ -1,7 +1,7 @@ -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 { ContainerColor, type ContainerColorVariants } 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..17f02dcc3 100644 --- a/src/app/components/sequence-card/style.css.ts +++ b/src/app/components/sequence-card/style.css.ts @@ -1,5 +1,5 @@ import { createVar } from '@vanilla-extract/css'; -import { RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { type RecipeVariants, recipe } from '@vanilla-extract/recipes'; import { config } from 'folds'; const outlinedWidth = createVar('0'); diff --git a/src/app/components/setting-tile/SettingTile.tsx b/src/app/components/setting-tile/SettingTile.tsx index e57dccd55..d0280b9fa 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, Text } from 'folds'; import { BreakWord } from '$styles/Text.css'; diff --git a/src/app/components/sidebar/Sidebar.css.ts b/src/app/components/sidebar/Sidebar.css.ts index 2952a0f7d..063b83c4d 100644 --- a/src/app/components/sidebar/Sidebar.css.ts +++ b/src/app/components/sidebar/Sidebar.css.ts @@ -1,5 +1,5 @@ import { createVar, style } from '@vanilla-extract/css'; -import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; +import { recipe, type RecipeVariants } 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..6e7f62fc2 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..b0af1ec13 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, type ReactNode, type 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..4ed6ef639 100644 --- a/src/app/components/sidebar/SidebarUnreadBadge.tsx +++ b/src/app/components/sidebar/SidebarUnreadBadge.tsx @@ -1,4 +1,8 @@ -import { UnreadBadge, UnreadBadgeMode, resolveUnreadBadgeMode } from '$components/unread-badge'; +import { + UnreadBadge, + type UnreadBadgeMode, + 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..71cada585 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/styles.css.ts b/src/app/components/stacked-avatar/styles.css.ts index 3bbf7271a..b7f279e2e 100644 --- a/src/app/components/stacked-avatar/styles.css.ts +++ b/src/app/components/stacked-avatar/styles.css.ts @@ -1,6 +1,6 @@ -import { ComplexStyleRule } from '@vanilla-extract/css'; -import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; -import { color, config, ContainerColor, toRem } from 'folds'; +import { type ComplexStyleRule } from '@vanilla-extract/css'; +import { recipe, type RecipeVariants } from '@vanilla-extract/recipes'; +import { color, config, type ContainerColor, toRem } from 'folds'; const getVariant = (variant: ContainerColor): ComplexStyleRule => ({ outlineColor: color[variant].Container, diff --git a/src/app/components/text-viewer/TextViewer.tsx b/src/app/components/text-viewer/TextViewer.tsx index 8c6957ec8..a21672434 100644 --- a/src/app/components/text-viewer/TextViewer.tsx +++ b/src/app/components/text-viewer/TextViewer.tsx @@ -1,4 +1,4 @@ -import { ComponentProps, HTMLAttributes, Suspense, forwardRef, lazy } from 'react'; +import { type ComponentProps, type HTMLAttributes, Suspense, forwardRef, lazy } from 'react'; import classNames from 'classnames'; import { Box, Chip, Header, Icon, IconButton, Icons, Scroll, Text, as } from 'folds'; import { ErrorBoundary } from 'react-error-boundary'; diff --git a/src/app/components/time-date/PickerColumn.tsx b/src/app/components/time-date/PickerColumn.tsx index a1fbcb34f..4a74f713d 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/uia-stages/DummyStage.tsx b/src/app/components/uia-stages/DummyStage.tsx index 9a78af0e8..62f716458 100644 --- a/src/app/components/uia-stages/DummyStage.tsx +++ b/src/app/components/uia-stages/DummyStage.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 DummyErrorDialog({ title, diff --git a/src/app/components/uia-stages/EmailStage.tsx b/src/app/components/uia-stages/EmailStage.tsx index 3d3134495..322f49d97 100644 --- a/src/app/components/uia-stages/EmailStage.tsx +++ b/src/app/components/uia-stages/EmailStage.tsx @@ -1,9 +1,9 @@ -import { useEffect, useCallback, FormEventHandler } from 'react'; +import { useEffect, useCallback, type FormEventHandler } from 'react'; import { Dialog, Text, Box, Button, config, Input, color, Spinner } from 'folds'; -import { AuthType, MatrixError } from '$types/matrix-sdk'; -import { AsyncState, AsyncStatus } from '$hooks/useAsyncCallback'; -import { RequestEmailTokenCallback, RequestEmailTokenResponse } from '$hooks/types'; -import { StageComponentProps } from './types'; +import { AuthType, type MatrixError } from '$types/matrix-sdk'; +import { type AsyncState, AsyncStatus } from '$hooks/useAsyncCallback'; +import { type RequestEmailTokenCallback, type RequestEmailTokenResponse } from '$hooks/types'; +import { type StageComponentProps } from './types'; function EmailErrorDialog({ title, diff --git a/src/app/components/uia-stages/PasswordStage.tsx b/src/app/components/uia-stages/PasswordStage.tsx index 8ebc923ab..e3b0884bf 100644 --- a/src/app/components/uia-stages/PasswordStage.tsx +++ b/src/app/components/uia-stages/PasswordStage.tsx @@ -1,8 +1,8 @@ import { Box, Button, color, config, Dialog, Header, Icon, IconButton, Icons, Text } from 'folds'; -import { FormEventHandler } from 'react'; +import { type FormEventHandler } from 'react'; import { AuthType } from '$types/matrix-sdk'; import { PasswordInput } from '$components/password-input'; -import { StageComponentProps } from './types'; +import { type StageComponentProps } from './types'; import { ErrorCode } from '../../cs-errorcode'; export function PasswordStage({ diff --git a/src/app/components/uia-stages/ReCaptchaStage.tsx b/src/app/components/uia-stages/ReCaptchaStage.tsx index 65357b0e4..ea190904e 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..d471b3813 100644 --- a/src/app/components/uia-stages/RegistrationTokenStage.tsx +++ b/src/app/components/uia-stages/RegistrationTokenStage.tsx @@ -1,7 +1,7 @@ -import { useEffect, useCallback, FormEventHandler } from 'react'; +import { useEffect, useCallback, type FormEventHandler } 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..5da517fda 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..01fe7b441 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..ca81984ff 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..0c0c29477 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, type 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..f03eb0d4b 100644 --- a/src/app/components/upload-board/UploadBoard.tsx +++ b/src/app/components/upload-board/UploadBoard.tsx @@ -1,9 +1,14 @@ -import { MutableRefObject, ReactNode, useImperativeHandle, useRef } from 'react'; +import { type MutableRefObject, type ReactNode, 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, + type Upload, + UploadStatus, + type UploadSuccess, +} 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..46708c690 100644 --- a/src/app/components/upload-card/CompactUploadCardRenderer.tsx +++ b/src/app/components/upload-card/CompactUploadCardRenderer.tsx @@ -1,8 +1,13 @@ import { useEffect } from 'react'; import { Chip, Icon, IconButton, Icons, Text, color } from 'folds'; -import { TUploadAtom, UploadStatus, UploadSuccess, useBindUploadAtom } from '$state/upload'; +import { + type TUploadAtom, + UploadStatus, + type UploadSuccess, + 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..fb15c4955 100644 --- a/src/app/components/upload-card/UploadCard.css.ts +++ b/src/app/components/upload-card/UploadCard.css.ts @@ -1,5 +1,5 @@ import { style } from '@vanilla-extract/css'; -import { RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { type RecipeVariants, 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..6111515fb 100644 --- a/src/app/components/upload-card/UploadCard.tsx +++ b/src/app/components/upload-card/UploadCard.tsx @@ -1,5 +1,5 @@ import { Badge, Box, Icon, Icons, ProgressBar, Text, percent } from 'folds'; -import { ReactNode, forwardRef } from 'react'; +import { type ReactNode, 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 d9fa444f7..2eb88190f 100644 --- a/src/app/components/upload-card/UploadCardRenderer.tsx +++ b/src/app/components/upload-card/UploadCardRenderer.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useEffect, useMemo, useRef, useState } from 'react'; +import { type ReactNode, useEffect, useMemo, useRef, useState } from 'react'; import { Box, Chip, @@ -13,18 +13,22 @@ 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 { UploadStatus, type UploadSuccess, 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 { + roomUploadAtomFamily, + type TUploadItem, + type TUploadMetadata, +} from '$state/room/roomInputDrafts'; import { useObjectURL } from '$hooks/useObjectURL'; import { useMediaConfig } from '$hooks/useMediaConfig'; import { UploadCard, UploadCardError, UploadCardProgress } from './UploadCard'; diff --git a/src/app/components/upload-card/UploadDescriptionEditor.tsx b/src/app/components/upload-card/UploadDescriptionEditor.tsx index 563f06eda..6d527c783 100644 --- a/src/app/components/upload-card/UploadDescriptionEditor.tsx +++ b/src/app/components/upload-card/UploadDescriptionEditor.tsx @@ -1,4 +1,4 @@ -import { KeyboardEventHandler, useCallback, useEffect, useState, useRef } from 'react'; +import { type KeyboardEventHandler, useCallback, useEffect, useState, useRef } from 'react'; import { Box, Chip, @@ -7,7 +7,7 @@ import { Icons, Line, PopOut, - RectCords, + type RectCords, Spinner, Text, config, @@ -17,7 +17,7 @@ import { ReactEditor } from 'slate-react'; import { isKeyHotkey } from 'is-hotkey'; import { AutocompletePrefix, - AutocompleteQuery, + type AutocompleteQuery, CustomEditor, EmoticonAutocomplete, Toolbar, diff --git a/src/app/components/url-preview/ClientPreview.tsx b/src/app/components/url-preview/ClientPreview.tsx index 962168d5f..922c25981 100644 --- a/src/app/components/url-preview/ClientPreview.tsx +++ b/src/app/components/url-preview/ClientPreview.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState, ReactNode } from 'react'; +import { useCallback, useEffect, useState, type ReactNode } from 'react'; import { Box, Badge, Icon, IconButton, Icons, Spinner, Text, as, toRem } from 'folds'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useSetting } from '$state/hooks/settings'; diff --git a/src/app/components/url-preview/UrlPreviewCard.tsx b/src/app/components/url-preview/UrlPreviewCard.tsx index 62106a00a..ff48f78d9 100644 --- a/src/app/components/url-preview/UrlPreviewCard.tsx +++ b/src/app/components/url-preview/UrlPreviewCard.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useRef, useState } from 'react'; -import { IPreviewUrlResponse } from '$types/matrix-sdk'; +import { type IPreviewUrlResponse } from '$types/matrix-sdk'; import { Box, Icon, IconButton, Icons, Scroll, Spinner, Text, as, color, config } from 'folds'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/components/user-avatar/UserAvatar.tsx b/src/app/components/user-avatar/UserAvatar.tsx index 3659cb305..a036221d4 100644 --- a/src/app/components/user-avatar/UserAvatar.tsx +++ b/src/app/components/user-avatar/UserAvatar.tsx @@ -1,5 +1,5 @@ import { AvatarFallback, AvatarImage, color } from 'folds'; -import { ReactEventHandler, ReactNode, useState } from 'react'; +import { type ReactEventHandler, type ReactNode, useState } from 'react'; import classNames from 'classnames'; import colorMXID from '$utils/colorMXID'; import * as css from './UserAvatar.css'; diff --git a/src/app/components/user-profile/CreatorChip.tsx b/src/app/components/user-profile/CreatorChip.tsx index f517581cc..6499a36a7 100644 --- a/src/app/components/user-profile/CreatorChip.tsx +++ b/src/app/components/user-profile/CreatorChip.tsx @@ -1,5 +1,5 @@ -import { Chip, config, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text } from 'folds'; -import { MouseEventHandler, useState } from 'react'; +import { Chip, config, Icon, Icons, Menu, MenuItem, PopOut, type RectCords, Text } from 'folds'; +import { type MouseEventHandler, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { isKeyHotkey } from 'is-hotkey'; import { useRoomCreatorsTag } from '$hooks/useRoomCreatorsTag'; diff --git a/src/app/components/user-profile/PowerChip.tsx b/src/app/components/user-profile/PowerChip.tsx index d1e4dbfa2..22f5a9f8a 100644 --- a/src/app/components/user-profile/PowerChip.tsx +++ b/src/app/components/user-profile/PowerChip.tsx @@ -15,12 +15,12 @@ import { OverlayBackdrop, OverlayCenter, PopOut, - RectCords, + type RectCords, Spinner, Text, toRem, } from 'folds'; -import { MouseEventHandler, useCallback, useState } from 'react'; +import { type MouseEventHandler, useCallback, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { isKeyHotkey } from 'is-hotkey'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/components/user-profile/UserChips.tsx b/src/app/components/user-profile/UserChips.tsx index 1ce3b26c1..fbcf870f1 100644 --- a/src/app/components/user-profile/UserChips.tsx +++ b/src/app/components/user-profile/UserChips.tsx @@ -1,6 +1,6 @@ import { - KeyboardEventHandler, - MouseEventHandler, + type KeyboardEventHandler, + type MouseEventHandler, useCallback, useEffect, useMemo, @@ -10,7 +10,7 @@ import { import { useNavigate } from 'react-router-dom'; import FocusTrap from 'focus-trap-react'; import { isKeyHotkey } from 'is-hotkey'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { PopOut, Menu, @@ -21,7 +21,7 @@ import { Chip, Icon, Icons, - RectCords, + type RectCords, Spinner, toRem, Box, diff --git a/src/app/components/user-profile/UserHero.tsx b/src/app/components/user-profile/UserHero.tsx index 0acdc3618..dccfab777 100644 --- a/src/app/components/user-profile/UserHero.tsx +++ b/src/app/components/user-profile/UserHero.tsx @@ -18,7 +18,7 @@ import FocusTrap from 'focus-trap-react'; import colorMXID from '$utils/colorMXID'; import { getMxIdLocalPart } from '$utils/matrix'; import { BreakWord, LineClamp3 } from '$styles/Text.css'; -import { UserPresence } from '$hooks/useUserPresence'; +import { type UserPresence } from '$hooks/useUserPresence'; import { stopPropagation } from '$utils/keyboard'; import { useRoom } from '$hooks/useRoom'; import { useSableCosmetics } from '$hooks/useSableCosmetics'; diff --git a/src/app/components/user-profile/UserRoomProfile.tsx b/src/app/components/user-profile/UserRoomProfile.tsx index e11deaa83..67a26a553 100644 --- a/src/app/components/user-profile/UserRoomProfile.tsx +++ b/src/app/components/user-profile/UserRoomProfile.tsx @@ -1,9 +1,9 @@ import { Box, Button, config, Icon, Icons, Scroll, Text } from 'folds'; -import { SyntheticEvent, useCallback, useMemo, useState } from 'react'; +import { type SyntheticEvent, useCallback, useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAtomValue } from 'jotai'; -import { Opts as LinkifyOpts } from 'linkifyjs'; -import { HTMLReactParserOptions } from 'html-react-parser'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; +import { type HTMLReactParserOptions } from 'html-react-parser'; import { getMxIdServer, mxcUrlToHttp } from '$utils/matrix'; import { getMemberAvatarMxc, getMemberDisplayName } from '$utils/room'; import { useMatrixClient } from '$hooks/useMatrixClient'; @@ -19,9 +19,9 @@ import { useRoomCreators } from '$hooks/useRoomCreators'; import { useRoomPermissions } from '$hooks/useRoomPermissions'; import { useMemberPowerCompare } from '$hooks/useMemberPowerCompare'; import { getDirectCreatePath, withSearchParam } from '$pages/pathUtils'; -import { DirectCreateSearchParams } from '$pages/paths'; +import { type DirectCreateSearchParams } from '$pages/paths'; import { nicknamesAtom } from '$state/nicknames'; -import { UserProfile, useUserProfile } from '$hooks/useUserProfile'; +import { type UserProfile, useUserProfile } from '$hooks/useUserProfile'; import { factoryRenderLinkifyWithMention, getReactCustomHtmlParser, diff --git a/src/app/components/virtualizer/VirtualTile.tsx b/src/app/components/virtualizer/VirtualTile.tsx index b92add55a..22c4faadd 100644 --- a/src/app/components/virtualizer/VirtualTile.tsx +++ b/src/app/components/virtualizer/VirtualTile.tsx @@ -1,4 +1,4 @@ -import { VirtualItem } from '@tanstack/react-virtual'; +import { type VirtualItem } from '@tanstack/react-virtual'; import { as } from 'folds'; import classNames from 'classnames'; import * as css from './style.css'; diff --git a/src/app/features/add-existing/AddExisting.tsx b/src/app/features/add-existing/AddExisting.tsx index 50cfc6717..fdee02b0c 100644 --- a/src/app/features/add-existing/AddExisting.tsx +++ b/src/app/features/add-existing/AddExisting.tsx @@ -20,8 +20,8 @@ import { Text, } from 'folds'; import { - ChangeEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type MouseEventHandler, useCallback, useMemo, useRef, @@ -29,7 +29,7 @@ import { } from 'react'; import { useAtomValue } from 'jotai'; import { useVirtualizer } from '@tanstack/react-virtual'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { stopPropagation } from '$utils/keyboard'; import { useDirects, useRooms, useSpaces } from '$state/hooks/roomList'; import { useMatrixClient } from '$hooks/useMatrixClient'; @@ -43,7 +43,11 @@ import { RoomAvatar, RoomIcon } from '$components/room-avatar'; import { nameInitials } from '$utils/common'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { factoryRoomIdByAtoZ } from '$utils/sort'; -import { SearchItemStrGetter, useAsyncSearch, UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; +import { + type SearchItemStrGetter, + useAsyncSearch, + type UseAsyncSearchOptions, +} from '$hooks/useAsyncSearch'; import { highlightText, makeHighlightRegex } from '$plugins/react-custom-html-parser'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { StateEvent } from '$types/matrix/room'; diff --git a/src/app/features/call-status/CallControl.tsx b/src/app/features/call-status/CallControl.tsx index 128df221f..d10a28a51 100644 --- a/src/app/features/call-status/CallControl.tsx +++ b/src/app/features/call-status/CallControl.tsx @@ -2,7 +2,7 @@ import { Box, Chip, Icon, IconButton, Icons, Spinner, Text, Tooltip, TooltipProv import { useCallback } from 'react'; import { useSetAtom } from 'jotai'; import { StatusDivider } from './components'; -import { CallEmbed, useCallControlState } from '../../plugins/call'; +import { type CallEmbed, useCallControlState } from '../../plugins/call'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; import { callEmbedAtom } from '../../state/callEmbed'; diff --git a/src/app/features/call-status/CallRoomName.tsx b/src/app/features/call-status/CallRoomName.tsx index e2cca3b1b..189d5e0ff 100644 --- a/src/app/features/call-status/CallRoomName.tsx +++ b/src/app/features/call-status/CallRoomName.tsx @@ -1,4 +1,4 @@ -import { Room } from 'matrix-js-sdk'; +import { type Room } from 'matrix-js-sdk'; import { Chip, Text } from 'folds'; import { useAtomValue } from 'jotai'; import { useRoomName } from '../../hooks/useRoomMeta'; diff --git a/src/app/features/call-status/CallStatus.tsx b/src/app/features/call-status/CallStatus.tsx index 899bff7d6..4379ac227 100644 --- a/src/app/features/call-status/CallStatus.tsx +++ b/src/app/features/call-status/CallStatus.tsx @@ -9,7 +9,7 @@ import { useCallMembers, useCallSession } from '../../hooks/useCall'; import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize'; import { MemberGlance } from './MemberGlance'; import { StatusDivider } from './components'; -import { CallEmbed } from '../../plugins/call/CallEmbed'; +import { type CallEmbed } from '../../plugins/call/CallEmbed'; import { useCallJoined } from '../../hooks/useCallEmbed'; import { useCallSpeakers } from '../../hooks/useCallSpeakers'; import { MemberSpeaking } from './MemberSpeaking'; diff --git a/src/app/features/call-status/LiveChip.tsx b/src/app/features/call-status/LiveChip.tsx index e62af0e24..6476ab2d4 100644 --- a/src/app/features/call-status/LiveChip.tsx +++ b/src/app/features/call-status/LiveChip.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useState } from 'react'; +import { type MouseEventHandler, useState } from 'react'; import { Avatar, Badge, @@ -10,14 +10,14 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Scroll, Text, toRem, } from 'folds'; -import { CallMembership } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; +import { type CallMembership } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; import FocusTrap from 'focus-trap-react'; -import { Room } from 'matrix-js-sdk'; +import { type Room } from 'matrix-js-sdk'; import * as css from './styles.css'; import { stopPropagation } from '../../utils/keyboard'; import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room'; diff --git a/src/app/features/call-status/MemberGlance.tsx b/src/app/features/call-status/MemberGlance.tsx index 88c114d51..681e13161 100644 --- a/src/app/features/call-status/MemberGlance.tsx +++ b/src/app/features/call-status/MemberGlance.tsx @@ -1,6 +1,6 @@ import { Box, config, Icon, Icons, Text } from 'folds'; -import { CallMembership } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; -import { Room } from 'matrix-js-sdk'; +import { type CallMembership } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; +import { type Room } from 'matrix-js-sdk'; import { UserAvatar } from '../../components/user-avatar'; import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room'; import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; diff --git a/src/app/features/call-status/MemberSpeaking.tsx b/src/app/features/call-status/MemberSpeaking.tsx index b80190cd3..3c7206e5b 100644 --- a/src/app/features/call-status/MemberSpeaking.tsx +++ b/src/app/features/call-status/MemberSpeaking.tsx @@ -1,4 +1,4 @@ -import { Room } from 'matrix-js-sdk'; +import { type Room } from 'matrix-js-sdk'; import { Box, Icon, Icons, Text } from 'folds'; import { getMemberDisplayName } from '../../utils/room'; import { getMxIdLocalPart } from '../../utils/matrix'; diff --git a/src/app/features/call/CallControls.tsx b/src/app/features/call/CallControls.tsx index 6643069c5..f015e684e 100644 --- a/src/app/features/call/CallControls.tsx +++ b/src/app/features/call/CallControls.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useEffect, useRef, useState } from 'react'; +import { type MouseEventHandler, useCallback, useEffect, useRef, useState } from 'react'; import { Box, Button, @@ -9,14 +9,14 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Spinner, Text, toRem, } from 'folds'; import FocusTrap from 'focus-trap-react'; import { SequenceCard } from '$components/sequence-card'; -import { CallEmbed, useCallControlState } from '$plugins/call'; +import { type CallEmbed, useCallControlState } from '$plugins/call'; import { stopPropagation } from '$utils/keyboard'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useRoom } from '$hooks/useRoom'; diff --git a/src/app/features/call/CallMemberCard.tsx b/src/app/features/call/CallMemberCard.tsx index 7d03ac77b..0c4ca7601 100644 --- a/src/app/features/call/CallMemberCard.tsx +++ b/src/app/features/call/CallMemberCard.tsx @@ -1,4 +1,7 @@ -import { CallMembership, SessionMembershipData } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; +import { + type CallMembership, + type SessionMembershipData, +} from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; import { useState } from 'react'; import { Avatar, Box, Icon, Icons, Text } from 'folds'; import { useMatrixClient } from '../../hooks/useMatrixClient'; diff --git a/src/app/features/common-settings/cosmetics/Cosmetics.tsx b/src/app/features/common-settings/cosmetics/Cosmetics.tsx index be793be7b..2533c2b2c 100644 --- a/src/app/features/common-settings/cosmetics/Cosmetics.tsx +++ b/src/app/features/common-settings/cosmetics/Cosmetics.tsx @@ -1,7 +1,7 @@ import { - ChangeEvent, - ChangeEventHandler, - FormEventHandler, + type ChangeEvent, + type ChangeEventHandler, + type FormEventHandler, useCallback, useEffect, useMemo, @@ -41,14 +41,14 @@ import { SequenceCardStyle } from '$features/common-settings/styles.css'; import { UserAvatar } from '$components/user-avatar'; import { nameInitials } from '$utils/common'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; -import { UserProfile, useUserProfile } from '$hooks/useUserProfile'; +import { type UserProfile, useUserProfile } from '$hooks/useUserProfile'; import { getMxIdLocalPart, mxcUrlToHttp } from '$utils/matrix'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; -import { Room, RoomMember } from '$types/matrix-sdk'; +import { type Room, type RoomMember } from '$types/matrix-sdk'; import { Command, useCommands } from '$hooks/useCommands'; import { useCapabilities } from '$hooks/useCapabilities'; import { useObjectURL } from '$hooks/useObjectURL'; -import { createUploadAtom, UploadSuccess } from '$state/upload'; +import { createUploadAtom, type UploadSuccess } from '$state/upload'; import { useFilePicker } from '$hooks/useFilePicker'; import { CompactUploadCardRenderer } from '$components/upload-card'; import FocusTrap from 'focus-trap-react'; @@ -57,7 +57,7 @@ import { stopPropagation } from '$utils/keyboard'; import { ModalWide } from '$styles/Modal.css'; import { NameColorEditor } from '$features/settings/account/NameColorEditor'; import { PronounEditor } from '$features/settings/account/PronounEditor'; -import { PronounSet } from '$utils/pronouns'; +import { type PronounSet } from '$utils/pronouns'; const log = createLogger('Cosmetics'); diff --git a/src/app/features/common-settings/developer-tools/DevelopTools.tsx b/src/app/features/common-settings/developer-tools/DevelopTools.tsx index aec2f2ca7..705ab1983 100644 --- a/src/app/features/common-settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/common-settings/developer-tools/DevelopTools.tsx @@ -29,11 +29,11 @@ import { allRoomsAtom } from '$state/room-list/roomList'; import { allInvitesAtom } from '$state/room-list/inviteList'; import { isNotificationEvent } from '$utils/room'; import { CutoutCard } from '$components/cutout-card'; -import { AccountDataEditor, AccountDataSubmitCallback } from '$components/AccountDataEditor'; +import { AccountDataEditor, type AccountDataSubmitCallback } from '$components/AccountDataEditor'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { SequenceCardStyle } from '$features/common-settings/styles.css'; import { SendRoomEvent } from './SendRoomEvent'; -import { StateEventEditor, StateEventInfo } from './StateEventEditor'; +import { StateEventEditor, type StateEventInfo } from './StateEventEditor'; const formatSyncReason = (reason: string): string => { if (reason === 'sliding_active') return 'Sliding Sync active'; diff --git a/src/app/features/common-settings/developer-tools/SendRoomEvent.tsx b/src/app/features/common-settings/developer-tools/SendRoomEvent.tsx index b246b14b6..fd1a1cff0 100644 --- a/src/app/features/common-settings/developer-tools/SendRoomEvent.tsx +++ b/src/app/features/common-settings/developer-tools/SendRoomEvent.tsx @@ -1,5 +1,5 @@ -import { useCallback, useRef, useState, FormEventHandler, useEffect } from 'react'; -import { MatrixError } from '$types/matrix-sdk'; +import { useCallback, useRef, useState, type FormEventHandler, useEffect } from 'react'; +import { type MatrixError } from '$types/matrix-sdk'; import { Box, Chip, diff --git a/src/app/features/common-settings/developer-tools/StateEventEditor.tsx b/src/app/features/common-settings/developer-tools/StateEventEditor.tsx index 00bbd1125..fe69b5f62 100644 --- a/src/app/features/common-settings/developer-tools/StateEventEditor.tsx +++ b/src/app/features/common-settings/developer-tools/StateEventEditor.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { type FormEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Box, Text, @@ -13,13 +13,13 @@ import { Spinner, Button, } from 'folds'; -import { MatrixError } from '$types/matrix-sdk'; +import { type MatrixError } from '$types/matrix-sdk'; import { Page, PageHeader } from '$components/page'; import { SequenceCard } from '$components/sequence-card'; import { TextViewerContent } from '$components/text-viewer'; import { useStateEvent } from '$hooks/useStateEvent'; import { useRoom } from '$hooks/useRoom'; -import { StateEvent } from '$types/matrix/room'; +import { type StateEvent } from '$types/matrix/room'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useAlive } from '$hooks/useAlive'; import { Cursor } from '$plugins/text-area'; diff --git a/src/app/features/common-settings/emojis-stickers/EmojisStickers.tsx b/src/app/features/common-settings/emojis-stickers/EmojisStickers.tsx index 0ee350a69..6de76d7ac 100644 --- a/src/app/features/common-settings/emojis-stickers/EmojisStickers.tsx +++ b/src/app/features/common-settings/emojis-stickers/EmojisStickers.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { Box, Icon, IconButton, Icons, Scroll, Text } from 'folds'; import { Page, PageContent, PageHeader } from '$components/page'; -import { ImagePack } from '$plugins/custom-emoji'; +import { type ImagePack } from '$plugins/custom-emoji'; import { ImagePackView } from '$components/image-pack-view'; import { RoomPacks } from './RoomPacks'; diff --git a/src/app/features/common-settings/emojis-stickers/RoomPacks.tsx b/src/app/features/common-settings/emojis-stickers/RoomPacks.tsx index 6162e4c0b..6a9e05b35 100644 --- a/src/app/features/common-settings/emojis-stickers/RoomPacks.tsx +++ b/src/app/features/common-settings/emojis-stickers/RoomPacks.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useMemo, useState } from 'react'; +import { type FormEventHandler, useCallback, useMemo, useState } from 'react'; import { Box, Text, @@ -16,14 +16,14 @@ import { IconButton, Menu, } from 'folds'; -import { MatrixError } from '$types/matrix-sdk'; +import { type MatrixError } from '$types/matrix-sdk'; import { SequenceCard } from '$components/sequence-card'; import { - ImagePack, + type ImagePack, ImageUsage, - PackAddress, + type PackAddress, packAddressEqual, - PackContent, + type PackContent, } from '$plugins/custom-emoji'; import { useRoom } from '$hooks/useRoom'; import { useRoomImagePacks } from '$hooks/useImagePacks'; diff --git a/src/app/features/common-settings/general/RoomAddress.tsx b/src/app/features/common-settings/general/RoomAddress.tsx index f1ae66968..80e3247ab 100644 --- a/src/app/features/common-settings/general/RoomAddress.tsx +++ b/src/app/features/common-settings/general/RoomAddress.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useState } from 'react'; +import { type FormEventHandler, useCallback, useState } from 'react'; import { Badge, Box, @@ -14,7 +14,7 @@ import { Text, toRem, } from 'folds'; -import { MatrixError } from '$types/matrix-sdk'; +import { type MatrixError } from '$types/matrix-sdk'; import { SettingTile } from '$components/setting-tile'; import { SequenceCard } from '$components/sequence-card'; import { SequenceCardStyle } from '$features/room-settings/styles.css'; @@ -31,7 +31,7 @@ import { CutoutCard } from '$components/cutout-card'; import { replaceSpaceWithDash } from '$utils/common'; import { useAlive } from '$hooks/useAlive'; import { StateEvent } from '$types/matrix/room'; -import { RoomPermissionsAPI } from '$hooks/useRoomPermissions'; +import { type RoomPermissionsAPI } from '$hooks/useRoomPermissions'; import { getMxIdServer } from '$utils/matrix'; type RoomPublishedAddressesProps = { diff --git a/src/app/features/common-settings/general/RoomEncryption.tsx b/src/app/features/common-settings/general/RoomEncryption.tsx index 3dc87f840..dac24596f 100644 --- a/src/app/features/common-settings/general/RoomEncryption.tsx +++ b/src/app/features/common-settings/general/RoomEncryption.tsx @@ -16,7 +16,7 @@ import { Text, } from 'folds'; import { useCallback, useState } from 'react'; -import { MatrixError } from '$types/matrix-sdk'; +import { type MatrixError } from '$types/matrix-sdk'; import FocusTrap from 'focus-trap-react'; import { SequenceCard } from '$components/sequence-card'; import { SequenceCardStyle } from '$features/room-settings/styles.css'; @@ -27,7 +27,7 @@ import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useRoom } from '$hooks/useRoom'; import { useStateEvent } from '$hooks/useStateEvent'; import { stopPropagation } from '$utils/keyboard'; -import { RoomPermissionsAPI } from '$hooks/useRoomPermissions'; +import { type RoomPermissionsAPI } from '$hooks/useRoomPermissions'; const ROOM_ENC_ALGO = 'm.megolm.v1.aes-sha2'; diff --git a/src/app/features/common-settings/general/RoomHistoryVisibility.tsx b/src/app/features/common-settings/general/RoomHistoryVisibility.tsx index 2f93472e6..9671110e1 100644 --- a/src/app/features/common-settings/general/RoomHistoryVisibility.tsx +++ b/src/app/features/common-settings/general/RoomHistoryVisibility.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useMemo, useState } from 'react'; +import { type MouseEventHandler, useCallback, useMemo, useState } from 'react'; import { Button, color, @@ -8,14 +8,14 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Spinner, Text, } from 'folds'; import { HistoryVisibility, - MatrixError, - RoomHistoryVisibilityEventContent, + type MatrixError, + type RoomHistoryVisibilityEventContent, } from '$types/matrix-sdk'; import FocusTrap from 'focus-trap-react'; import { SequenceCard } from '$components/sequence-card'; @@ -27,7 +27,7 @@ import { StateEvent } from '$types/matrix/room'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useStateEvent } from '$hooks/useStateEvent'; import { stopPropagation } from '$utils/keyboard'; -import { RoomPermissionsAPI } from '$hooks/useRoomPermissions'; +import { type RoomPermissionsAPI } from '$hooks/useRoomPermissions'; const useVisibilityStr = () => useMemo( diff --git a/src/app/features/common-settings/general/RoomJoinRules.tsx b/src/app/features/common-settings/general/RoomJoinRules.tsx index 5a6c3697f..f69e194db 100644 --- a/src/app/features/common-settings/general/RoomJoinRules.tsx +++ b/src/app/features/common-settings/general/RoomJoinRules.tsx @@ -2,13 +2,13 @@ import { useCallback, useMemo } from 'react'; import { color, Text } from 'folds'; import { JoinRule, - MatrixError, + type MatrixError, RestrictedAllowType, - RoomJoinRulesEventContent, + type RoomJoinRulesEventContent, } from '$types/matrix-sdk'; import { useAtomValue } from 'jotai'; import { - ExtendedJoinRules, + type ExtendedJoinRules, JoinRulesSwitcher, useJoinRuleIcons, useRoomJoinRuleLabel, @@ -27,7 +27,7 @@ import { useRecursiveChildSpaceScopeFactory, useSpaceChildren } from '$state/hoo import { allRoomsAtom } from '$state/room-list/roomList'; import { roomToParentsAtom } from '$state/room/roomToParents'; import { knockRestrictedSupported, knockSupported, restrictedSupported } from '$utils/matrix'; -import { RoomPermissionsAPI } from '$hooks/useRoomPermissions'; +import { type RoomPermissionsAPI } from '$hooks/useRoomPermissions'; type RestrictedRoomAllowContent = { room_id: string; diff --git a/src/app/features/common-settings/general/RoomProfile.tsx b/src/app/features/common-settings/general/RoomProfile.tsx index cd523f32b..b6df8ec3d 100644 --- a/src/app/features/common-settings/general/RoomProfile.tsx +++ b/src/app/features/common-settings/general/RoomProfile.tsx @@ -11,11 +11,11 @@ import { Text, TextArea, } from 'folds'; -import { FormEventHandler, useCallback, useMemo, useState } from 'react'; +import { type FormEventHandler, useCallback, useMemo, useState } from 'react'; import { useAtomValue } from 'jotai'; import Linkify from 'linkify-react'; import classNames from 'classnames'; -import { JoinRule, MatrixError } from '$types/matrix-sdk'; +import { JoinRule, type MatrixError } from '$types/matrix-sdk'; import { SequenceCard } from '$components/sequence-card'; import { SequenceCardStyle } from '$features/room-settings/styles.css'; import { useRoom } from '$hooks/useRoom'; @@ -30,11 +30,11 @@ import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { StateEvent } from '$types/matrix/room'; import { CompactUploadCardRenderer } from '$components/upload-card'; import { useObjectURL } from '$hooks/useObjectURL'; -import { createUploadAtom, UploadSuccess } from '$state/upload'; +import { createUploadAtom, type UploadSuccess } from '$state/upload'; import { useFilePicker } from '$hooks/useFilePicker'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useAlive } from '$hooks/useAlive'; -import { RoomPermissionsAPI } from '$hooks/useRoomPermissions'; +import { type RoomPermissionsAPI } from '$hooks/useRoomPermissions'; type RoomProfileEditProps = { canEditAvatar: boolean; diff --git a/src/app/features/common-settings/general/RoomPublish.tsx b/src/app/features/common-settings/general/RoomPublish.tsx index a4aa47d2a..5739cc5ee 100644 --- a/src/app/features/common-settings/general/RoomPublish.tsx +++ b/src/app/features/common-settings/general/RoomPublish.tsx @@ -1,5 +1,5 @@ import { Box, color, Spinner, Switch, Text } from 'folds'; -import { JoinRule, MatrixError, RoomJoinRulesEventContent } from '$types/matrix-sdk'; +import { JoinRule, type MatrixError, type RoomJoinRulesEventContent } from '$types/matrix-sdk'; import { SequenceCard } from '$components/sequence-card'; import { SequenceCardStyle } from '$features/room-settings/styles.css'; import { SettingTile } from '$components/setting-tile'; @@ -9,8 +9,8 @@ import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { StateEvent } from '$types/matrix/room'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useStateEvent } from '$hooks/useStateEvent'; -import { ExtendedJoinRules } from '$components/JoinRulesSwitcher'; -import { RoomPermissionsAPI } from '$hooks/useRoomPermissions'; +import { type ExtendedJoinRules } from '$components/JoinRulesSwitcher'; +import { type RoomPermissionsAPI } from '$hooks/useRoomPermissions'; type RoomPublishProps = { permissions: RoomPermissionsAPI; diff --git a/src/app/features/common-settings/general/RoomUpgrade.tsx b/src/app/features/common-settings/general/RoomUpgrade.tsx index 073465688..ac738ff77 100644 --- a/src/app/features/common-settings/general/RoomUpgrade.tsx +++ b/src/app/features/common-settings/general/RoomUpgrade.tsx @@ -16,19 +16,19 @@ import { Icons, } from 'folds'; import FocusTrap from 'focus-trap-react'; -import { MatrixError, Method, RoomTombstoneEventContent } from '$types/matrix-sdk'; +import { type MatrixError, Method, type RoomTombstoneEventContent } from '$types/matrix-sdk'; import { SequenceCard } from '$components/sequence-card'; import { SequenceCardStyle } from '$features/room-settings/styles.css'; import { SettingTile } from '$components/setting-tile'; import { useRoom } from '$hooks/useRoom'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; -import { IRoomCreateContent, StateEvent } from '$types/matrix/room'; +import { type IRoomCreateContent, StateEvent } from '$types/matrix/room'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useStateEvent } from '$hooks/useStateEvent'; import { useRoomNavigate } from '$hooks/useRoomNavigate'; import { useCapabilities } from '$hooks/useCapabilities'; import { stopPropagation } from '$utils/keyboard'; -import { RoomPermissionsAPI } from '$hooks/useRoomPermissions'; +import { type RoomPermissionsAPI } from '$hooks/useRoomPermissions'; import { AdditionalCreatorInput, RoomVersionSelector, diff --git a/src/app/features/common-settings/members/Members.tsx b/src/app/features/common-settings/members/Members.tsx index 19b8ffc46..6a7abc10f 100644 --- a/src/app/features/common-settings/members/Members.tsx +++ b/src/app/features/common-settings/members/Members.tsx @@ -1,6 +1,6 @@ import { - ChangeEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type MouseEventHandler, useCallback, useMemo, useRef, @@ -15,14 +15,14 @@ import { Icons, Input, PopOut, - RectCords, + type RectCords, Scroll, Spinner, Text, toRem, } from 'folds'; import { useVirtualizer } from '@tanstack/react-virtual'; -import { RoomMember } from '$types/matrix-sdk'; +import { type RoomMember } from '$types/matrix-sdk'; import { Page, PageContent, PageHeader } from '$components/page'; import { useRoom } from '$hooks/useRoom'; import { useRoomMembers } from '$hooks/useRoomMembers'; @@ -34,7 +34,11 @@ import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { getMxIdLocalPart, getMxIdServer } from '$utils/matrix'; import { ServerBadge } from '$components/server-badge'; import { useDebounce } from '$hooks/useDebounce'; -import { SearchItemStrGetter, useAsyncSearch, UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; +import { + type SearchItemStrGetter, + useAsyncSearch, + type UseAsyncSearchOptions, +} from '$hooks/useAsyncSearch'; import { getMemberSearchStr } from '$utils/room'; import { useMembershipFilter, useMembershipFilterMenu } from '$hooks/useMemberFilter'; import { useMemberPowerSort, useMemberSort, useMemberSortMenu } from '$hooks/useMemberSort'; diff --git a/src/app/features/common-settings/permissions/PermissionGroups.tsx b/src/app/features/common-settings/permissions/PermissionGroups.tsx index 324005819..b29c788e1 100644 --- a/src/app/features/common-settings/permissions/PermissionGroups.tsx +++ b/src/app/features/common-settings/permissions/PermissionGroups.tsx @@ -7,8 +7,8 @@ import { SettingTile } from '$components/setting-tile'; import { applyPermissionPower, getPermissionPower, - IPowerLevels, - PermissionLocation, + type IPowerLevels, + type PermissionLocation, } from '$hooks/usePowerLevels'; import { getPowerLevelTag, getPowers, usePowerLevelTags } from '$hooks/usePowerLevelTags'; import { useRoom } from '$hooks/useRoom'; @@ -18,7 +18,7 @@ import { PowerSwitcher } from '$components/power'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useAlive } from '$hooks/useAlive'; import { SequenceCardStyle } from '$features/common-settings/styles.css'; -import { PermissionGroup } from './types'; +import { type PermissionGroup } from './types'; const USER_DEFAULT_LOCATION: PermissionLocation = { user: true, diff --git a/src/app/features/common-settings/permissions/Powers.tsx b/src/app/features/common-settings/permissions/Powers.tsx index a029ac785..ce1d03674 100644 --- a/src/app/features/common-settings/permissions/Powers.tsx +++ b/src/app/features/common-settings/permissions/Powers.tsx @@ -1,12 +1,12 @@ /* eslint-disable react/no-array-index-key */ -import { useState, MouseEventHandler, ReactNode } from 'react'; +import { useState, type MouseEventHandler, type ReactNode } from 'react'; import FocusTrap from 'focus-trap-react'; import { Box, Button, Chip, Text, - RectCords, + type RectCords, PopOut, Menu, Scroll, @@ -17,7 +17,7 @@ import { import { SequenceCard } from '$components/sequence-card'; import { getPowers, usePowerLevelTags } from '$hooks/usePowerLevelTags'; import { SettingTile } from '$components/setting-tile'; -import { getPermissionPower, IPowerLevels } from '$hooks/usePowerLevels'; +import { getPermissionPower, type IPowerLevels } from '$hooks/usePowerLevels'; import { useRoom } from '$hooks/useRoom'; import { PowerColorBadge, PowerIcon } from '$components/power'; import { useMatrixClient } from '$hooks/useMatrixClient'; @@ -27,7 +27,7 @@ import { getPowerTagIconSrc } from '$hooks/useMemberPowerTag'; import { useRoomCreatorsTag } from '$hooks/useRoomCreatorsTag'; import { useRoomCreators } from '$hooks/useRoomCreators'; import { SequenceCardStyle } from '$features/common-settings/styles.css'; -import { PermissionGroup } from './types'; +import { type PermissionGroup } from './types'; type PeekPermissionsProps = { powerLevels: IPowerLevels; diff --git a/src/app/features/common-settings/permissions/PowersEditor.tsx b/src/app/features/common-settings/permissions/PowersEditor.tsx index f53f3a237..06cfd8337 100644 --- a/src/app/features/common-settings/permissions/PowersEditor.tsx +++ b/src/app/features/common-settings/permissions/PowersEditor.tsx @@ -1,4 +1,10 @@ -import { FormEventHandler, MouseEventHandler, useCallback, useMemo, useState } from 'react'; +import { + type FormEventHandler, + type MouseEventHandler, + useCallback, + useMemo, + useState, +} from 'react'; import { Box, Text, @@ -9,7 +15,7 @@ import { Scroll, Button, Input, - RectCords, + type RectCords, PopOut, Menu, config, @@ -21,13 +27,13 @@ import { import { HexColorPicker } from 'react-colorful'; import { useAtomValue } from 'jotai'; import { Page, PageContent, PageHeader } from '$components/page'; -import { IPowerLevels } from '$hooks/usePowerLevels'; +import { type IPowerLevels } from '$hooks/usePowerLevels'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; import { getPowers, getUsedPowers, - PowerLevelTags, + type PowerLevelTags, usePowerLevelTags, } from '$hooks/usePowerLevelTags'; import { useRoom } from '$hooks/useRoom'; @@ -41,9 +47,9 @@ import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useFilePicker } from '$hooks/useFilePicker'; import { CompactUploadCardRenderer } from '$components/upload-card'; -import { createUploadAtom, UploadSuccess } from '$state/upload'; +import { createUploadAtom, type UploadSuccess } from '$state/upload'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; -import { MemberPowerTag, MemberPowerTagIcon, StateEvent } from '$types/matrix/room'; +import { type MemberPowerTag, type MemberPowerTagIcon, StateEvent } from '$types/matrix/room'; import { useAlive } from '$hooks/useAlive'; import { BetaNoticeBadge } from '$components/BetaNoticeBadge'; import { getPowerTagIconSrc } from '$hooks/useMemberPowerTag'; diff --git a/src/app/features/common-settings/permissions/types.ts b/src/app/features/common-settings/permissions/types.ts index 5d5eaa35d..1f47aa452 100644 --- a/src/app/features/common-settings/permissions/types.ts +++ b/src/app/features/common-settings/permissions/types.ts @@ -1,4 +1,4 @@ -import { PermissionLocation } from '$hooks/usePowerLevels'; +import { type PermissionLocation } from '$hooks/usePowerLevels'; export type PermissionItem = { location: PermissionLocation; diff --git a/src/app/features/create-chat/CreateChat.tsx b/src/app/features/create-chat/CreateChat.tsx index 225ef9b64..c862718b6 100644 --- a/src/app/features/create-chat/CreateChat.tsx +++ b/src/app/features/create-chat/CreateChat.tsx @@ -1,6 +1,6 @@ import { Box, Button, color, config, Icon, Icons, Input, Spinner, Switch, Text } from 'folds'; -import { FormEventHandler, useCallback, useState } from 'react'; -import { ICreateRoomStateEvent, MatrixError, Preset, Visibility } from '$types/matrix-sdk'; +import { type FormEventHandler, useCallback, useState } from 'react'; +import { type ICreateRoomStateEvent, MatrixError, Preset, Visibility } from '$types/matrix-sdk'; import { useNavigate } from 'react-router-dom'; import { SettingTile } from '$components/setting-tile'; import { SequenceCard } from '$components/sequence-card'; diff --git a/src/app/features/create-room/CreateRoom.tsx b/src/app/features/create-room/CreateRoom.tsx index 7347ba586..1f5692018 100644 --- a/src/app/features/create-room/CreateRoom.tsx +++ b/src/app/features/create-room/CreateRoom.tsx @@ -1,5 +1,5 @@ -import { FormEventHandler, useCallback, useEffect, useState } from 'react'; -import { MatrixError, Room, JoinRule } from '$types/matrix-sdk'; +import { type FormEventHandler, useCallback, useEffect, useState } from 'react'; +import { MatrixError, type Room, JoinRule } from '$types/matrix-sdk'; import { Box, Button, @@ -31,7 +31,7 @@ import { AdditionalCreatorInput, createRoom, CreateRoomAliasInput, - CreateRoomData, + type CreateRoomData, CreateRoomAccess, CreateRoomAccessSelector, RoomVersionSelector, diff --git a/src/app/features/create-room/CreateRoomModal.tsx b/src/app/features/create-room/CreateRoomModal.tsx index ad613a520..7297ab150 100644 --- a/src/app/features/create-room/CreateRoomModal.tsx +++ b/src/app/features/create-room/CreateRoomModal.tsx @@ -16,7 +16,7 @@ import FocusTrap from 'focus-trap-react'; import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom'; import { SpaceProvider } from '$hooks/useSpace'; import { useCloseCreateRoomModal, useCreateRoomModalState } from '$state/hooks/createRoomModal'; -import { CreateRoomModalState } from '$state/createRoomModal'; +import { type CreateRoomModalState } from '$state/createRoomModal'; import { stopPropagation } from '$utils/keyboard'; import { CreateRoomType } from '$components/create-room/types'; import { CreateRoomForm } from './CreateRoom'; diff --git a/src/app/features/create-space/CreateSpace.tsx b/src/app/features/create-space/CreateSpace.tsx index 2fbeb198b..e1de7d25c 100644 --- a/src/app/features/create-space/CreateSpace.tsx +++ b/src/app/features/create-space/CreateSpace.tsx @@ -1,5 +1,5 @@ -import { FormEventHandler, useCallback, useEffect, useState } from 'react'; -import { MatrixError, Room } from '$types/matrix-sdk'; +import { type FormEventHandler, useCallback, useEffect, useState } from 'react'; +import { MatrixError, type Room } from '$types/matrix-sdk'; import { Box, Button, @@ -31,7 +31,7 @@ import { AdditionalCreatorInput, createRoom, CreateRoomAliasInput, - CreateRoomData, + type CreateRoomData, CreateRoomAccess, CreateRoomAccessSelector, RoomVersionSelector, diff --git a/src/app/features/create-space/CreateSpaceModal.tsx b/src/app/features/create-space/CreateSpaceModal.tsx index 3ef0da51f..effa38bdd 100644 --- a/src/app/features/create-space/CreateSpaceModal.tsx +++ b/src/app/features/create-space/CreateSpaceModal.tsx @@ -16,7 +16,7 @@ import FocusTrap from 'focus-trap-react'; import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom'; import { SpaceProvider } from '$hooks/useSpace'; import { useCloseCreateSpaceModal, useCreateSpaceModalState } from '$state/hooks/createSpaceModal'; -import { CreateSpaceModalState } from '$state/createSpaceModal'; +import { type CreateSpaceModalState } from '$state/createSpaceModal'; import { stopPropagation } from '$utils/keyboard'; import { CreateSpaceForm } from './CreateSpace'; diff --git a/src/app/features/lobby/DnD.tsx b/src/app/features/lobby/DnD.tsx index fa4584a40..3c6f46d7e 100644 --- a/src/app/features/lobby/DnD.tsx +++ b/src/app/features/lobby/DnD.tsx @@ -1,4 +1,4 @@ -import { RefObject, useEffect, useRef, useState } from 'react'; +import { type RefObject, useEffect, useRef, useState } from 'react'; import { dropTargetForElements, draggable, @@ -8,7 +8,7 @@ import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-sc import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine'; import classNames from 'classnames'; import { Box, Icon, Icons, as } from 'folds'; -import { HierarchyItem } from '$hooks/useSpaceHierarchy'; +import { type HierarchyItem } from '$hooks/useSpaceHierarchy'; import * as css from './DnD.css'; export type DropContainerData = { diff --git a/src/app/features/lobby/HierarchyItemMenu.tsx b/src/app/features/lobby/HierarchyItemMenu.tsx index 1377f33ff..6ffac6de8 100644 --- a/src/app/features/lobby/HierarchyItemMenu.tsx +++ b/src/app/features/lobby/HierarchyItemMenu.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useEffect, useState } from 'react'; +import { type MouseEventHandler, useCallback, useEffect, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { Box, @@ -9,15 +9,15 @@ import { Menu, MenuItem, Text, - RectCords, + type RectCords, config, Line, Spinner, toRem, } from 'folds'; -import { HierarchyItem } from '$hooks/useSpaceHierarchy'; +import { type HierarchyItem } from '$hooks/useSpaceHierarchy'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { MSpaceChildContent, StateEvent } from '$types/matrix/room'; +import { type MSpaceChildContent, StateEvent } from '$types/matrix/room'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { UseStateProvider } from '$components/UseStateProvider'; import { LeaveSpacePrompt } from '$components/leave-space-prompt'; @@ -26,7 +26,7 @@ import { stopPropagation } from '$utils/keyboard'; import { useOpenRoomSettings } from '$state/hooks/roomSettings'; import { useSpaceOptionally } from '$hooks/useSpace'; import { useOpenSpaceSettings } from '$state/hooks/spaceSettings'; -import { IPowerLevels } from '$hooks/usePowerLevels'; +import { type IPowerLevels } from '$hooks/usePowerLevels'; import { getRoomCreatorsForRoomId } from '$hooks/useRoomCreators'; import { getRoomPermissionsAPI } from '$hooks/useRoomPermissions'; import { InviteUserPrompt } from '$components/invite-user-prompt'; diff --git a/src/app/features/lobby/Lobby.tsx b/src/app/features/lobby/Lobby.tsx index c980db462..7c9213bad 100644 --- a/src/app/features/lobby/Lobby.tsx +++ b/src/app/features/lobby/Lobby.tsx @@ -1,6 +1,6 @@ import { - MouseEventHandler, - ReactElement, + type MouseEventHandler, + type ReactElement, useCallback, useEffect, useMemo, @@ -20,20 +20,24 @@ import { color, config, } from 'folds'; -import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual'; +import { useVirtualizer, type VirtualItem } from '@tanstack/react-virtual'; import { useAtom, useAtomValue } from 'jotai'; import { useNavigate } from 'react-router-dom'; import { JoinRule, RestrictedAllowType, - Room, - RoomJoinRulesEventContent, - IHierarchyRoom, + type Room, + type RoomJoinRulesEventContent, + type IHierarchyRoom, } from '$types/matrix-sdk'; import { produce } from 'immer'; import { useSpace } from '$hooks/useSpace'; import { Page, PageContent, PageContentCenter, PageHeroSection } from '$components/page'; -import { HierarchyItem, HierarchyItemSpace, useSpaceHierarchy } from '$hooks/useSpaceHierarchy'; +import { + type HierarchyItem, + type HierarchyItemSpace, + useSpaceHierarchy, +} from '$hooks/useSpaceHierarchy'; import { VirtualTile } from '$components/virtualizer'; import { spaceRoomsAtom } from '$state/spaceRooms'; import { useSetting } from '$state/hooks/settings'; @@ -42,7 +46,7 @@ import { settingsAtom } from '$state/settings'; import { ScrollTopContainer } from '$components/scroll-top-container'; import { useElementSizeObserver } from '$hooks/useElementSizeObserver'; import { - IPowerLevels, + type IPowerLevels, PowerLevelsContextProvider, usePowerLevels, useRoomsPowerLevels, @@ -73,7 +77,7 @@ import { getRoomPermissionsAPI } from '$hooks/useRoomPermissions'; import { getRoomCreatorsForRoomId } from '$hooks/useRoomCreators'; import { MembersDrawer } from '$features/room/MembersDrawer'; import { SpaceHierarchyItem } from './SpaceHierarchyItem'; -import { CanDropCallback, useDnDMonitor } from './DnD'; +import { type CanDropCallback, useDnDMonitor } from './DnD'; import { LobbyHero } from './LobbyHero'; import { LobbyHeader } from './LobbyHeader'; import { SpaceHierarchyNavItem } from './SpaceHierarchyNavItem'; diff --git a/src/app/features/lobby/LobbyHeader.tsx b/src/app/features/lobby/LobbyHeader.tsx index 4c3ba7447..d64673b79 100644 --- a/src/app/features/lobby/LobbyHeader.tsx +++ b/src/app/features/lobby/LobbyHeader.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, forwardRef, useState } from 'react'; +import { type MouseEventHandler, forwardRef, useState } from 'react'; import { Avatar, Box, @@ -9,7 +9,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Text, Tooltip, TooltipProvider, @@ -25,7 +25,7 @@ import { useSpace } from '$hooks/useSpace'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { RoomAvatar } from '$components/room-avatar'; import { nameInitials } from '$utils/common'; -import { IPowerLevels } from '$hooks/usePowerLevels'; +import { type IPowerLevels } from '$hooks/usePowerLevels'; import { UseStateProvider } from '$components/UseStateProvider'; import { LeaveSpacePrompt } from '$components/leave-space-prompt'; import { stopPropagation } from '$utils/keyboard'; diff --git a/src/app/features/lobby/RoomItem.tsx b/src/app/features/lobby/RoomItem.tsx index 090871c7b..13addce24 100644 --- a/src/app/features/lobby/RoomItem.tsx +++ b/src/app/features/lobby/RoomItem.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, ReactNode, useCallback, useRef } from 'react'; +import { type MouseEventHandler, type ReactNode, useCallback, useRef } from 'react'; import { Avatar, Badge, @@ -19,11 +19,11 @@ import { toRem, } from 'folds'; import FocusTrap from 'focus-trap-react'; -import { JoinRule, MatrixError, Room, IHierarchyRoom } from '$types/matrix-sdk'; +import { JoinRule, type MatrixError, type Room, type IHierarchyRoom } from '$types/matrix-sdk'; import { RoomAvatar, RoomIcon } from '$components/room-avatar'; import { SequenceCard } from '$components/sequence-card'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { HierarchyItem } from '$hooks/useSpaceHierarchy'; +import { type HierarchyItem } from '$hooks/useSpaceHierarchy'; import { KnockRoomPrompt } from '$components/knock-room-prompt'; import { LocalRoomSummaryLoader } from '$components/RoomSummaryLoader'; import { UseStateProvider } from '$components/UseStateProvider'; diff --git a/src/app/features/lobby/SpaceHierarchyItem.tsx b/src/app/features/lobby/SpaceHierarchyItem.tsx index 2797be88e..917f25de8 100644 --- a/src/app/features/lobby/SpaceHierarchyItem.tsx +++ b/src/app/features/lobby/SpaceHierarchyItem.tsx @@ -1,20 +1,20 @@ -import { forwardRef, MouseEventHandler, useEffect, useMemo } from 'react'; -import { MatrixError, Room, IHierarchyRoom } from '$types/matrix-sdk'; +import { forwardRef, type MouseEventHandler, useEffect, useMemo } from 'react'; +import { MatrixError, type Room, type IHierarchyRoom } from '$types/matrix-sdk'; import { Box, config, Text } from 'folds'; import { - HierarchyItem, - HierarchyItemRoom, - HierarchyItemSpace, + type HierarchyItem, + type HierarchyItemRoom, + type HierarchyItemSpace, useFetchSpaceHierarchyLevel, } from '$hooks/useSpaceHierarchy'; -import { IPowerLevels } from '$hooks/usePowerLevels'; +import { type IPowerLevels } from '$hooks/usePowerLevels'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { RoomType, StateEvent } from '$types/matrix/room'; import { SequenceCard } from '$components/sequence-card'; import { getRoomCreatorsForRoomId } from '$hooks/useRoomCreators'; import { getRoomPermissionsAPI } from '$hooks/useRoomPermissions'; import { SpaceItemCard } from './SpaceItem'; -import { AfterItemDropTarget, CanDropCallback } from './DnD'; +import { AfterItemDropTarget, type CanDropCallback } from './DnD'; import { HierarchyItemMenu } from './HierarchyItemMenu'; import { RoomItemCard } from './RoomItem'; diff --git a/src/app/features/lobby/SpaceHierarchyNavItem.tsx b/src/app/features/lobby/SpaceHierarchyNavItem.tsx index def804f62..0a4f3c03e 100644 --- a/src/app/features/lobby/SpaceHierarchyNavItem.tsx +++ b/src/app/features/lobby/SpaceHierarchyNavItem.tsx @@ -1,13 +1,13 @@ import { forwardRef } from 'react'; -import { Room, IHierarchyRoom } from '$types/matrix-sdk'; +import { type Room, type IHierarchyRoom } from '$types/matrix-sdk'; import { Box } from 'folds'; -import { HierarchyItem, HierarchyItemSpace } from '$hooks/useSpaceHierarchy'; -import { IPowerLevels } from '$hooks/usePowerLevels'; +import { type HierarchyItem, type HierarchyItemSpace } from '$hooks/useSpaceHierarchy'; +import { type IPowerLevels } from '$hooks/usePowerLevels'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { StateEvent } from '$types/matrix/room'; import { getRoomCreatorsForRoomId } from '$hooks/useRoomCreators'; import { getRoomPermissionsAPI } from '$hooks/useRoomPermissions'; -import { AfterItemDropTarget, CanDropCallback } from './DnD'; +import { AfterItemDropTarget, type CanDropCallback } from './DnD'; import { HierarchyItemMenu } from './HierarchyItemMenu'; import { SpaceNavItemCard } from './SpaceNavItem'; diff --git a/src/app/features/lobby/SpaceItem.tsx b/src/app/features/lobby/SpaceItem.tsx index 3a95049d7..09c05e914 100644 --- a/src/app/features/lobby/SpaceItem.tsx +++ b/src/app/features/lobby/SpaceItem.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, ReactNode, useCallback, useRef, useState } from 'react'; +import { type MouseEventHandler, type ReactNode, useCallback, useRef, useState } from 'react'; import { Box, Avatar, @@ -14,11 +14,11 @@ import { config, Menu, MenuItem, - RectCords, + type RectCords, } from 'folds'; import classNames from 'classnames'; -import { MatrixError, Room, IHierarchyRoom } from '$types/matrix-sdk'; -import { HierarchyItem } from '$hooks/useSpaceHierarchy'; +import { type MatrixError, type Room, type IHierarchyRoom } from '$types/matrix-sdk'; +import { type HierarchyItem } from '$hooks/useSpaceHierarchy'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { RoomAvatar } from '$components/room-avatar'; import { nameInitials } from '$utils/common'; diff --git a/src/app/features/lobby/SpaceNavItem.tsx b/src/app/features/lobby/SpaceNavItem.tsx index c07ce6cbc..e7f01e9dc 100644 --- a/src/app/features/lobby/SpaceNavItem.tsx +++ b/src/app/features/lobby/SpaceNavItem.tsx @@ -1,11 +1,11 @@ -import { ReactNode, useRef } from 'react'; +import { type ReactNode, useRef } from 'react'; import { Avatar, Badge, Box, Chip, Icon, Icons, as, Text } from 'folds'; import classNames from 'classnames'; -import { IHierarchyRoom, MatrixClient, Room } from '$types/matrix-sdk'; +import { type IHierarchyRoom, type MatrixClient, type Room } from '$types/matrix-sdk'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { getCanonicalAliasOrRoomId, mxcUrlToHttp } from '$utils/matrix'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; -import { HierarchyItem } from '$hooks/useSpaceHierarchy'; +import { type HierarchyItem } from '$hooks/useSpaceHierarchy'; import { LocalRoomSummaryLoader } from '$components/RoomSummaryLoader'; import { getRoomAvatarUrl } from '$utils/room'; import { RoomAvatar } from '$components/room-avatar'; diff --git a/src/app/features/message-search/MessageSearch.tsx b/src/app/features/message-search/MessageSearch.tsx index db9191725..443d6a20c 100644 --- a/src/app/features/message-search/MessageSearch.tsx +++ b/src/app/features/message-search/MessageSearch.tsx @@ -1,4 +1,4 @@ -import { RefObject, useEffect, useMemo, useRef } from 'react'; +import { type RefObject, useEffect, useMemo, useRef } from 'react'; import { Text, Box, Icon, Icons, config, Spinner, IconButton, Line, toRem } from 'folds'; import { useAtomValue } from 'jotai'; import { useVirtualizer } from '@tanstack/react-virtual'; @@ -7,7 +7,7 @@ import { useSearchParams } from 'react-router-dom'; import { SearchOrderBy } from '$types/matrix-sdk'; import { PageHero, PageHeroEmpty, PageHeroSection } from '$components/page'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { SearchPathSearchParams } from '$pages/paths'; +import { type SearchPathSearchParams } from '$pages/paths'; import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { SequenceCard } from '$components/sequence-card'; @@ -19,7 +19,7 @@ import { useRooms } from '$state/hooks/roomList'; import { allRoomsAtom } from '$state/room-list/roomList'; import { mDirectAtom } from '$state/mDirectList'; import { VirtualTile } from '$components/virtualizer'; -import { MessageSearchParams, useMessageSearch } from './useMessageSearch'; +import { type MessageSearchParams, useMessageSearch } from './useMessageSearch'; import { SearchResultGroup } from './SearchResultGroup'; import { SearchInput } from './SearchInput'; import { SearchFilters } from './SearchFilters'; diff --git a/src/app/features/message-search/SearchFilters.tsx b/src/app/features/message-search/SearchFilters.tsx index 4c1abd75d..57a8e31af 100644 --- a/src/app/features/message-search/SearchFilters.tsx +++ b/src/app/features/message-search/SearchFilters.tsx @@ -1,6 +1,6 @@ import { - ChangeEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type MouseEventHandler, useCallback, useEffect, useRef, @@ -23,7 +23,7 @@ import { Button, Input, Badge, - RectCords, + type RectCords, } from 'folds'; import { SearchOrderBy } from '$types/matrix-sdk'; import FocusTrap from 'focus-trap-react'; @@ -31,8 +31,12 @@ import { useVirtualizer } from '@tanstack/react-virtual'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { getRoomIconSrc } from '$utils/room'; import { factoryRoomIdByAtoZ } from '$utils/sort'; -import { SearchItemStrGetter, UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; -import { DebounceOptions, useDebounce } from '$hooks/useDebounce'; +import { + type SearchItemStrGetter, + type UseAsyncSearchOptions, + useAsyncSearch, +} from '$hooks/useAsyncSearch'; +import { type DebounceOptions, useDebounce } from '$hooks/useDebounce'; import { VirtualTile } from '$components/virtualizer'; import { stopPropagation } from '$utils/keyboard'; diff --git a/src/app/features/message-search/SearchInput.tsx b/src/app/features/message-search/SearchInput.tsx index ad1ca593d..de927c277 100644 --- a/src/app/features/message-search/SearchInput.tsx +++ b/src/app/features/message-search/SearchInput.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, RefObject } from 'react'; +import { type FormEventHandler, type RefObject } from 'react'; import { Box, Text, Input, Icon, Icons, Spinner, Chip, config } from 'folds'; type SearchProps = { diff --git a/src/app/features/message-search/SearchResultGroup.tsx b/src/app/features/message-search/SearchResultGroup.tsx index 7e4bcf533..85487ffe7 100644 --- a/src/app/features/message-search/SearchResultGroup.tsx +++ b/src/app/features/message-search/SearchResultGroup.tsx @@ -1,9 +1,9 @@ /* eslint-disable react/destructuring-assignment */ -import { MouseEventHandler, useMemo } from 'react'; -import { IEventWithRoomId, JoinRule, RelationType, Room } from '$types/matrix-sdk'; -import { HTMLReactParserOptions } from 'html-react-parser'; +import { type MouseEventHandler, useMemo } from 'react'; +import { type IEventWithRoomId, JoinRule, RelationType, type Room } from '$types/matrix-sdk'; +import { type HTMLReactParserOptions } from 'html-react-parser'; import { Avatar, Box, Chip, Header, Icon, Icons, Text, config } from 'folds'; -import { Opts as LinkifyOpts } from 'linkifyjs'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { factoryRenderLinkifyWithMention, @@ -15,7 +15,7 @@ import { } from '$plugins/react-custom-html-parser'; import { getMxIdLocalPart, mxcUrlToHttp } from '$utils/matrix'; import { useMatrixEventRenderer } from '$hooks/useMatrixEventRenderer'; -import { GetContentCallback, MessageEvent, StateEvent } from '$types/matrix/room'; +import { type GetContentCallback, MessageEvent, StateEvent } from '$types/matrix/room'; import { AvatarBase, ImageContent, @@ -52,7 +52,7 @@ import { } from '$hooks/useMemberPowerTag'; import { useRoomCreators } from '$hooks/useRoomCreators'; import { useRoomCreatorsTag } from '$hooks/useRoomCreatorsTag'; -import { ResultItem } from './useMessageSearch'; +import { type ResultItem } from './useMessageSearch'; type SearchResultGroupProps = { room: Room; diff --git a/src/app/features/message-search/useMessageSearch.ts b/src/app/features/message-search/useMessageSearch.ts index de1b15585..a0349531e 100644 --- a/src/app/features/message-search/useMessageSearch.ts +++ b/src/app/features/message-search/useMessageSearch.ts @@ -1,10 +1,10 @@ import { - IEventWithRoomId, - IResultContext, - ISearchRequestBody, - ISearchResponse, - ISearchResult, - SearchOrderBy, + type IEventWithRoomId, + type IResultContext, + type ISearchRequestBody, + type ISearchResponse, + type ISearchResult, + type SearchOrderBy, } from '$types/matrix-sdk'; import { useCallback } from 'react'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/features/room-nav/RoomNavItem.tsx b/src/app/features/room-nav/RoomNavItem.tsx index f9d279062..b73603bb3 100644 --- a/src/app/features/room-nav/RoomNavItem.tsx +++ b/src/app/features/room-nav/RoomNavItem.tsx @@ -1,5 +1,5 @@ -import { MouseEventHandler, forwardRef, useState, MouseEvent, useEffect } from 'react'; -import { Room, RoomEvent as RoomEventEnum } from '$types/matrix-sdk'; +import { type MouseEventHandler, forwardRef, useState, type MouseEvent, useEffect } from 'react'; +import { type Room, RoomEvent as RoomEventEnum } from '$types/matrix-sdk'; import { Avatar, Box, @@ -13,7 +13,7 @@ import { PopOut, toRem, Line, - RectCords, + type RectCords, Badge, Spinner, Tooltip, diff --git a/src/app/features/room-nav/RoomNavUser.tsx b/src/app/features/room-nav/RoomNavUser.tsx index 7d25d7bf9..ed62ced95 100644 --- a/src/app/features/room-nav/RoomNavUser.tsx +++ b/src/app/features/room-nav/RoomNavUser.tsx @@ -1,7 +1,7 @@ import { Avatar, Box, Icon, Icons, Text } from 'folds'; -import { MouseEventHandler } from 'react'; +import { type MouseEventHandler } from 'react'; import { useAtomValue } from 'jotai'; -import { Room, CallMembership } from '$types/matrix-sdk'; +import { type Room, type CallMembership } from '$types/matrix-sdk'; import { NavButton, NavItem, NavItemContent } from '$components/nav'; import { UserAvatar } from '$components/user-avatar'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/features/room-settings/RoomSettings.tsx b/src/app/features/room-settings/RoomSettings.tsx index 02fb0e849..7b205c0e5 100644 --- a/src/app/features/room-settings/RoomSettings.tsx +++ b/src/app/features/room-settings/RoomSettings.tsx @@ -1,6 +1,6 @@ import { useMemo, useState } from 'react'; import { useAtomValue } from 'jotai'; -import { Avatar, Box, config, Icon, IconButton, Icons, IconSrc, MenuItem, Text } from 'folds'; +import { Avatar, Box, config, Icon, IconButton, Icons, type IconSrc, MenuItem, Text } from 'folds'; import { JoinRule } from '$types/matrix-sdk'; import { PageNav, PageNavContent, PageNavHeader, PageRoot } from '$components/page'; import { ScreenSize, useScreenSizeContext } from '$hooks/useScreenSize'; diff --git a/src/app/features/room-settings/RoomSettingsRenderer.tsx b/src/app/features/room-settings/RoomSettingsRenderer.tsx index 7f2e53e79..d9dcbecf6 100644 --- a/src/app/features/room-settings/RoomSettingsRenderer.tsx +++ b/src/app/features/room-settings/RoomSettingsRenderer.tsx @@ -1,7 +1,7 @@ import { Modal500 } from '$components/Modal500'; import { useCloseRoomSettings, useRoomSettingsState } from '$state/hooks/roomSettings'; import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom'; -import { RoomSettingsState } from '$state/roomSettings'; +import { type RoomSettingsState } from '$state/roomSettings'; import { RoomProvider } from '$hooks/useRoom'; import { SpaceProvider } from '$hooks/useSpace'; import { RoomSettings } from './RoomSettings'; diff --git a/src/app/features/room-settings/abbreviations/RoomAbbreviations.tsx b/src/app/features/room-settings/abbreviations/RoomAbbreviations.tsx index 1354f5691..333c06b36 100644 --- a/src/app/features/room-settings/abbreviations/RoomAbbreviations.tsx +++ b/src/app/features/room-settings/abbreviations/RoomAbbreviations.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useMemo } from 'react'; +import { type FormEventHandler, useCallback, useMemo } from 'react'; import { useAtomValue } from 'jotai'; import { Box, @@ -26,8 +26,8 @@ import { useStateEventCallback } from '$hooks/useStateEventCallback'; import { useForceUpdate } from '$hooks/useForceUpdate'; import { StateEvent } from '$types/matrix/room'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; -import { MatrixError } from '$types/matrix-sdk'; -import { AbbreviationEntry, RoomAbbreviationsContent } from '$utils/abbreviations'; +import { type MatrixError } from '$types/matrix-sdk'; +import { type AbbreviationEntry, type RoomAbbreviationsContent } from '$utils/abbreviations'; import { getAllParents, getStateEvent } from '$utils/room'; import { roomToParentsAtom } from '$state/room/roomToParents'; import { SequenceCardStyle } from '$features/common-settings/styles.css'; diff --git a/src/app/features/room-settings/permissions/usePermissionItems.ts b/src/app/features/room-settings/permissions/usePermissionItems.ts index 20222d45f..7d967c754 100644 --- a/src/app/features/room-settings/permissions/usePermissionItems.ts +++ b/src/app/features/room-settings/permissions/usePermissionItems.ts @@ -1,6 +1,6 @@ import { useMemo } from 'react'; import { MessageEvent, StateEvent } from '$types/matrix/room'; -import { PermissionGroup } from '$features/common-settings/permissions'; +import { type PermissionGroup } from '$features/common-settings/permissions'; export const usePermissionGroups = (isCallRoom: boolean): PermissionGroup[] => { const groups: PermissionGroup[] = useMemo(() => { diff --git a/src/app/features/room/CommandAutocomplete.tsx b/src/app/features/room/CommandAutocomplete.tsx index 42ef1374d..76e00e7db 100644 --- a/src/app/features/room/CommandAutocomplete.tsx +++ b/src/app/features/room/CommandAutocomplete.tsx @@ -1,16 +1,16 @@ -import { KeyboardEvent as ReactKeyboardEvent, useCallback, useEffect, useMemo } from 'react'; -import { Editor } from 'slate'; +import { type KeyboardEvent as ReactKeyboardEvent, useCallback, useEffect, useMemo } from 'react'; +import { type Editor } from 'slate'; import { Box, config, MenuItem, Text } from 'folds'; -import { Room } from '$types/matrix-sdk'; -import { Command, useCommands } from '$hooks/useCommands'; +import { type Room } from '$types/matrix-sdk'; +import { type Command, useCommands } from '$hooks/useCommands'; import { AutocompleteMenu, - AutocompleteQuery, + type AutocompleteQuery, createCommandElement, moveCursor, replaceWithElement, } from '$components/editor'; -import { UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; +import { type UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useKeyDown } from '$hooks/useKeyDown'; import { onTabPress } from '$utils/keyboard'; diff --git a/src/app/features/room/MembersDrawer.tsx b/src/app/features/room/MembersDrawer.tsx index 0a74acfda..6d5efc64e 100644 --- a/src/app/features/room/MembersDrawer.tsx +++ b/src/app/features/room/MembersDrawer.tsx @@ -1,6 +1,6 @@ import { - ChangeEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type MouseEventHandler, useCallback, useMemo, useRef, @@ -18,7 +18,7 @@ import { Input, MenuItem, PopOut, - RectCords, + type RectCords, Scroll, Spinner, Text, @@ -27,7 +27,7 @@ import { config, toRem, } from 'folds'; -import { MatrixClient, Room, RoomMember } from '$types/matrix-sdk'; +import { type MatrixClient, type Room, type RoomMember } from '$types/matrix-sdk'; import { useVirtualizer } from '@tanstack/react-virtual'; import classNames from 'classnames'; @@ -35,7 +35,11 @@ import { AvatarPresence, PresenceBadge } from '$components/presence'; import { useUserPresence } from '$hooks/useUserPresence'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { UseStateProvider } from '$components/UseStateProvider'; -import { SearchItemStrGetter, UseAsyncSearchOptions, useAsyncSearch } from '$hooks/useAsyncSearch'; +import { + type SearchItemStrGetter, + type UseAsyncSearchOptions, + useAsyncSearch, +} from '$hooks/useAsyncSearch'; import { useDebounce } from '$hooks/useDebounce'; import { TypingIndicator } from '$components/typing-indicator'; import { getMemberDisplayName, getMemberSearchStr } from '$utils/room'; diff --git a/src/app/features/room/RoomCallButton.tsx b/src/app/features/room/RoomCallButton.tsx index ad3c7916d..11becd090 100644 --- a/src/app/features/room/RoomCallButton.tsx +++ b/src/app/features/room/RoomCallButton.tsx @@ -1,6 +1,6 @@ import { IconButton, Icon, Icons, TooltipProvider, Tooltip, Text } from 'folds'; import { useAtomValue } from 'jotai'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useCallStart, useCallJoined } from '$hooks/useCallEmbed'; import { callEmbedAtom } from '$state/callEmbed'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx index 3b36b0d7f..981b9c270 100644 --- a/src/app/features/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -1,8 +1,8 @@ import { forwardRef, - KeyboardEventHandler, - MouseEvent, - RefObject, + type KeyboardEventHandler, + type MouseEvent, + type RefObject, useCallback, useEffect, useRef, @@ -12,13 +12,13 @@ import { useAtom, useAtomValue } from 'jotai'; import { isKeyHotkey } from 'is-hotkey'; import { EventType, - IContent, - MatrixEvent, + type IContent, + type MatrixEvent, MsgType, RelationType, - Room, - IEventRelation, - StickerEventContent, + type Room, + type IEventRelation, + type StickerEventContent, } from '$types/matrix-sdk'; import { ReactEditor } from 'slate-react'; import { Editor, Point, Range, Transforms } from 'slate'; @@ -37,7 +37,7 @@ import { OverlayBackdrop, OverlayCenter, PopOut, - RectCords, + type RectCords, Scroll, Text, toRem, @@ -46,7 +46,7 @@ import { import { useMatrixClient } from '$hooks/useMatrixClient'; import { AutocompletePrefix, - AutocompleteQuery, + type AutocompleteQuery, createEmoticonElement, CustomEditor, customHtmlEqualsPlainText, @@ -72,7 +72,7 @@ import { import { EmojiBoard, EmojiBoardTab } from '$components/emoji-board'; import { UseStateProvider } from '$components/UseStateProvider'; import { - TUploadContent, + type TUploadContent, encryptFile, getImageInfo, mxcUrlToHttp, @@ -87,18 +87,23 @@ import { roomIdToReplyDraftAtomFamily, roomIdToUploadItemsAtomFamily, roomUploadAtomFamily, - TUploadItem, - TUploadMetadata, - IReplyDraft, + type TUploadItem, + type TUploadMetadata, + type IReplyDraft, } from '$state/room/roomInputDrafts'; import { UploadCardRenderer } from '$components/upload-card'; import { UploadBoard, UploadBoardContent, UploadBoardHeader, - UploadBoardImperativeHandlers, + type UploadBoardImperativeHandlers, } from '$components/upload-board'; -import { Upload, UploadStatus, UploadSuccess, createUploadFamilyObserverAtom } from '$state/upload'; +import { + type Upload, + UploadStatus, + type UploadSuccess, + createUploadFamilyObserverAtom, +} from '$state/upload'; import { getImageUrlBlob, loadImageElement } from '$utils/dom'; import { safeFile } from '$utils/mimeTypes'; import { fulfilledPromiseSettledResult } from '$utils/common'; @@ -155,8 +160,8 @@ import { import { CommandAutocomplete } from './CommandAutocomplete'; import { AudioMessageRecorder, - AudioMessageRecorderHandle, - AudioRecordingCompletePayload, + type AudioMessageRecorderHandle, + type AudioRecordingCompletePayload, } from './AudioMessageRecorder'; // Returns the event ID of the most recent non-reaction/non-edit event in a thread, diff --git a/src/app/features/room/RoomInputPlaceholder.tsx b/src/app/features/room/RoomInputPlaceholder.tsx index fc923d196..319660755 100644 --- a/src/app/features/room/RoomInputPlaceholder.tsx +++ b/src/app/features/room/RoomInputPlaceholder.tsx @@ -1,4 +1,4 @@ -import { ComponentProps } from 'react'; +import { type ComponentProps } from 'react'; import { Box, as } from 'folds'; import classNames from 'classnames'; diff --git a/src/app/features/room/RoomTimeline.css.ts b/src/app/features/room/RoomTimeline.css.ts index 7b355fe1e..df0812b2a 100644 --- a/src/app/features/room/RoomTimeline.css.ts +++ b/src/app/features/room/RoomTimeline.css.ts @@ -1,5 +1,5 @@ import { globalStyle, style } from '@vanilla-extract/css'; -import { RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { type RecipeVariants, recipe } from '@vanilla-extract/recipes'; import { DefaultReset, color, config, toRem } from 'folds'; export const TimelineFloat = recipe({ diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index 94b1ad696..6fc9fc08b 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -1,6 +1,6 @@ import { Fragment, - ReactNode, + type ReactNode, useCallback, useEffect, useLayoutEffect, @@ -8,11 +8,11 @@ import { useRef, useState, } from 'react'; -import { Editor } from 'slate'; +import { type Editor } from 'slate'; import { useAtomValue, useSetAtom } from 'jotai'; -import { PushProcessor, Room, Direction } from '$types/matrix-sdk'; +import { PushProcessor, type Room, Direction } from '$types/matrix-sdk'; import classNames from 'classnames'; -import { VList, VListHandle } from 'virtua'; +import { VList, type VListHandle } from 'virtua'; import { as, Box, @@ -25,7 +25,7 @@ import { color, config, toRem, - ContainerColor, + type ContainerColor, Spinner, } from 'folds'; import { MessageBase, CompactPlaceholder, DefaultPlaceholder } from '$components/message'; @@ -73,7 +73,7 @@ import { } from '$utils/timeline'; import { useTimelineSync } from '$hooks/timeline/useTimelineSync'; import { useTimelineActions } from '$hooks/timeline/useTimelineActions'; -import { ProcessedEvent, useProcessedTimeline } from '$hooks/timeline/useProcessedTimeline'; +import { type ProcessedEvent, useProcessedTimeline } from '$hooks/timeline/useProcessedTimeline'; import { useTimelineEventRenderer } from '$hooks/timeline/useTimelineEventRenderer'; import * as css from './RoomTimeline.css'; diff --git a/src/app/features/room/RoomViewFollowing.tsx b/src/app/features/room/RoomViewFollowing.tsx index 6d9a60c68..946c5923b 100644 --- a/src/app/features/room/RoomViewFollowing.tsx +++ b/src/app/features/room/RoomViewFollowing.tsx @@ -11,7 +11,7 @@ import { as, config, } from 'folds'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import classNames from 'classnames'; import FocusTrap from 'focus-trap-react'; import { useAtomValue } from 'jotai'; diff --git a/src/app/features/room/RoomViewHeader.tsx b/src/app/features/room/RoomViewHeader.tsx index 8552332cf..fd08cde69 100644 --- a/src/app/features/room/RoomViewHeader.tsx +++ b/src/app/features/room/RoomViewHeader.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, forwardRef, useCallback, useEffect, useState } from 'react'; +import { type MouseEventHandler, forwardRef, useCallback, useEffect, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { useAtom, useAtomValue } from 'jotai'; import { @@ -19,17 +19,17 @@ import { config, Line, PopOut, - RectCords, + type RectCords, Badge, Spinner, } from 'folds'; import { useNavigate } from 'react-router-dom'; import { EventTimeline, - Room, + type Room, ThreadEvent, RoomEvent, - MatrixEvent, + type MatrixEvent, NotificationCountType, } from '$types/matrix-sdk'; diff --git a/src/app/features/room/RoomViewTyping.tsx b/src/app/features/room/RoomViewTyping.tsx index e75c4a13d..fd3912263 100644 --- a/src/app/features/room/RoomViewTyping.tsx +++ b/src/app/features/room/RoomViewTyping.tsx @@ -1,5 +1,5 @@ import { Box, Icon, IconButton, Icons, Text, as } from 'folds'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import classNames from 'classnames'; import { useSetAtom, useAtomValue } from 'jotai'; import { roomIdToTypingMembersAtom } from '$state/typingMembers'; diff --git a/src/app/features/room/ThreadBrowser.tsx b/src/app/features/room/ThreadBrowser.tsx index 7c1e830f0..bd2c1adf0 100644 --- a/src/app/features/room/ThreadBrowser.tsx +++ b/src/app/features/room/ThreadBrowser.tsx @@ -1,6 +1,6 @@ import { - ChangeEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type MouseEventHandler, useCallback, useEffect, useMemo, @@ -20,10 +20,10 @@ import { config, Chip, } from 'folds'; -import { MatrixEvent, Room, Thread, ThreadEvent } from '$types/matrix-sdk'; +import { type MatrixEvent, type Room, type Thread, ThreadEvent } from '$types/matrix-sdk'; import { useAtomValue } from 'jotai'; -import { HTMLReactParserOptions } from 'html-react-parser'; -import { Opts as LinkifyOpts } from 'linkifyjs'; +import { type HTMLReactParserOptions } from 'html-react-parser'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { useRoomNavigate } from '$hooks/useRoomNavigate'; @@ -43,7 +43,7 @@ import { import { RenderMessageContent } from '$components/RenderMessageContent'; import { settingsAtom } from '$state/settings'; import { useSetting } from '$state/hooks/settings'; -import { GetContentCallback } from '$types/matrix/room'; +import { type GetContentCallback } from '$types/matrix/room'; import { useMentionClickHandler } from '$hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '$hooks/useSpoilerClickHandler'; import { diff --git a/src/app/features/room/ThreadDrawer.tsx b/src/app/features/room/ThreadDrawer.tsx index b662d2ab3..3676240c9 100644 --- a/src/app/features/room/ThreadDrawer.tsx +++ b/src/app/features/room/ThreadDrawer.tsx @@ -1,18 +1,18 @@ -import { MouseEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { type MouseEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Box, Header, Icon, IconButton, Icons, Scroll, Text, config } from 'folds'; import { - MatrixEvent, + type MatrixEvent, PushProcessor, ReceiptType, RelationType, - Room, + type Room, RoomEvent, ThreadEvent, } from '$types/matrix-sdk'; import { useAtomValue, useSetAtom } from 'jotai'; import { ReactEditor } from 'slate-react'; -import { HTMLReactParserOptions } from 'html-react-parser'; -import { Opts as LinkifyOpts } from 'linkifyjs'; +import { type HTMLReactParserOptions } from 'html-react-parser'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; import { ImageContent, MSticker, RedactedContent, Reply } from '$components/message'; import { RenderMessageContent } from '$components/RenderMessageContent'; import { Image } from '$components/media'; @@ -36,20 +36,20 @@ import { minuteDifference } from '$utils/time'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { nicknamesAtom } from '$state/nicknames'; -import { MessageLayout, MessageSpacing, settingsAtom } from '$state/settings'; +import { MessageLayout, type MessageSpacing, settingsAtom } from '$state/settings'; import { useSetting } from '$state/hooks/settings'; import { useRoomAbbreviationsContext } from '$hooks/useRoomAbbreviations'; import { buildAbbrReplaceTextNode } from '$components/message/RenderBody'; import { createMentionElement, moveCursor, useEditor } from '$components/editor'; import { useMentionClickHandler } from '$hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '$hooks/useSpoilerClickHandler'; -import { GetContentCallback, MessageEvent, StateEvent } from '$types/matrix/room'; +import { type GetContentCallback, MessageEvent, StateEvent } from '$types/matrix/room'; import { usePowerLevelsContext } from '$hooks/usePowerLevels'; import { useRoomPermissions } from '$hooks/useRoomPermissions'; import { useRoomCreators } from '$hooks/useRoomCreators'; import { useImagePackRooms } from '$hooks/useImagePackRooms'; import { useOpenUserRoomProfile } from '$state/hooks/userRoomProfile'; -import { IReplyDraft, roomIdToReplyDraftAtomFamily } from '$state/room/roomInputDrafts'; +import { type IReplyDraft, roomIdToReplyDraftAtomFamily } from '$state/room/roomInputDrafts'; import { roomToParentsAtom } from '$state/room/roomToParents'; import { EncryptedContent, Message, Reactions } from './message'; import { RoomInput } from './RoomInput'; diff --git a/src/app/features/room/jump-to-time/JumpToTime.tsx b/src/app/features/room/jump-to-time/JumpToTime.tsx index 9ebd5a7ac..81ffd29ee 100644 --- a/src/app/features/room/jump-to-time/JumpToTime.tsx +++ b/src/app/features/room/jump-to-time/JumpToTime.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useMemo, useState } from 'react'; +import { type MouseEventHandler, useCallback, useMemo, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { Dialog, @@ -17,9 +17,9 @@ import { Spinner, Chip, PopOut, - RectCords, + type RectCords, } from 'folds'; -import { Direction, MatrixError } from '$types/matrix-sdk'; +import { Direction, 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/features/room/message/EncryptedContent.tsx b/src/app/features/room/message/EncryptedContent.tsx index 33955b6e9..89c1ba56d 100644 --- a/src/app/features/room/message/EncryptedContent.tsx +++ b/src/app/features/room/message/EncryptedContent.tsx @@ -1,5 +1,5 @@ -import { MatrixEvent, MatrixEventEvent, MatrixEventHandlerMap } from '$types/matrix-sdk'; -import { ReactNode, useEffect, useState } from 'react'; +import { type MatrixEvent, MatrixEventEvent, type MatrixEventHandlerMap } from '$types/matrix-sdk'; +import { type ReactNode, useEffect, useState } from 'react'; import { MessageEvent } from '$types/matrix/room'; import { useMatrixClient } from '$hooks/useMatrixClient'; import * as Sentry from '@sentry/react'; diff --git a/src/app/features/room/message/Message.tsx b/src/app/features/room/message/Message.tsx index 4bfab3bbb..1cae02f57 100644 --- a/src/app/features/room/message/Message.tsx +++ b/src/app/features/room/message/Message.tsx @@ -9,16 +9,16 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Text, as, config, } from 'folds'; import { - MouseEventHandler, - MouseEvent, - PointerEvent, - ReactNode, + type MouseEventHandler, + type MouseEvent, + type PointerEvent, + type ReactNode, memo, useCallback, useRef, @@ -30,13 +30,13 @@ import FocusTrap from 'focus-trap-react'; import { useHover, useFocusWithin } from 'react-aria'; import { EventStatus, - MatrixEvent, - Room, - Relations, - RoomPinnedEventsEventContent, + type MatrixEvent, + type Room, + type Relations, + type RoomPinnedEventsEventContent, MatrixEventEvent, RoomEvent, - IRoomTimelineData, + type IRoomTimelineData, } from '$types/matrix-sdk'; import classNames from 'classnames'; import { useAtomValue, useSetAtom } from 'jotai'; @@ -53,7 +53,7 @@ import { } from '$components/message'; import { canEditEvent, getEditedEvent, getEventEdits, getMemberAvatarMxc } from '$utils/room'; import { mxcUrlToHttp } from '$utils/matrix'; -import { getSettings, MessageLayout, MessageSpacing, settingsAtom } from '$state/settings'; +import { getSettings, MessageLayout, type MessageSpacing, settingsAtom } from '$state/settings'; import { nicknamesAtom, setNicknameAtom } from '$state/nicknames'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useRecentEmoji } from '$hooks/useRecentEmoji'; @@ -65,7 +65,7 @@ import { getMatrixToRoomEvent } from '$plugins/matrix-to'; import { getViaServers } from '$plugins/via-servers'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { useRoomPinnedEvents } from '$hooks/useRoomPinnedEvents'; -import { MemberPowerTag, StateEvent } from '$types/matrix/room'; +import { type MemberPowerTag, StateEvent } from '$types/matrix/room'; import { PowerIcon } from '$components/power'; import { getPowerTagIconSrc } from '$hooks/useMemberPowerTag'; import { useSableCosmetics } from '$hooks/useSableCosmetics'; @@ -89,7 +89,7 @@ import { } from '$utils/addStickerToDefaultStickerPack'; import { convertBeeperFormatToOurPerMessageProfile, - PerMessageProfileBeeperFormat, + type PerMessageProfileBeeperFormat, } from '$hooks/usePerMessageProfile'; import { MessageEditor } from './MessageEditor'; import * as css from './styles.css'; diff --git a/src/app/features/room/message/MessageEditor.tsx b/src/app/features/room/message/MessageEditor.tsx index 22c63ce26..b5960dcca 100644 --- a/src/app/features/room/message/MessageEditor.tsx +++ b/src/app/features/room/message/MessageEditor.tsx @@ -1,6 +1,6 @@ import { - KeyboardEventHandler, - MouseEventHandler, + type KeyboardEventHandler, + type MouseEventHandler, useCallback, useEffect, useMemo, @@ -14,7 +14,7 @@ import { Icons, Line, PopOut, - RectCords, + type RectCords, Spinner, Text, as, @@ -23,19 +23,19 @@ import { import { Editor, Transforms } from 'slate'; import { ReactEditor } from 'slate-react'; import { - IContent, - IMentions, - MatrixEvent, - ReplacementEvent, + type IContent, + type IMentions, + type MatrixEvent, + type ReplacementEvent, RelationType, - Room, - RoomMessageTextEventContent, + type Room, + type RoomMessageTextEventContent, MsgType, } from '$types/matrix-sdk'; import { isKeyHotkey } from 'is-hotkey'; import { AutocompletePrefix, - AutocompleteQuery, + type AutocompleteQuery, CustomEditor, EmoticonAutocomplete, RoomMentionAutocomplete, @@ -68,10 +68,10 @@ import { floatingEditor } from '$styles/overrides/Composer.css'; import { RenderMessageContent } from '$components/RenderMessageContent'; import { getReactCustomHtmlParser, LINKIFY_OPTS } from '$plugins/react-custom-html-parser'; import { useSpoilerClickHandler } from '$hooks/useSpoilerClickHandler'; -import { HTMLReactParserOptions } from 'html-react-parser'; +import { type HTMLReactParserOptions } from 'html-react-parser'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; -import { Opts as LinkifyOpts } from 'linkifyjs'; -import { GetContentCallback } from '$types/matrix/room'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; +import { type GetContentCallback } from '$types/matrix/room'; import { sanitizeCustomHtml } from '$utils/sanitize'; type MessageEditorProps = { diff --git a/src/app/features/room/message/Reactions.tsx b/src/app/features/room/message/Reactions.tsx index efcd74dc9..a5cacf2dc 100644 --- a/src/app/features/room/message/Reactions.tsx +++ b/src/app/features/room/message/Reactions.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useState } from 'react'; +import { type MouseEventHandler, useCallback, useState } from 'react'; import { Box, Modal, @@ -12,8 +12,7 @@ import { toRem, } from 'folds'; import classNames from 'classnames'; -import { Room } from '$types/matrix-sdk'; -import { type Relations } from '$types/matrix-sdk'; +import { type Room, type Relations } from '$types/matrix-sdk'; import FocusTrap from 'focus-trap-react'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { factoryEventSentBy } from '$utils/matrix'; diff --git a/src/app/features/room/msgContent.ts b/src/app/features/room/msgContent.ts index 0cec05a57..8d85d13db 100644 --- a/src/app/features/room/msgContent.ts +++ b/src/app/features/room/msgContent.ts @@ -1,7 +1,7 @@ -import { IContent, MatrixClient, MsgType } from '$types/matrix-sdk'; +import { type IContent, type MatrixClient, MsgType } from '$types/matrix-sdk'; import to from 'await-to-js'; import { - IThumbnailContent, + type IThumbnailContent, MATRIX_BLUR_HASH_PROPERTY_NAME, MATRIX_SPOILER_PROPERTY_NAME, } from '$types/matrix/common'; @@ -14,7 +14,7 @@ import { loadVideoElement, } from '$utils/dom'; import { encryptFile, getImageInfo, getThumbnailContent, getVideoInfo } from '$utils/matrix'; -import { TUploadItem } from '$state/room/roomInputDrafts'; +import { type TUploadItem } from '$state/room/roomInputDrafts'; import { encodeBlurHash } from '$utils/blurHash'; import { scaleYDimension } from '$utils/common'; import { createLogger } from '$utils/debug'; diff --git a/src/app/features/room/reaction-viewer/ReactionViewer.tsx b/src/app/features/room/reaction-viewer/ReactionViewer.tsx index 9065cfb64..fc0573499 100644 --- a/src/app/features/room/reaction-viewer/ReactionViewer.tsx +++ b/src/app/features/room/reaction-viewer/ReactionViewer.tsx @@ -14,7 +14,7 @@ import { as, config, } from 'folds'; -import { MatrixEvent, Room, RoomMember, Relations } from '$types/matrix-sdk'; +import { type MatrixEvent, type Room, type RoomMember, type Relations } from '$types/matrix-sdk'; import { getMemberDisplayName } from '$utils/room'; import { eventWithShortcode, getMxIdLocalPart } from '$utils/matrix'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/features/room/room-pin-menu/RoomPinMenu.tsx b/src/app/features/room/room-pin-menu/RoomPinMenu.tsx index 9762f216a..705e8e850 100644 --- a/src/app/features/room/room-pin-menu/RoomPinMenu.tsx +++ b/src/app/features/room/room-pin-menu/RoomPinMenu.tsx @@ -1,6 +1,13 @@ /* eslint-disable react/no-unused-prop-types, react/destructuring-assignment */ -import { forwardRef, MouseEventHandler, ReactNode, useCallback, useMemo, useRef } from 'react'; -import { MatrixEvent, Room, RoomPinnedEventsEventContent } from '$types/matrix-sdk'; +import { + forwardRef, + type MouseEventHandler, + type ReactNode, + useCallback, + useMemo, + useRef, +} from 'react'; +import { type MatrixEvent, type Room, type RoomPinnedEventsEventContent } from '$types/matrix-sdk'; import { Avatar, Box, @@ -17,8 +24,8 @@ import { Text, toRem, } from 'folds'; -import { Opts as LinkifyOpts } from 'linkifyjs'; -import { HTMLReactParserOptions } from 'html-react-parser'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; +import { type HTMLReactParserOptions } from 'html-react-parser'; import { useAtomValue } from 'jotai'; import { useVirtualizer } from '@tanstack/react-virtual'; import { createLogger } from '$utils/debug'; @@ -49,7 +56,7 @@ import { getMemberDisplayName, getStateEvent, } from '$utils/room'; -import { GetContentCallback, MessageEvent, StateEvent } from '$types/matrix/room'; +import { type GetContentCallback, MessageEvent, StateEvent } from '$types/matrix/room'; import { useMentionClickHandler } from '$hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '$hooks/useSpoilerClickHandler'; import { @@ -59,7 +66,7 @@ import { makeMentionCustomProps, renderMatrixMention, } from '$plugins/react-custom-html-parser'; -import { RenderMatrixEvent, useMatrixEventRenderer } from '$hooks/useMatrixEventRenderer'; +import { type RenderMatrixEvent, useMatrixEventRenderer } from '$hooks/useMatrixEventRenderer'; import { RenderMessageContent } from '$components/RenderMessageContent'; import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; @@ -77,7 +84,7 @@ import { PowerIcon } from '$components/power'; import { useRoomCreators } from '$hooks/useRoomCreators'; import { useRoomPermissions } from '$hooks/useRoomPermissions'; import { - GetMemberPowerTag, + type GetMemberPowerTag, getPowerTagIconSrc, useAccessiblePowerTagColors, useGetMemberPowerTag, diff --git a/src/app/features/room/schedule-send/SchedulePickerDialog.tsx b/src/app/features/room/schedule-send/SchedulePickerDialog.tsx index 50f119ef9..a2ab1141a 100644 --- a/src/app/features/room/schedule-send/SchedulePickerDialog.tsx +++ b/src/app/features/room/schedule-send/SchedulePickerDialog.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useState } from 'react'; +import { type MouseEventHandler, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { Dialog, @@ -16,7 +16,7 @@ import { Button, Chip, PopOut, - RectCords, + type RectCords, } from 'folds'; import { stopPropagation } from '$utils/keyboard'; import { timeDayMonthYear, timeHourMinute, hoursToMs, daysToMs } from '$utils/time'; diff --git a/src/app/features/room/schedule-send/ScheduledMessagesList.tsx b/src/app/features/room/schedule-send/ScheduledMessagesList.tsx index 39f751c9c..94ce0e338 100644 --- a/src/app/features/room/schedule-send/ScheduledMessagesList.tsx +++ b/src/app/features/room/schedule-send/ScheduledMessagesList.tsx @@ -1,7 +1,7 @@ import { useCallback, useState } from 'react'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { Box, Text, Chip, Icon, Icons, IconButton } from 'folds'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { getDelayedEvents, cancelDelayedEvent } from '$utils/delayedEvents'; diff --git a/src/app/features/search/Search.tsx b/src/app/features/search/Search.tsx index 65c79ba83..4c29a68df 100644 --- a/src/app/features/search/Search.tsx +++ b/src/app/features/search/Search.tsx @@ -16,9 +16,9 @@ import { toRem, } from 'folds'; import { - ChangeEventHandler, - KeyboardEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type KeyboardEventHandler, + type MouseEventHandler, useCallback, useEffect, useMemo, @@ -27,12 +27,16 @@ import { } from 'react'; import { isKeyHotkey } from 'is-hotkey'; import { useAtom, useAtomValue } from 'jotai'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useDirects, useOrphanSpaces, useRooms, useSpaces } from '$state/hooks/roomList'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { mDirectAtom } from '$state/mDirectList'; import { allRoomsAtom } from '$state/room-list/roomList'; -import { SearchItemStrGetter, useAsyncSearch, UseAsyncSearchOptions } from '$hooks/useAsyncSearch'; +import { + type SearchItemStrGetter, + useAsyncSearch, + type UseAsyncSearchOptions, +} from '$hooks/useAsyncSearch'; import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom'; import { RoomAvatar, RoomIcon } from '$components/room-avatar'; import { diff --git a/src/app/features/settings/Persona/PerMessageProfileEditor.tsx b/src/app/features/settings/Persona/PerMessageProfileEditor.tsx index 00a0ff9fe..d1350a2b1 100644 --- a/src/app/features/settings/Persona/PerMessageProfileEditor.tsx +++ b/src/app/features/settings/Persona/PerMessageProfileEditor.tsx @@ -1,6 +1,6 @@ import { SequenceCard } from '$components/sequence-card'; import { Box, Button, Text, Avatar, config, Icon, IconButton, Icons, Input } from 'folds'; -import { MatrixClient } from 'matrix-js-sdk'; +import { type MatrixClient } from 'matrix-js-sdk'; import { useCallback, useMemo, useState } from 'react'; import { mxcUrlToHttp } from '$utils/matrix'; import { useFilePicker } from '$hooks/useFilePicker'; @@ -14,7 +14,7 @@ import { deletePerMessageProfile, renamePerMessageProfile, } from '$hooks/usePerMessageProfile'; -import { parsePronounsStringToPronounsSetArray, PronounSet } from '$utils/pronouns'; +import { parsePronounsStringToPronounsSetArray, type PronounSet } from '$utils/pronouns'; import { SequenceCardStyle } from '../styles.css'; /** diff --git a/src/app/features/settings/Persona/PerMessageProfileOverview.tsx b/src/app/features/settings/Persona/PerMessageProfileOverview.tsx index 6ed0dcef0..be7989b89 100644 --- a/src/app/features/settings/Persona/PerMessageProfileOverview.tsx +++ b/src/app/features/settings/Persona/PerMessageProfileOverview.tsx @@ -2,7 +2,7 @@ import { useMatrixClient } from '$hooks/useMatrixClient'; import { addOrUpdatePerMessageProfile, getAllPerMessageProfiles, - PerMessageProfile, + type PerMessageProfile, } from '$hooks/usePerMessageProfile'; import { useEffect, useState } from 'react'; import { Box, Button, Text } from 'folds'; diff --git a/src/app/features/settings/Settings.tsx b/src/app/features/settings/Settings.tsx index 2dd1e4ae4..2167f476d 100644 --- a/src/app/features/settings/Settings.tsx +++ b/src/app/features/settings/Settings.tsx @@ -7,7 +7,7 @@ import { Icon, IconButton, Icons, - IconSrc, + type IconSrc, MenuItem, Overlay, OverlayBackdrop, diff --git a/src/app/features/settings/account/AnimalCosmetics.tsx b/src/app/features/settings/account/AnimalCosmetics.tsx index ada07ef99..93cb9a798 100644 --- a/src/app/features/settings/account/AnimalCosmetics.tsx +++ b/src/app/features/settings/account/AnimalCosmetics.tsx @@ -1,7 +1,7 @@ import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { UserProfile } from '$hooks/useUserProfile'; +import { type UserProfile } from '$hooks/useUserProfile'; import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { profilesCacheAtom } from '$state/userRoomProfile'; diff --git a/src/app/features/settings/account/BioEditor.tsx b/src/app/features/settings/account/BioEditor.tsx index b5670a22c..cf194252a 100644 --- a/src/app/features/settings/account/BioEditor.tsx +++ b/src/app/features/settings/account/BioEditor.tsx @@ -1,4 +1,4 @@ -import { KeyboardEventHandler, useCallback, useEffect, useState, useRef } from 'react'; +import { type KeyboardEventHandler, useCallback, useEffect, useState, useRef } from 'react'; import { Box, Chip, @@ -7,7 +7,7 @@ import { Icons, Line, PopOut, - RectCords, + type RectCords, Spinner, Text, config, @@ -17,7 +17,7 @@ import { ReactEditor } from 'slate-react'; import { isKeyHotkey } from 'is-hotkey'; import { AutocompletePrefix, - AutocompleteQuery, + type AutocompleteQuery, CustomEditor, EmoticonAutocomplete, Toolbar, diff --git a/src/app/features/settings/account/IgnoredUserList.tsx b/src/app/features/settings/account/IgnoredUserList.tsx index 0b3b3470f..ef8a024ce 100644 --- a/src/app/features/settings/account/IgnoredUserList.tsx +++ b/src/app/features/settings/account/IgnoredUserList.tsx @@ -1,4 +1,4 @@ -import { ChangeEventHandler, FormEventHandler, useCallback, useState } from 'react'; +import { type ChangeEventHandler, type FormEventHandler, useCallback, useState } from 'react'; import { Box, Button, Chip, Icon, IconButton, Icons, Input, Spinner, Text, config } from 'folds'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; diff --git a/src/app/features/settings/account/Profile.tsx b/src/app/features/settings/account/Profile.tsx index 5702c0293..1c5149ae2 100644 --- a/src/app/features/settings/account/Profile.tsx +++ b/src/app/features/settings/account/Profile.tsx @@ -1,6 +1,6 @@ import { - ChangeEventHandler, - FormEventHandler, + type ChangeEventHandler, + type FormEventHandler, useCallback, useEffect, useMemo, @@ -29,7 +29,7 @@ import { useSetAtom } from 'jotai'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { UserProfile, useUserProfile, MSC4440Bio } from '$hooks/useUserProfile'; +import { type UserProfile, useUserProfile, type MSC4440Bio } from '$hooks/useUserProfile'; import { getMxIdLocalPart, mxcUrlToHttp } from '$utils/matrix'; import { UserAvatar } from '$components/user-avatar'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; @@ -40,13 +40,13 @@ import { useObjectURL } from '$hooks/useObjectURL'; import { stopPropagation } from '$utils/keyboard'; import { ImageEditor } from '$components/image-editor'; import { ModalWide } from '$styles/Modal.css'; -import { createUploadAtom, UploadSuccess } from '$state/upload'; +import { createUploadAtom, type UploadSuccess } from '$state/upload'; import { CompactUploadCardRenderer } from '$components/upload-card'; import { useCapabilities } from '$hooks/useCapabilities'; import { profilesCacheAtom } from '$state/userRoomProfile'; import { SequenceCardStyle } from '$features/settings/styles.css'; import { useUserPresence } from '$hooks/useUserPresence'; -import { MSC1767Text } from '$types/matrix/common'; +import { type MSC1767Text } from '$types/matrix/common'; import { TimezoneEditor } from './TimezoneEditor'; import { PronounEditor } from './PronounEditor'; import { BioEditor } from './BioEditor'; diff --git a/src/app/features/settings/account/PronounEditor.tsx b/src/app/features/settings/account/PronounEditor.tsx index 2de50a142..28ead56c8 100644 --- a/src/app/features/settings/account/PronounEditor.tsx +++ b/src/app/features/settings/account/PronounEditor.tsx @@ -1,7 +1,7 @@ -import { useState, useEffect, ChangeEvent } from 'react'; +import { useState, useEffect, type ChangeEvent } from 'react'; import { Input } from 'folds'; import { SettingTile } from '$components/setting-tile'; -import { parsePronounsInput, PronounSet } from '$utils/pronouns'; +import { parsePronounsInput, type PronounSet } from '$utils/pronouns'; type PronounEditorProps = { title: string; diff --git a/src/app/features/settings/account/StatusEditor.tsx b/src/app/features/settings/account/StatusEditor.tsx index 001c99c34..1ca6f68ce 100644 --- a/src/app/features/settings/account/StatusEditor.tsx +++ b/src/app/features/settings/account/StatusEditor.tsx @@ -1,4 +1,4 @@ -import { ChangeEventHandler, FormEventHandler, useEffect, useState } from 'react'; +import { type ChangeEventHandler, type FormEventHandler, useEffect, useState } from 'react'; import { Box, Text, Button, Input, IconButton, Icon, Icons, Spinner, config } from 'folds'; import { SettingTile } from '$components/setting-tile'; diff --git a/src/app/features/settings/account/TimezoneEditor.tsx b/src/app/features/settings/account/TimezoneEditor.tsx index 7d28399a5..0b3e12d1c 100644 --- a/src/app/features/settings/account/TimezoneEditor.tsx +++ b/src/app/features/settings/account/TimezoneEditor.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState, useEffect, ChangeEvent } from 'react'; +import { useMemo, useState, useEffect, type ChangeEvent } from 'react'; import { Box, IconButton, Button, Icon, Icons, Input, Text } from 'folds'; import { SettingTile } from '$components/setting-tile'; diff --git a/src/app/features/settings/cosmetics/Cosmetics.tsx b/src/app/features/settings/cosmetics/Cosmetics.tsx index 7e44bf480..039751820 100644 --- a/src/app/features/settings/cosmetics/Cosmetics.tsx +++ b/src/app/features/settings/cosmetics/Cosmetics.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useState } from 'react'; +import { type MouseEventHandler, useState } from 'react'; import { Box, Button, @@ -9,7 +9,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Scroll, Switch, Text, @@ -18,7 +18,7 @@ import FocusTrap from 'focus-trap-react'; import { Page, PageContent, PageHeader } from '$components/page'; import { SequenceCard } from '$components/sequence-card'; import { useSetting } from '$state/hooks/settings'; -import { JumboEmojiSize, settingsAtom } from '$state/settings'; +import { type JumboEmojiSize, settingsAtom } from '$state/settings'; import { SettingTile } from '$components/setting-tile'; import { stopPropagation } from '$utils/keyboard'; import { SequenceCardStyle } from '$features/settings/styles.css'; diff --git a/src/app/features/settings/cosmetics/Themes.tsx b/src/app/features/settings/cosmetics/Themes.tsx index 0ec660aa0..f855f3548 100644 --- a/src/app/features/settings/cosmetics/Themes.tsx +++ b/src/app/features/settings/cosmetics/Themes.tsx @@ -1,4 +1,9 @@ -import { ChangeEventHandler, KeyboardEventHandler, MouseEventHandler, useState } from 'react'; +import { + type ChangeEventHandler, + type KeyboardEventHandler, + type MouseEventHandler, + useState, +} from 'react'; import { as, Box, @@ -11,7 +16,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Switch, Text, toRem, @@ -25,7 +30,7 @@ import { SettingTile } from '$components/setting-tile'; import { DarkTheme, LightTheme, - Theme, + type Theme, ThemeKind, useSystemThemeKind, useThemeNames, diff --git a/src/app/features/settings/developer-tools/DebugLogViewer.tsx b/src/app/features/settings/developer-tools/DebugLogViewer.tsx index 8e5ae01e1..d983cf436 100644 --- a/src/app/features/settings/developer-tools/DebugLogViewer.tsx +++ b/src/app/features/settings/developer-tools/DebugLogViewer.tsx @@ -1,10 +1,21 @@ -import { useEffect, useState, useCallback, useMemo, MouseEventHandler } from 'react'; +import { useEffect, useState, useCallback, useMemo, type MouseEventHandler } from 'react'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; -import { Box, Text, Button, color, config, Badge, Menu, MenuItem, PopOut, RectCords } from 'folds'; +import { + Box, + Text, + Button, + color, + config, + Badge, + Menu, + MenuItem, + PopOut, + type RectCords, +} from 'folds'; import { SequenceCard } from '$components/sequence-card'; import { debugLoggerEnabledAtom, debugLogsAtom, clearDebugLogsAtom } from '$state/debugLogger'; -import { LogEntry, getDebugLogger, LogLevel, LogCategory } from '$utils/debugLogger'; +import { type LogEntry, getDebugLogger, type LogLevel, type LogCategory } from '$utils/debugLogger'; import { SequenceCardStyle } from '$features/settings/styles.css'; const formatTimestamp = (timestamp: number): string => { diff --git a/src/app/features/settings/developer-tools/DevelopTools.tsx b/src/app/features/settings/developer-tools/DevelopTools.tsx index b717f2261..f13f8457f 100644 --- a/src/app/features/settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/settings/developer-tools/DevelopTools.tsx @@ -6,7 +6,7 @@ import { SettingTile } from '$components/setting-tile'; import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { AccountDataEditor, AccountDataSubmitCallback } from '$components/AccountDataEditor'; +import { AccountDataEditor, type AccountDataSubmitCallback } from '$components/AccountDataEditor'; import { copyToClipboard } from '$utils/dom'; import { SequenceCardStyle } from '$features/settings/styles.css'; import { AccountData } from './AccountData'; diff --git a/src/app/features/settings/developer-tools/SentrySettings.tsx b/src/app/features/settings/developer-tools/SentrySettings.tsx index b0425e76f..3c6ef4874 100644 --- a/src/app/features/settings/developer-tools/SentrySettings.tsx +++ b/src/app/features/settings/developer-tools/SentrySettings.tsx @@ -3,7 +3,7 @@ import { Box, Text, Switch, Button } from 'folds'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; import { SequenceCardStyle } from '$features/settings/styles.css'; -import { getDebugLogger, LogCategory } from '$utils/debugLogger'; +import { getDebugLogger, type LogCategory } from '$utils/debugLogger'; const ALL_CATEGORIES: LogCategory[] = [ 'sync', diff --git a/src/app/features/settings/developer-tools/SyncDiagnostics.tsx b/src/app/features/settings/developer-tools/SyncDiagnostics.tsx index 1d9631107..f9b062b71 100644 --- a/src/app/features/settings/developer-tools/SyncDiagnostics.tsx +++ b/src/app/features/settings/developer-tools/SyncDiagnostics.tsx @@ -3,7 +3,7 @@ import { Box, Button, Icon, Icons, Text } from 'folds'; import { SequenceCard } from '$components/sequence-card'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { getClientSyncDiagnostics } from '$client/initMatrix'; -import { Direction, EventType, NotificationCountType, Room } from '$types/matrix-sdk'; +import { Direction, EventType, NotificationCountType, type Room } from '$types/matrix-sdk'; import { Membership } from '$types/matrix/room'; import { SequenceCardStyle } from '$features/settings/styles.css'; import { getUnreadInfo, isNotificationEvent } from '$utils/room'; diff --git a/src/app/features/settings/devices/DeviceTile.tsx b/src/app/features/settings/devices/DeviceTile.tsx index b77be8ac5..c9473b484 100644 --- a/src/app/features/settings/devices/DeviceTile.tsx +++ b/src/app/features/settings/devices/DeviceTile.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, ReactNode, useCallback, useEffect, useState } from 'react'; +import { type FormEventHandler, type ReactNode, useCallback, useEffect, useState } from 'react'; import { Box, Text, @@ -15,7 +15,7 @@ import { OverlayBackdrop, OverlayCenter, } from 'folds'; -import { CryptoApi, IMyDevice, MatrixError } from '$types/matrix-sdk'; +import { type CryptoApi, type IMyDevice, type MatrixError } from '$types/matrix-sdk'; import FocusTrap from 'focus-trap-react'; import { SettingTile } from '$components/setting-tile'; import { useMatrixClient } from '$hooks/useMatrixClient'; diff --git a/src/app/features/settings/devices/LocalBackup.tsx b/src/app/features/settings/devices/LocalBackup.tsx index eaefc7ff5..b8700405f 100644 --- a/src/app/features/settings/devices/LocalBackup.tsx +++ b/src/app/features/settings/devices/LocalBackup.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useEffect, useState } from 'react'; +import { type FormEventHandler, useCallback, useEffect, useState } from 'react'; import { Box, Button, color, Icon, Icons, Spinner, Text, toRem } from 'folds'; import FileSaver from 'file-saver'; import { SequenceCard } from '$components/sequence-card'; diff --git a/src/app/features/settings/devices/OtherDevices.tsx b/src/app/features/settings/devices/OtherDevices.tsx index e044201d1..8687f1165 100644 --- a/src/app/features/settings/devices/OtherDevices.tsx +++ b/src/app/features/settings/devices/OtherDevices.tsx @@ -1,9 +1,9 @@ import { useCallback, useState } from 'react'; import { Box, Button, config, Menu, Spinner, Text } from 'folds'; -import { AuthDict, IMyDevice, MatrixError } from '$types/matrix-sdk'; +import { type AuthDict, type IMyDevice, type MatrixError } from '$types/matrix-sdk'; import { SequenceCard } from '$components/sequence-card'; import { ActionUIA, ActionUIAFlowsLoader } from '$components/ActionUIA'; -import { AsyncState, AsyncStatus, useAsync } from '$hooks/useAsyncCallback'; +import { type AsyncState, AsyncStatus, useAsync } from '$hooks/useAsyncCallback'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useUIAMatrixError } from '$hooks/useUIAFlows'; import { DeviceVerificationStatus } from '$components/DeviceVerificationStatus'; diff --git a/src/app/features/settings/devices/Verification.tsx b/src/app/features/settings/devices/Verification.tsx index 34dccf481..7376c4116 100644 --- a/src/app/features/settings/devices/Verification.tsx +++ b/src/app/features/settings/devices/Verification.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useState } from 'react'; +import { type MouseEventHandler, useCallback, useState } from 'react'; import { Badge, Box, @@ -13,18 +13,18 @@ import { OverlayBackdrop, OverlayCenter, IconButton, - RectCords, + type RectCords, PopOut, Menu, MenuItem, } from 'folds'; import FocusTrap from 'focus-trap-react'; -import { CryptoApi, VerificationRequest } from '$types/matrix-sdk'; +import { type CryptoApi, type VerificationRequest } from '$types/matrix-sdk'; import { VerificationStatus } from '$hooks/useDeviceVerificationStatus'; import { InfoCard } from '$components/info-card'; import { ManualVerificationTile } from '$components/ManualVerification'; -import { SecretStorageKeyContent } from '$types/matrix/accountData'; -import { AsyncState, AsyncStatus, useAsync } from '$hooks/useAsyncCallback'; +import { type SecretStorageKeyContent } from '$types/matrix/accountData'; +import { type AsyncState, AsyncStatus, useAsync } from '$hooks/useAsyncCallback'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { DeviceVerification } from '$components/DeviceVerification'; import { diff --git a/src/app/features/settings/emojis-stickers/EmojisStickers.tsx b/src/app/features/settings/emojis-stickers/EmojisStickers.tsx index d8708907c..6ceb142a6 100644 --- a/src/app/features/settings/emojis-stickers/EmojisStickers.tsx +++ b/src/app/features/settings/emojis-stickers/EmojisStickers.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { Box, Text, IconButton, Icon, Icons, Scroll } from 'folds'; import { Page, PageContent, PageHeader } from '$components/page'; -import { ImagePack } from '$plugins/custom-emoji'; +import { type ImagePack } from '$plugins/custom-emoji'; import { ImagePackView } from '$components/image-pack-view'; import { GlobalPacks } from './GlobalPacks'; import { UserPack } from './UserPack'; diff --git a/src/app/features/settings/emojis-stickers/GlobalPacks.tsx b/src/app/features/settings/emojis-stickers/GlobalPacks.tsx index 1c66d4c6f..799e709f6 100644 --- a/src/app/features/settings/emojis-stickers/GlobalPacks.tsx +++ b/src/app/features/settings/emojis-stickers/GlobalPacks.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useEffect, useMemo, useState } from 'react'; +import { type MouseEventHandler, useCallback, useEffect, useMemo, useState } from 'react'; import { Box, Text, @@ -12,7 +12,7 @@ import { config, Spinner, Menu, - RectCords, + type RectCords, PopOut, Checkbox, toRem, @@ -23,7 +23,7 @@ import { } from 'folds'; import FocusTrap from 'focus-trap-react'; import { useAtomValue } from 'jotai'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useGlobalImagePacks, useRoomsImagePacks } from '$hooks/useImagePacks'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; @@ -31,10 +31,10 @@ import { mxcUrlToHttp } from '$utils/matrix'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { - EmoteRoomsContent, - ImagePack, + type EmoteRoomsContent, + type ImagePack, ImageUsage, - PackAddress, + type PackAddress, packAddressEqual, } from '$plugins/custom-emoji'; import { LineClamp2 } from '$styles/Text.css'; diff --git a/src/app/features/settings/general/General.tsx b/src/app/features/settings/general/General.tsx index f7b8a6531..1d4bcd1e5 100644 --- a/src/app/features/settings/general/General.tsx +++ b/src/app/features/settings/general/General.tsx @@ -1,8 +1,8 @@ import { - ChangeEventHandler, - FormEventHandler, - KeyboardEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type FormEventHandler, + type KeyboardEventHandler, + type MouseEventHandler, useEffect, useState, } from 'react'; @@ -20,7 +20,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Scroll, Switch, Text, @@ -31,11 +31,11 @@ import { Page, PageContent, PageHeader } from '$components/page'; import { SequenceCard } from '$components/sequence-card'; import { useSetting } from '$state/hooks/settings'; import { - DateFormat, + type DateFormat, MessageLayout, - MessageSpacing, + type MessageSpacing, RightSwipeAction, - CaptionPosition, + type CaptionPosition, settingsAtom, } from '$state/settings'; import { SettingTile } from '$components/setting-tile'; diff --git a/src/app/features/settings/notifications/AllMessages.tsx b/src/app/features/settings/notifications/AllMessages.tsx index 5ee60a178..6fa701409 100644 --- a/src/app/features/settings/notifications/AllMessages.tsx +++ b/src/app/features/settings/notifications/AllMessages.tsx @@ -2,8 +2,8 @@ import { useCallback, useMemo } from 'react'; import { Badge, Box, Text } from 'folds'; import { ConditionKind, - IPushRules, - PushRuleCondition, + type IPushRules, + type PushRuleCondition, PushRuleKind, RuleId, } from '$types/matrix-sdk'; @@ -11,7 +11,7 @@ import { useAccountData } from '$hooks/useAccountData'; import { AccountDataEvent } from '$types/matrix/accountData'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; -import { PushRuleData, usePushRule } from '$hooks/usePushRule'; +import { type PushRuleData, usePushRule } from '$hooks/usePushRule'; import { getNotificationModeActions, NotificationMode, diff --git a/src/app/features/settings/notifications/KeywordMessages.tsx b/src/app/features/settings/notifications/KeywordMessages.tsx index ff235271f..4395d8a78 100644 --- a/src/app/features/settings/notifications/KeywordMessages.tsx +++ b/src/app/features/settings/notifications/KeywordMessages.tsx @@ -1,5 +1,11 @@ -import { ChangeEventHandler, FormEventHandler, useCallback, useMemo, useState } from 'react'; -import { IPushRule, IPushRules, PushRuleKind } from '$types/matrix-sdk'; +import { + type ChangeEventHandler, + type FormEventHandler, + useCallback, + useMemo, + useState, +} from 'react'; +import { type IPushRule, type IPushRules, PushRuleKind } from '$types/matrix-sdk'; import { Box, Text, Badge, Button, Input, config, IconButton, Icons, Icon, Spinner } from 'folds'; import { useAccountData } from '$hooks/useAccountData'; import { AccountDataEvent } from '$types/matrix/accountData'; @@ -9,7 +15,7 @@ import { useMatrixClient } from '$hooks/useMatrixClient'; import { getNotificationModeActions, NotificationMode, - NotificationModeOptions, + type NotificationModeOptions, useNotificationModeActions, } from '$hooks/useNotificationMode'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; diff --git a/src/app/features/settings/notifications/NotificationLevelsHint.tsx b/src/app/features/settings/notifications/NotificationLevelsHint.tsx index 700ca2bdb..9585a57ed 100644 --- a/src/app/features/settings/notifications/NotificationLevelsHint.tsx +++ b/src/app/features/settings/notifications/NotificationLevelsHint.tsx @@ -1,5 +1,16 @@ -import { MouseEventHandler, useState } from 'react'; -import { Box, config, Header, Icon, IconButton, Icons, Menu, PopOut, RectCords, Text } from 'folds'; +import { type MouseEventHandler, useState } from 'react'; +import { + Box, + config, + Header, + Icon, + IconButton, + Icons, + Menu, + PopOut, + type RectCords, + Text, +} from 'folds'; import FocusTrap from 'focus-trap-react'; import { stopPropagation } from '$utils/keyboard'; diff --git a/src/app/features/settings/notifications/NotificationModeSwitcher.tsx b/src/app/features/settings/notifications/NotificationModeSwitcher.tsx index 608bd5078..b76be0a83 100644 --- a/src/app/features/settings/notifications/NotificationModeSwitcher.tsx +++ b/src/app/features/settings/notifications/NotificationModeSwitcher.tsx @@ -7,12 +7,12 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Spinner, Text, } from 'folds'; -import { IPushRule } from '$types/matrix-sdk'; -import { MouseEventHandler, useMemo, useState } from 'react'; +import { type IPushRule } from '$types/matrix-sdk'; +import { type MouseEventHandler, useMemo, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { NotificationMode, useNotificationActionsMode } from '$hooks/useNotificationMode'; import { stopPropagation } from '$utils/keyboard'; diff --git a/src/app/features/settings/notifications/PushNotifications.tsx b/src/app/features/settings/notifications/PushNotifications.tsx index 46c0ebb0d..45c6526d7 100644 --- a/src/app/features/settings/notifications/PushNotifications.tsx +++ b/src/app/features/settings/notifications/PushNotifications.tsx @@ -1,6 +1,6 @@ -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { createDebugLogger } from '$utils/debugLogger'; -import { ClientConfig } from '../../../hooks/useClientConfig'; +import { type ClientConfig } from '../../../hooks/useClientConfig'; const debugLog = createDebugLogger('PushNotifications'); diff --git a/src/app/features/settings/notifications/SpecialMessages.tsx b/src/app/features/settings/notifications/SpecialMessages.tsx index ac8d736f3..f347cee17 100644 --- a/src/app/features/settings/notifications/SpecialMessages.tsx +++ b/src/app/features/settings/notifications/SpecialMessages.tsx @@ -1,5 +1,5 @@ import { useCallback, useMemo } from 'react'; -import { ConditionKind, IPushRules, PushRuleKind, RuleId } from '$types/matrix-sdk'; +import { ConditionKind, type IPushRules, PushRuleKind, RuleId } from '$types/matrix-sdk'; import { Box, Text, Badge } from 'folds'; import { useAccountData } from '$hooks/useAccountData'; import { AccountDataEvent } from '$types/matrix/accountData'; @@ -8,11 +8,11 @@ import { SettingTile } from '$components/setting-tile'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useUserProfile } from '$hooks/useUserProfile'; import { getMxIdLocalPart } from '$utils/matrix'; -import { makePushRuleData, PushRuleData, usePushRule } from '$hooks/usePushRule'; +import { makePushRuleData, type PushRuleData, usePushRule } from '$hooks/usePushRule'; import { getNotificationModeActions, NotificationMode, - NotificationModeOptions, + type NotificationModeOptions, useNotificationModeActions, } from '$hooks/useNotificationMode'; import { SequenceCardStyle } from '$features/settings/styles.css'; diff --git a/src/app/features/settings/notifications/SystemNotification.tsx b/src/app/features/settings/notifications/SystemNotification.tsx index c9b59549a..b92ea3366 100644 --- a/src/app/features/settings/notifications/SystemNotification.tsx +++ b/src/app/features/settings/notifications/SystemNotification.tsx @@ -1,7 +1,7 @@ /* eslint-disable no-nested-ternary */ import { useCallback, useEffect, useState } from 'react'; import { Box, Text, Switch, Button, color, Spinner, config } from 'folds'; -import { IPusherRequest } from '$types/matrix-sdk'; +import { type IPusherRequest } from '$types/matrix-sdk'; import { useAtom } from 'jotai'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; diff --git a/src/app/features/space-nav/SpaceNavItem.tsx b/src/app/features/space-nav/SpaceNavItem.tsx index f319a9da6..91c6d5735 100644 --- a/src/app/features/space-nav/SpaceNavItem.tsx +++ b/src/app/features/space-nav/SpaceNavItem.tsx @@ -1,6 +1,6 @@ -import { MouseEventHandler, useState } from 'react'; -import { Room } from '$types/matrix-sdk'; -import { Box, Icon, Icons, Text, config, RectCords, Avatar } from 'folds'; +import { type MouseEventHandler, useState } from 'react'; +import { type Room } from '$types/matrix-sdk'; +import { Box, Icon, Icons, Text, config, type RectCords, Avatar } from 'folds'; import { useNavigate } from 'react-router-dom'; import { NavButton, NavItem, NavItemContent } from '$components/nav'; import { useRoomName } from '$hooks/useRoomMeta'; diff --git a/src/app/features/space-settings/SpaceSettings.tsx b/src/app/features/space-settings/SpaceSettings.tsx index 586fba3f2..e2377896e 100644 --- a/src/app/features/space-settings/SpaceSettings.tsx +++ b/src/app/features/space-settings/SpaceSettings.tsx @@ -1,6 +1,6 @@ import { useMemo, useState } from 'react'; import { useAtomValue } from 'jotai'; -import { Avatar, Box, config, Icon, IconButton, Icons, IconSrc, MenuItem, Text } from 'folds'; +import { Avatar, Box, config, Icon, IconButton, Icons, type IconSrc, MenuItem, Text } from 'folds'; import { JoinRule } from '$types/matrix-sdk'; import { PageNav, PageNavContent, PageNavHeader, PageRoot } from '$components/page'; import { ScreenSize, useScreenSizeContext } from '$hooks/useScreenSize'; diff --git a/src/app/features/space-settings/SpaceSettingsRenderer.tsx b/src/app/features/space-settings/SpaceSettingsRenderer.tsx index 425428685..fe1f95624 100644 --- a/src/app/features/space-settings/SpaceSettingsRenderer.tsx +++ b/src/app/features/space-settings/SpaceSettingsRenderer.tsx @@ -1,7 +1,7 @@ import { Modal500 } from '$components/Modal500'; import { useCloseSpaceSettings, useSpaceSettingsState } from '$state/hooks/spaceSettings'; import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom'; -import { SpaceSettingsState } from '$state/spaceSettings'; +import { type SpaceSettingsState } from '$state/spaceSettings'; import { RoomProvider } from '$hooks/useRoom'; import { SpaceProvider } from '$hooks/useSpace'; import { SpaceSettings } from './SpaceSettings'; diff --git a/src/app/features/space-settings/permissions/usePermissionItems.ts b/src/app/features/space-settings/permissions/usePermissionItems.ts index cdc4f73df..573970a16 100644 --- a/src/app/features/space-settings/permissions/usePermissionItems.ts +++ b/src/app/features/space-settings/permissions/usePermissionItems.ts @@ -1,6 +1,6 @@ import { useMemo } from 'react'; import { StateEvent } from '$types/matrix/room'; -import { PermissionGroup } from '$features/common-settings/permissions'; +import { type PermissionGroup } from '$features/common-settings/permissions'; export const usePermissionGroups = (): PermissionGroup[] => { const groups: PermissionGroup[] = useMemo(() => { diff --git a/src/app/features/widgets/GenericWidgetDriver.ts b/src/app/features/widgets/GenericWidgetDriver.ts index ee143b4f3..c58752406 100644 --- a/src/app/features/widgets/GenericWidgetDriver.ts +++ b/src/app/features/widgets/GenericWidgetDriver.ts @@ -6,14 +6,14 @@ import { type IRoomEvent, type Widget, WidgetDriver, - WidgetKind, + type WidgetKind, type IWidgetApiErrorResponseDataDetails, type ISearchUserDirectoryResult, type IGetMediaConfigResult, UpdateDelayedEventAction, OpenIDRequestState, - SimpleObservable, - IOpenIDUpdate, + type SimpleObservable, + type IOpenIDUpdate, } from 'matrix-widget-api'; import { EventType, @@ -24,8 +24,8 @@ import { type SendDelayedEventResponse, type StateEvents, type TimelineEvents, - MatrixClient, - Room, + type MatrixClient, + type Room, } from '$types/matrix-sdk'; export type CapabilityApprovalCallback = (requested: Set) => Promise>; diff --git a/src/app/features/widgets/IntegrationManager.tsx b/src/app/features/widgets/IntegrationManager.tsx index 4bf242a4f..09ab8bcae 100644 --- a/src/app/features/widgets/IntegrationManager.tsx +++ b/src/app/features/widgets/IntegrationManager.tsx @@ -12,7 +12,7 @@ import { Text, } from 'folds'; import FocusTrap from 'focus-trap-react'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useIntegrationManager, buildIntegrationManagerUrl } from '$hooks/useIntegrationManager'; import * as css from './IntegrationManager.css'; diff --git a/src/app/features/widgets/WidgetIframe.tsx b/src/app/features/widgets/WidgetIframe.tsx index 844debfd2..bf63cde61 100644 --- a/src/app/features/widgets/WidgetIframe.tsx +++ b/src/app/features/widgets/WidgetIframe.tsx @@ -1,16 +1,22 @@ import { useEffect, useRef, useState } from 'react'; -import { ClientWidgetApi, IWidget, IRoomEvent, Widget, WidgetKind } from 'matrix-widget-api'; +import { + ClientWidgetApi, + type IWidget, + type IRoomEvent, + Widget, + WidgetKind, +} from 'matrix-widget-api'; import { ClientEvent, Direction, - IEvent, - MatrixClient, - MatrixEvent, + type IEvent, + type MatrixClient, + type MatrixEvent, MatrixEventEvent, } from '$types/matrix-sdk'; import { createLogger } from '$utils/debug'; import { resolveWidgetUrl } from '$hooks/useRoomWidgets'; -import { GenericWidgetDriver, CapabilityApprovalCallback } from './GenericWidgetDriver'; +import { GenericWidgetDriver, type CapabilityApprovalCallback } from './GenericWidgetDriver'; const log = createLogger('WidgetIframe'); diff --git a/src/app/features/widgets/WidgetsDrawer.tsx b/src/app/features/widgets/WidgetsDrawer.tsx index ade7699e8..9c66f2832 100644 --- a/src/app/features/widgets/WidgetsDrawer.tsx +++ b/src/app/features/widgets/WidgetsDrawer.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, MouseEventHandler, useState } from 'react'; +import { type FormEventHandler, type MouseEventHandler, useState } from 'react'; import { Box, Header, @@ -15,10 +15,10 @@ import { Button, Line, } from 'folds'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useMatrixClient } from '$hooks/useMatrixClient'; -import { useRoomWidgets, RoomWidget, enrichWidgetUrl } from '$hooks/useRoomWidgets'; +import { useRoomWidgets, type RoomWidget, enrichWidgetUrl } from '$hooks/useRoomWidgets'; import { useSetSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { usePowerLevelsContext } from '$hooks/usePowerLevels'; diff --git a/src/app/hooks/timeline/useProcessedTimeline.ts b/src/app/hooks/timeline/useProcessedTimeline.ts index f1f799308..861736f5d 100644 --- a/src/app/hooks/timeline/useProcessedTimeline.ts +++ b/src/app/hooks/timeline/useProcessedTimeline.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { MatrixEvent, EventTimelineSet, EventTimeline } from '$types/matrix-sdk'; +import { type MatrixEvent, type EventTimelineSet, type EventTimeline } from '$types/matrix-sdk'; import { getTimelineAndBaseIndex, getTimelineRelativeIndex, diff --git a/src/app/hooks/timeline/useTimelineActions.ts b/src/app/hooks/timeline/useTimelineActions.ts index e7bb45f68..a3782eea0 100644 --- a/src/app/hooks/timeline/useTimelineActions.ts +++ b/src/app/hooks/timeline/useTimelineActions.ts @@ -1,6 +1,12 @@ -import { useCallback, MouseEventHandler } from 'react'; -import { MatrixClient, Room, MatrixEvent, EventStatus, IContent } from '$types/matrix-sdk'; -import { Editor } from 'slate'; +import { useCallback, type MouseEventHandler } from 'react'; +import { + type MatrixClient, + type Room, + type MatrixEvent, + EventStatus, + type IContent, +} from '$types/matrix-sdk'; +import { type Editor } from 'slate'; import { ReactEditor } from 'slate-react'; import { getMxIdLocalPart, toggleReaction } from '$utils/matrix'; diff --git a/src/app/hooks/timeline/useTimelineEventRenderer.tsx b/src/app/hooks/timeline/useTimelineEventRenderer.tsx index f7dca411a..d7d94e49d 100644 --- a/src/app/hooks/timeline/useTimelineEventRenderer.tsx +++ b/src/app/hooks/timeline/useTimelineEventRenderer.tsx @@ -1,22 +1,22 @@ -import { MouseEventHandler, useCallback, useMemo } from 'react'; +import { type MouseEventHandler, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useAtomValue } from 'jotai'; import { - MatrixClient, - MatrixEvent, - Room, - PushProcessor, - EventTimelineSet, - IContent, + type MatrixClient, + type MatrixEvent, + type Room, + type PushProcessor, + type EventTimelineSet, + type IContent, } from '$types/matrix-sdk'; -import { SessionMembershipData } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; -import { HTMLReactParserOptions } from 'html-react-parser'; -import { Opts as LinkifyOpts } from 'linkifyjs'; +import { type SessionMembershipData } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; +import { type HTMLReactParserOptions } from 'html-react-parser'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; import { Box, Chip, Avatar, Text, Icons, config, toRem, Icon } from 'folds'; import { MessageLayout } from '$state/settings'; import { nicknamesAtom } from '$state/nicknames'; -import { useGetMemberPowerTag } from '$hooks/useMemberPowerTag'; -import { useMemberEventParser } from '$hooks/useMemberEventParser'; +import { type useGetMemberPowerTag } from '$hooks/useMemberPowerTag'; +import { type useMemberEventParser } from '$hooks/useMemberEventParser'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { useMatrixEventRenderer } from '$hooks/useMatrixEventRenderer'; @@ -35,7 +35,7 @@ import { ImageViewer } from '$components/image-viewer'; import { RenderMessageContent } from '$components/RenderMessageContent'; import { ClientSideHoverFreeze } from '$components/ClientSideHoverFreeze'; import { UserAvatar } from '$components/user-avatar'; -import { MessageEvent, StateEvent, GetContentCallback } from '$types/matrix/room'; +import { MessageEvent, StateEvent, type GetContentCallback } from '$types/matrix/room'; import { getMxIdLocalPart, mxcUrlToHttp } from '$utils/matrix'; import { getEditedEvent, @@ -50,7 +50,7 @@ import * as customHtmlCss from '$styles/CustomHtml.css'; import { EncryptedContent, Event, - ForwardedMessageProps, + type ForwardedMessageProps, Message, Reactions, } from '$features/room/message'; diff --git a/src/app/hooks/timeline/useTimelineSync.test.tsx b/src/app/hooks/timeline/useTimelineSync.test.tsx index 71fde31c2..bbedbebad 100644 --- a/src/app/hooks/timeline/useTimelineSync.test.tsx +++ b/src/app/hooks/timeline/useTimelineSync.test.tsx @@ -1,7 +1,7 @@ import { EventEmitter } from 'events'; import { act, renderHook } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; -import { Room, RoomEvent } from '$types/matrix-sdk'; +import { type Room, RoomEvent } from '$types/matrix-sdk'; import { useTimelineSync } from './useTimelineSync'; vi.mock('@sentry/react', () => ({ diff --git a/src/app/hooks/timeline/useTimelineSync.ts b/src/app/hooks/timeline/useTimelineSync.ts index 395d6fc46..62c525f13 100644 --- a/src/app/hooks/timeline/useTimelineSync.ts +++ b/src/app/hooks/timeline/useTimelineSync.ts @@ -1,16 +1,24 @@ -import { useState, useMemo, useCallback, useRef, useEffect, Dispatch, SetStateAction } from 'react'; +import { + useState, + useMemo, + useCallback, + useRef, + useEffect, + type Dispatch, + type SetStateAction, +} from 'react'; import to from 'await-to-js'; import * as Sentry from '@sentry/react'; import { - MatrixClient, - Room, - MatrixEvent, + type MatrixClient, + type Room, + type MatrixEvent, Direction, - EventTimeline, - EventTimelineSetHandlerMap, + type EventTimeline, + type EventTimelineSetHandlerMap, RoomEvent, - IRoomTimelineData, - RoomEventHandlerMap, + type IRoomTimelineData, + type RoomEventHandlerMap, RelationType, ThreadEvent, } from '$types/matrix-sdk'; diff --git a/src/app/hooks/types.ts b/src/app/hooks/types.ts index 781eb90ca..37c5e42ca 100644 --- a/src/app/hooks/types.ts +++ b/src/app/hooks/types.ts @@ -1,4 +1,4 @@ -import { IRequestTokenResponse } from '$types/matrix-sdk'; +import { type IRequestTokenResponse } from '$types/matrix-sdk'; export type RequestEmailTokenResponse = { email: string; diff --git a/src/app/hooks/useAccountData.ts b/src/app/hooks/useAccountData.ts index 11d3d5b42..ca90d866c 100644 --- a/src/app/hooks/useAccountData.ts +++ b/src/app/hooks/useAccountData.ts @@ -1,5 +1,5 @@ import { useState, useCallback } from 'react'; -import { AccountDataEvents } from '$types/matrix-sdk'; +import { type AccountDataEvents } from '$types/matrix-sdk'; import { useMatrixClient } from './useMatrixClient'; import { useAccountDataCallback } from './useAccountDataCallback'; diff --git a/src/app/hooks/useAccountDataCallback.ts b/src/app/hooks/useAccountDataCallback.ts index 97c350446..7c4995707 100644 --- a/src/app/hooks/useAccountDataCallback.ts +++ b/src/app/hooks/useAccountDataCallback.ts @@ -1,4 +1,4 @@ -import { ClientEvent, ClientEventHandlerMap, MatrixClient } from '$types/matrix-sdk'; +import { ClientEvent, type ClientEventHandlerMap, type MatrixClient } from '$types/matrix-sdk'; import { useEffect } from 'react'; export const useAccountDataCallback = ( diff --git a/src/app/hooks/useAppVisibility.ts b/src/app/hooks/useAppVisibility.ts index 7fd5f2325..4dc9a5be7 100644 --- a/src/app/hooks/useAppVisibility.ts +++ b/src/app/hooks/useAppVisibility.ts @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { useAtom } from 'jotai'; import { togglePusher } from '../features/settings/notifications/PushNotifications'; import { appEvents } from '../utils/appEvents'; diff --git a/src/app/hooks/useAsyncCallback.ts b/src/app/hooks/useAsyncCallback.ts index 70831bea1..f06c0060b 100644 --- a/src/app/hooks/useAsyncCallback.ts +++ b/src/app/hooks/useAsyncCallback.ts @@ -1,4 +1,11 @@ -import { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react'; +import { + type Dispatch, + type SetStateAction, + useCallback, + useEffect, + useRef, + useState, +} from 'react'; import { flushSync } from 'react-dom'; import { useAlive } from './useAlive'; diff --git a/src/app/hooks/useAsyncSearch.ts b/src/app/hooks/useAsyncSearch.ts index ebf78b8be..5ab436d09 100644 --- a/src/app/hooks/useAsyncSearch.ts +++ b/src/app/hooks/useAsyncSearch.ts @@ -1,14 +1,14 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { - MatchHandler, + type MatchHandler, AsyncSearch, - AsyncSearchHandler, - AsyncSearchOption, - MatchQueryOption, - NormalizeOption, + type AsyncSearchHandler, + type AsyncSearchOption, + type MatchQueryOption, + type NormalizeOption, normalize, matchQuery, - ResultHandler, + type ResultHandler, } from '$utils/AsyncSearch'; import { sanitizeForRegex } from '$utils/regex'; diff --git a/src/app/hooks/useAuthFlows.ts b/src/app/hooks/useAuthFlows.ts index 8d82435e2..a1791b86e 100644 --- a/src/app/hooks/useAuthFlows.ts +++ b/src/app/hooks/useAuthFlows.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { IAuthData, MatrixError, ILoginFlowsResponse } from '$types/matrix-sdk'; +import { type IAuthData, type MatrixError, type ILoginFlowsResponse } from '$types/matrix-sdk'; export enum RegisterFlowStatus { FlowRequired = 401, diff --git a/src/app/hooks/useAuthMetadata.ts b/src/app/hooks/useAuthMetadata.ts index a24859093..42830c443 100644 --- a/src/app/hooks/useAuthMetadata.ts +++ b/src/app/hooks/useAuthMetadata.ts @@ -1,4 +1,4 @@ -import { ValidatedAuthMetadata } from '$types/matrix-sdk'; +import { type ValidatedAuthMetadata } from '$types/matrix-sdk'; import { createContext, useContext } from 'react'; const AuthMetadataContext = createContext(undefined); diff --git a/src/app/hooks/useAutoDiscoveryInfo.ts b/src/app/hooks/useAutoDiscoveryInfo.ts index b2f8bcb56..9d570d467 100644 --- a/src/app/hooks/useAutoDiscoveryInfo.ts +++ b/src/app/hooks/useAutoDiscoveryInfo.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { AutoDiscoveryInfo } from '../cs-api'; +import { type AutoDiscoveryInfo } from '../cs-api'; const AutoDiscoverInfoContext = createContext(null); diff --git a/src/app/hooks/useCall.ts b/src/app/hooks/useCall.ts index 1364e4598..9ec13122d 100644 --- a/src/app/hooks/useCall.ts +++ b/src/app/hooks/useCall.ts @@ -1,9 +1,9 @@ -import { Room } from 'matrix-js-sdk'; +import { type Room } from 'matrix-js-sdk'; import { MatrixRTCSession, MatrixRTCSessionEvent, } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSession'; -import { CallMembership } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; +import { type CallMembership } from 'matrix-js-sdk/lib/matrixrtc/CallMembership'; import { useEffect, useState } from 'react'; import { MatrixRTCSessionManagerEvents } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSessionManager'; import { useMatrixClient } from './useMatrixClient'; diff --git a/src/app/hooks/useCallEmbed.ts b/src/app/hooks/useCallEmbed.ts index aa3466193..14a90a315 100644 --- a/src/app/hooks/useCallEmbed.ts +++ b/src/app/hooks/useCallEmbed.ts @@ -1,11 +1,11 @@ -import { createContext, RefObject, useCallback, useContext, useEffect, useState } from 'react'; +import { createContext, type RefObject, useCallback, useContext, useEffect, useState } from 'react'; import { MatrixRTCSession } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSession'; -import { MatrixClient, Room } from 'matrix-js-sdk'; +import { type MatrixClient, type Room } from 'matrix-js-sdk'; import { useSetAtom } from 'jotai'; import * as Sentry from '@sentry/react'; import { CallEmbed, - ElementCallThemeKind, + type ElementCallThemeKind, ElementWidgetActions, useClientWidgetApiEvent, } from '../plugins/call'; @@ -15,7 +15,7 @@ import { callEmbedAtom } from '../state/callEmbed'; import { useResizeObserver } from './useResizeObserver'; import { CallControlState } from '../plugins/call/CallControlState'; import { useCallMembersChange, useCallSession } from './useCall'; -import { CallPreferences } from '../state/callPreferences'; +import { type CallPreferences } from '../state/callPreferences'; import { createDebugLogger } from '../utils/debugLogger'; const debugLog = createDebugLogger('useCallEmbed'); diff --git a/src/app/hooks/useCallSpeakers.ts b/src/app/hooks/useCallSpeakers.ts index 240036785..4e18fce14 100644 --- a/src/app/hooks/useCallSpeakers.ts +++ b/src/app/hooks/useCallSpeakers.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; -import { CallEmbed } from '../plugins/call'; +import { type CallEmbed } from '../plugins/call'; import { useMutationObserver } from './useMutationObserver'; import { isUserId } from '../utils/matrix'; import { useCallMembers, useCallSession } from './useCall'; diff --git a/src/app/hooks/useCapabilities.ts b/src/app/hooks/useCapabilities.ts index 6e84090e7..3022347b6 100644 --- a/src/app/hooks/useCapabilities.ts +++ b/src/app/hooks/useCapabilities.ts @@ -1,4 +1,4 @@ -import { Capabilities } from '$types/matrix-sdk'; +import { type Capabilities } from '$types/matrix-sdk'; import { createContext, useContext } from 'react'; const CapabilitiesContext = createContext(null); diff --git a/src/app/hooks/useCategoryHandler.ts b/src/app/hooks/useCategoryHandler.ts index 086902d63..434a5120f 100644 --- a/src/app/hooks/useCategoryHandler.ts +++ b/src/app/hooks/useCategoryHandler.ts @@ -1,4 +1,4 @@ -import { MouseEventHandler } from 'react'; +import { type MouseEventHandler } from 'react'; type CategoryAction = | { diff --git a/src/app/hooks/useCommands.ts b/src/app/hooks/useCommands.ts index edd901d98..91c610ca3 100644 --- a/src/app/hooks/useCommands.ts +++ b/src/app/hooks/useCommands.ts @@ -1,14 +1,14 @@ import { Direction, EventTimeline, - IContextResponse, - MatrixClient, + type IContextResponse, + type MatrixClient, Method, Preset, - Room, - RoomMember, + type Room, + type RoomMember, Visibility, - RoomServerAclEventContent, + type RoomServerAclEventContent, MsgType, } from '$types/matrix-sdk'; import { useMemo } from 'react'; @@ -38,7 +38,7 @@ import { useUserProfile } from './useUserProfile'; import { addOrUpdatePerMessageProfile, deletePerMessageProfile, - PerMessageProfile, + type PerMessageProfile, setCurrentlyUsedPerMessageProfileIdForRoom, } from './usePerMessageProfile'; diff --git a/src/app/hooks/useCrossSigning.ts b/src/app/hooks/useCrossSigning.ts index b280ecfdc..776ce9ddb 100644 --- a/src/app/hooks/useCrossSigning.ts +++ b/src/app/hooks/useCrossSigning.ts @@ -1,4 +1,4 @@ -import { AccountDataEvent, SecretAccountData } from '$types/matrix/accountData'; +import { AccountDataEvent, type SecretAccountData } from '$types/matrix/accountData'; import { useAccountData } from './useAccountData'; export const useCrossSigningActive = (): boolean => { diff --git a/src/app/hooks/useDateFormat.ts b/src/app/hooks/useDateFormat.ts index 497173101..05de45b29 100644 --- a/src/app/hooks/useDateFormat.ts +++ b/src/app/hooks/useDateFormat.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { DateFormat } from '$state/settings'; +import { type DateFormat } from '$state/settings'; export type DateFormatItem = { name: string; diff --git a/src/app/hooks/useDeviceList.ts b/src/app/hooks/useDeviceList.ts index 965784125..06b3bb73f 100644 --- a/src/app/hooks/useDeviceList.ts +++ b/src/app/hooks/useDeviceList.ts @@ -1,5 +1,5 @@ import { useEffect, useCallback, useMemo } from 'react'; -import { IMyDevice, CryptoEvent, CryptoEventHandlerMap } from '$types/matrix-sdk'; +import { type IMyDevice, CryptoEvent, type CryptoEventHandlerMap } from '$types/matrix-sdk'; import { useQuery } from '@tanstack/react-query'; import { useMatrixClient } from './useMatrixClient'; diff --git a/src/app/hooks/useDeviceVerificationStatus.ts b/src/app/hooks/useDeviceVerificationStatus.ts index 4d2ea071f..95e24b27c 100644 --- a/src/app/hooks/useDeviceVerificationStatus.ts +++ b/src/app/hooks/useDeviceVerificationStatus.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from 'react'; -import { CryptoApi } from '$types/matrix-sdk'; +import { type CryptoApi } from '$types/matrix-sdk'; import { verifiedDevice } from '$utils/matrix-crypto'; import { fulfilledPromiseSettledResult } from '$utils/common'; import { useAlive } from './useAlive'; diff --git a/src/app/hooks/useDirectUsers.ts b/src/app/hooks/useDirectUsers.ts index ea412fb65..9f65bfc74 100644 --- a/src/app/hooks/useDirectUsers.ts +++ b/src/app/hooks/useDirectUsers.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { AccountDataEvent, MDirectContent } from '$types/matrix/accountData'; +import { AccountDataEvent, type MDirectContent } from '$types/matrix/accountData'; import { useAccountData } from './useAccountData'; import { useAllJoinedRoomsSet, useGetRoom } from './useGetRoom'; diff --git a/src/app/hooks/useFileDrop.ts b/src/app/hooks/useFileDrop.ts index 7922c336d..ff95f8b62 100644 --- a/src/app/hooks/useFileDrop.ts +++ b/src/app/hooks/useFileDrop.ts @@ -1,4 +1,11 @@ -import { useCallback, DragEventHandler, RefObject, useState, useEffect, useRef } from 'react'; +import { + useCallback, + type DragEventHandler, + type RefObject, + useState, + useEffect, + useRef, +} from 'react'; import { getDataTransferFiles } from '$utils/dom'; export const useFileDropHandler = (onDrop: (file: File[]) => void): DragEventHandler => diff --git a/src/app/hooks/useFilePasteHandler.ts b/src/app/hooks/useFilePasteHandler.ts index 253ad9b3b..197a8f85c 100644 --- a/src/app/hooks/useFilePasteHandler.ts +++ b/src/app/hooks/useFilePasteHandler.ts @@ -1,4 +1,4 @@ -import { useCallback, ClipboardEventHandler } from 'react'; +import { useCallback, type ClipboardEventHandler } from 'react'; import { getDataTransferFiles } from '$utils/dom'; export const useFilePasteHandler = (onPaste: (file: File[]) => void): ClipboardEventHandler => diff --git a/src/app/hooks/useGetRoom.ts b/src/app/hooks/useGetRoom.ts index 6ab37b795..671b72fa4 100644 --- a/src/app/hooks/useGetRoom.ts +++ b/src/app/hooks/useGetRoom.ts @@ -1,4 +1,4 @@ -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useAtomValue } from 'jotai'; import { useCallback, useMemo } from 'react'; import { allRoomsAtom } from '$state/room-list/roomList'; diff --git a/src/app/hooks/useGroupDMMembers.ts b/src/app/hooks/useGroupDMMembers.ts index a3ab796a1..2908e3a0b 100644 --- a/src/app/hooks/useGroupDMMembers.ts +++ b/src/app/hooks/useGroupDMMembers.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { MatrixClient, Room } from '$types/matrix-sdk'; +import { type MatrixClient, type Room } from '$types/matrix-sdk'; export type GroupMemberInfo = { userId: string; diff --git a/src/app/hooks/useImagePackRooms.ts b/src/app/hooks/useImagePackRooms.ts index b2163a726..6e22886e3 100644 --- a/src/app/hooks/useImagePackRooms.ts +++ b/src/app/hooks/useImagePackRooms.ts @@ -1,4 +1,4 @@ -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useMemo } from 'react'; import { getAllParents } from '$utils/room'; import { useMatrixClient } from './useMatrixClient'; diff --git a/src/app/hooks/useImagePacks.ts b/src/app/hooks/useImagePacks.ts index 7146966b2..47c6cbedd 100644 --- a/src/app/hooks/useImagePacks.ts +++ b/src/app/hooks/useImagePacks.ts @@ -1,4 +1,4 @@ -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { AccountDataEvent } from '$types/matrix/accountData'; import { StateEvent } from '$types/matrix/room'; @@ -8,8 +8,8 @@ import { getRoomImagePacks, getUserImagePack, globalPacksScope, - ImagePack, - ImageUsage, + type ImagePack, + type ImageUsage, readCachedPack, readCachedPacks, roomPacksScope, diff --git a/src/app/hooks/useIntegrationManager.ts b/src/app/hooks/useIntegrationManager.ts index 00feba387..c84d98d97 100644 --- a/src/app/hooks/useIntegrationManager.ts +++ b/src/app/hooks/useIntegrationManager.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from 'react'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { useMatrixClient } from './useMatrixClient'; export interface IntegrationManager { diff --git a/src/app/hooks/useKeyBackup.ts b/src/app/hooks/useKeyBackup.ts index 3714ec6be..48b0751c8 100644 --- a/src/app/hooks/useKeyBackup.ts +++ b/src/app/hooks/useKeyBackup.ts @@ -1,9 +1,9 @@ import { - BackupTrustInfo, - CryptoApi, + type BackupTrustInfo, + type CryptoApi, CryptoEvent, - CryptoEventHandlerMap, - KeyBackupInfo, + type CryptoEventHandlerMap, + type KeyBackupInfo, } from '$types/matrix-sdk'; import { useCallback, useEffect, useState } from 'react'; import * as Sentry from '@sentry/react'; diff --git a/src/app/hooks/useLivekitSupport.ts b/src/app/hooks/useLivekitSupport.ts index 3cb2c1d88..b38bc12ca 100644 --- a/src/app/hooks/useLivekitSupport.ts +++ b/src/app/hooks/useLivekitSupport.ts @@ -1,4 +1,4 @@ -import { AutoDiscoveryInfo } from '../cs-api'; +import { type AutoDiscoveryInfo } from '../cs-api'; import { useAutoDiscoveryInfo } from './useAutoDiscoveryInfo'; export const livekitSupport = (autoDiscoveryInfo: AutoDiscoveryInfo): boolean => { diff --git a/src/app/hooks/useLocalRoomSummary.ts b/src/app/hooks/useLocalRoomSummary.ts index 043d09f7b..3cd38330a 100644 --- a/src/app/hooks/useLocalRoomSummary.ts +++ b/src/app/hooks/useLocalRoomSummary.ts @@ -1,4 +1,4 @@ -import { GuestAccess, HistoryVisibility, JoinRule, Room } from '$types/matrix-sdk'; +import { GuestAccess, HistoryVisibility, type JoinRule, type Room } from '$types/matrix-sdk'; import { StateEvent } from '$types/matrix/room'; import { getStateEvent } from '$utils/room'; diff --git a/src/app/hooks/useMatrixClient.ts b/src/app/hooks/useMatrixClient.ts index f12365351..6b1310d7f 100644 --- a/src/app/hooks/useMatrixClient.ts +++ b/src/app/hooks/useMatrixClient.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; const MatrixClientContext = createContext(null); diff --git a/src/app/hooks/useMatrixEventRenderer.ts b/src/app/hooks/useMatrixEventRenderer.ts index 57d56cc1c..f08258009 100644 --- a/src/app/hooks/useMatrixEventRenderer.ts +++ b/src/app/hooks/useMatrixEventRenderer.ts @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; export type EventRenderer = (...args: T) => ReactNode; diff --git a/src/app/hooks/useMemberEventParser.tsx b/src/app/hooks/useMemberEventParser.tsx index 2791cef4d..19a1bf57b 100644 --- a/src/app/hooks/useMemberEventParser.tsx +++ b/src/app/hooks/useMemberEventParser.tsx @@ -1,7 +1,7 @@ -import { MouseEventHandler, useCallback, ReactNode } from 'react'; -import { IconSrc, Icons, Text } from 'folds'; -import { MatrixEvent, Room } from '$types/matrix-sdk'; -import { IMemberContent, Membership } from '$types/matrix/room'; +import { type MouseEventHandler, useCallback, type ReactNode } from 'react'; +import { type IconSrc, Icons, Text } from 'folds'; +import { type MatrixEvent, type Room } from '$types/matrix-sdk'; +import { type IMemberContent, Membership } from '$types/matrix/room'; import { getMxIdLocalPart } from '$utils/matrix'; import { isMembershipChanged } from '$utils/room'; import { useOpenUserRoomProfile } from '$state/hooks/userRoomProfile'; diff --git a/src/app/hooks/useMemberFilter.ts b/src/app/hooks/useMemberFilter.ts index 3ce50a5bd..fb40fc2c4 100644 --- a/src/app/hooks/useMemberFilter.ts +++ b/src/app/hooks/useMemberFilter.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { RoomMember } from '$types/matrix-sdk'; +import { type RoomMember } from '$types/matrix-sdk'; import { Membership } from '$types/matrix/room'; export const MembershipFilter = { diff --git a/src/app/hooks/useMemberPowerCompare.ts b/src/app/hooks/useMemberPowerCompare.ts index 72163edfc..3380377b0 100644 --- a/src/app/hooks/useMemberPowerCompare.ts +++ b/src/app/hooks/useMemberPowerCompare.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import { IPowerLevels, readPowerLevel } from './usePowerLevels'; +import { type IPowerLevels, readPowerLevel } from './usePowerLevels'; export const useMemberPowerCompare = (creators: Set, powerLevels: IPowerLevels) => { /** diff --git a/src/app/hooks/useMemberPowerTag.ts b/src/app/hooks/useMemberPowerTag.ts index ac2df17c4..727daad09 100644 --- a/src/app/hooks/useMemberPowerTag.ts +++ b/src/app/hooks/useMemberPowerTag.ts @@ -1,11 +1,11 @@ import { useCallback, useMemo } from 'react'; -import { MatrixClient, Room, RoomMember } from '$types/matrix-sdk'; -import { MemberPowerTag, MemberPowerTagIcon } from '$types/matrix/room'; +import { type MatrixClient, type Room, type RoomMember } from '$types/matrix-sdk'; +import { type MemberPowerTag, type MemberPowerTagIcon } from '$types/matrix/room'; import { accessibleColor } from '$plugins/color'; -import { getPowerLevelTag, PowerLevelTags, usePowerLevelTags } from './usePowerLevelTags'; -import { IPowerLevels, readPowerLevel } from './usePowerLevels'; +import { getPowerLevelTag, type PowerLevelTags, usePowerLevelTags } from './usePowerLevelTags'; +import { type IPowerLevels, readPowerLevel } from './usePowerLevels'; import { useRoomCreatorsTag } from './useRoomCreatorsTag'; -import { ThemeKind } from './useTheme'; +import { type ThemeKind } from './useTheme'; export type GetMemberPowerTag = (userId: string) => MemberPowerTag; diff --git a/src/app/hooks/useMemberSort.ts b/src/app/hooks/useMemberSort.ts index 72e0581da..af82c3a4d 100644 --- a/src/app/hooks/useMemberSort.ts +++ b/src/app/hooks/useMemberSort.ts @@ -1,4 +1,4 @@ -import { RoomMember } from '$types/matrix-sdk'; +import { type RoomMember } from '$types/matrix-sdk'; import { useCallback, useMemo } from 'react'; export const MemberSort = { diff --git a/src/app/hooks/useMembership.ts b/src/app/hooks/useMembership.ts index 47044c381..6957e7fc6 100644 --- a/src/app/hooks/useMembership.ts +++ b/src/app/hooks/useMembership.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Room, RoomMemberEvent, RoomMemberEventHandlerMap } from '$types/matrix-sdk'; +import { type Room, RoomMemberEvent, type RoomMemberEventHandlerMap } from '$types/matrix-sdk'; import { Membership } from '$types/matrix/room'; export const useMembership = (room: Room, userId: string): Membership => { diff --git a/src/app/hooks/useMentionClickHandler.ts b/src/app/hooks/useMentionClickHandler.ts index aadfb9826..1e736257f 100644 --- a/src/app/hooks/useMentionClickHandler.ts +++ b/src/app/hooks/useMentionClickHandler.ts @@ -1,8 +1,8 @@ -import { ReactEventHandler, useCallback } from 'react'; +import { type ReactEventHandler, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { isRoomId, isUserId } from '$utils/matrix'; import { getHomeRoomPath, withSearchParam } from '$pages/pathUtils'; -import { RoomSearchParams } from '$pages/paths'; +import { type RoomSearchParams } from '$pages/paths'; import { useOpenUserRoomProfile } from '$state/hooks/userRoomProfile'; import { useMatrixClient } from './useMatrixClient'; import { useRoomNavigate } from './useRoomNavigate'; diff --git a/src/app/hooks/useMessageSpacing.ts b/src/app/hooks/useMessageSpacing.ts index aab6cb531..33647903f 100644 --- a/src/app/hooks/useMessageSpacing.ts +++ b/src/app/hooks/useMessageSpacing.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { MessageSpacing } from '$state/settings'; +import { type MessageSpacing } from '$state/settings'; export type MessageSpacingItem = { name: string; diff --git a/src/app/hooks/useMutualRooms.ts b/src/app/hooks/useMutualRooms.ts index d0cbefe7e..2c10dfd6a 100644 --- a/src/app/hooks/useMutualRooms.ts +++ b/src/app/hooks/useMutualRooms.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react'; import { useMatrixClient } from './useMatrixClient'; -import { AsyncState, useAsyncCallbackValue } from './useAsyncCallback'; +import { type AsyncState, useAsyncCallbackValue } from './useAsyncCallback'; import { useSpecVersions } from './useSpecVersions'; export const useMutualRoomsSupport = (): boolean => { diff --git a/src/app/hooks/useNickname.ts b/src/app/hooks/useNickname.ts index 999a668dd..56c65496f 100644 --- a/src/app/hooks/useNickname.ts +++ b/src/app/hooks/useNickname.ts @@ -1,6 +1,6 @@ import { useAtomValue, useSetAtom } from 'jotai'; import { useCallback, useEffect } from 'react'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { AccountDataEvent } from '$types/matrix/accountData'; import { nicknamesAtom, setNicknameAtom } from '$state/nicknames'; import { useAccountDataCallback } from './useAccountDataCallback'; diff --git a/src/app/hooks/useNotificationMode.ts b/src/app/hooks/useNotificationMode.ts index 7901c80a2..d537398fc 100644 --- a/src/app/hooks/useNotificationMode.ts +++ b/src/app/hooks/useNotificationMode.ts @@ -1,4 +1,4 @@ -import { PushRuleAction, PushRuleActionName, TweakName } from '$types/matrix-sdk'; +import { type PushRuleAction, PushRuleActionName, TweakName } from '$types/matrix-sdk'; import { useCallback, useMemo } from 'react'; export enum NotificationMode { diff --git a/src/app/hooks/useParsedLoginFlows.ts b/src/app/hooks/useParsedLoginFlows.ts index 8095ef37a..85605ef7e 100644 --- a/src/app/hooks/useParsedLoginFlows.ts +++ b/src/app/hooks/useParsedLoginFlows.ts @@ -1,5 +1,10 @@ import { useMemo } from 'react'; -import { ILoginFlow, IPasswordFlow, ISSOFlow, LoginFlow } from '$types/matrix-sdk'; +import { + type ILoginFlow, + type IPasswordFlow, + type ISSOFlow, + type LoginFlow, +} from '$types/matrix-sdk'; export const getSSOFlow = (loginFlows: LoginFlow[]): ISSOFlow | undefined => loginFlows.find((flow) => flow.type === 'm.login.sso' || flow.type === 'm.login.cas') as diff --git a/src/app/hooks/usePasswordEmail.ts b/src/app/hooks/usePasswordEmail.ts index dbe39010d..bc2169cf5 100644 --- a/src/app/hooks/usePasswordEmail.ts +++ b/src/app/hooks/usePasswordEmail.ts @@ -1,7 +1,7 @@ -import { MatrixClient, MatrixError } from '$types/matrix-sdk'; +import { type MatrixClient, type MatrixError } from '$types/matrix-sdk'; import { useCallback, useRef } from 'react'; -import { AsyncState, useAsyncCallback } from './useAsyncCallback'; -import { RequestEmailTokenCallback, RequestEmailTokenResponse } from './types'; +import { type AsyncState, useAsyncCallback } from './useAsyncCallback'; +import { type RequestEmailTokenCallback, type RequestEmailTokenResponse } from './types'; export const usePasswordEmail = ( mx: MatrixClient diff --git a/src/app/hooks/usePerMessageProfile.ts b/src/app/hooks/usePerMessageProfile.ts index 966db2af9..dced8f01e 100644 --- a/src/app/hooks/usePerMessageProfile.ts +++ b/src/app/hooks/usePerMessageProfile.ts @@ -1,5 +1,5 @@ -import { PronounSet } from '$utils/pronouns'; -import { MatrixClient } from 'matrix-js-sdk'; +import { type PronounSet } from '$utils/pronouns'; +import { type MatrixClient } from 'matrix-js-sdk'; const ACCOUNT_DATA_PREFIX = 'fyi.cisnt.permessageprofile'; diff --git a/src/app/hooks/usePowerLevelTags.ts b/src/app/hooks/usePowerLevelTags.ts index eab9cc1f7..6b5407cdd 100644 --- a/src/app/hooks/usePowerLevelTags.ts +++ b/src/app/hooks/usePowerLevelTags.ts @@ -1,7 +1,7 @@ -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useMemo } from 'react'; -import { MemberPowerTag, StateEvent } from '$types/matrix/room'; -import { IPowerLevels } from './usePowerLevels'; +import { type MemberPowerTag, StateEvent } from '$types/matrix/room'; +import { type IPowerLevels } from './usePowerLevels'; import { useStateEvent } from './useStateEvent'; export type PowerLevelTags = Record; diff --git a/src/app/hooks/usePowerLevels.ts b/src/app/hooks/usePowerLevels.ts index 4b1b874b4..2332f3354 100644 --- a/src/app/hooks/usePowerLevels.ts +++ b/src/app/hooks/usePowerLevels.ts @@ -1,4 +1,4 @@ -import { MatrixEvent, Room } from '$types/matrix-sdk'; +import { type MatrixEvent, type Room } from '$types/matrix-sdk'; import { createContext, useCallback, useContext, useMemo, useState } from 'react'; import { produce } from 'immer'; import { StateEvent } from '$types/matrix/room'; diff --git a/src/app/hooks/usePushRule.ts b/src/app/hooks/usePushRule.ts index 32c9c3133..6a845115d 100644 --- a/src/app/hooks/usePushRule.ts +++ b/src/app/hooks/usePushRule.ts @@ -1,10 +1,10 @@ import { - IPushRule, - IPushRules, - PushRuleAction, - PushRuleCondition, + type IPushRule, + type IPushRules, + type PushRuleAction, + type PushRuleCondition, PushRuleKind, - RuleId, + type RuleId, } from '$types/matrix-sdk'; import { useMemo } from 'react'; diff --git a/src/app/hooks/useRecentEmoji.ts b/src/app/hooks/useRecentEmoji.ts index 09c356795..44609c506 100644 --- a/src/app/hooks/useRecentEmoji.ts +++ b/src/app/hooks/useRecentEmoji.ts @@ -1,8 +1,8 @@ import { useEffect, useState } from 'react'; -import { ClientEvent, MatrixClient, MatrixEvent } from '$types/matrix-sdk'; +import { ClientEvent, type MatrixClient, type MatrixEvent } from '$types/matrix-sdk'; import { AccountDataEvent } from '$types/matrix/accountData'; import { getRecentEmojis } from '$plugins/recent-emoji'; -import { IEmoji } from '$plugins/emoji'; +import { type IEmoji } from '$plugins/emoji'; export const useRecentEmoji = (mx: MatrixClient, limit?: number): IEmoji[] => { const [recentEmoji, setRecentEmoji] = useState(() => getRecentEmojis(mx, limit)); diff --git a/src/app/hooks/useRegisterEmail.ts b/src/app/hooks/useRegisterEmail.ts index 9124f116f..d311d9b0e 100644 --- a/src/app/hooks/useRegisterEmail.ts +++ b/src/app/hooks/useRegisterEmail.ts @@ -1,7 +1,7 @@ -import { MatrixClient, MatrixError } from '$types/matrix-sdk'; +import { type MatrixClient, type MatrixError } from '$types/matrix-sdk'; import { useCallback, useRef } from 'react'; -import { AsyncState, useAsyncCallback } from './useAsyncCallback'; -import { RequestEmailTokenCallback, RequestEmailTokenResponse } from './types'; +import { type AsyncState, useAsyncCallback } from './useAsyncCallback'; +import { type RequestEmailTokenCallback, type RequestEmailTokenResponse } from './types'; export const useRegisterEmail = ( mx: MatrixClient diff --git a/src/app/hooks/useRoom.ts b/src/app/hooks/useRoom.ts index 80b148115..5de2f999c 100644 --- a/src/app/hooks/useRoom.ts +++ b/src/app/hooks/useRoom.ts @@ -1,4 +1,4 @@ -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { createContext, useContext } from 'react'; const RoomContext = createContext(null); diff --git a/src/app/hooks/useRoomAbbreviations.ts b/src/app/hooks/useRoomAbbreviations.ts index e2641b341..91a2b35a7 100644 --- a/src/app/hooks/useRoomAbbreviations.ts +++ b/src/app/hooks/useRoomAbbreviations.ts @@ -1,8 +1,8 @@ import { createContext, useContext, useCallback, useMemo } from 'react'; import { useAtomValue } from 'jotai'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { StateEvent } from '$types/matrix/room'; -import { buildAbbreviationsMap, RoomAbbreviationsContent } from '$utils/abbreviations'; +import { buildAbbreviationsMap, type RoomAbbreviationsContent } from '$utils/abbreviations'; import { getAllParents, getStateEvent } from '$utils/room'; import { roomToParentsAtom } from '$state/room/roomToParents'; import { useMatrixClient } from './useMatrixClient'; diff --git a/src/app/hooks/useRoomAccountData.ts b/src/app/hooks/useRoomAccountData.ts index 4d246fe49..5fd4ff520 100644 --- a/src/app/hooks/useRoomAccountData.ts +++ b/src/app/hooks/useRoomAccountData.ts @@ -1,4 +1,4 @@ -import { Room, RoomEvent, RoomEventHandlerMap } from '$types/matrix-sdk'; +import { type Room, RoomEvent, type RoomEventHandlerMap } from '$types/matrix-sdk'; import { useCallback, useEffect, useState } from 'react'; export const useRoomAccountData = (room: Room): Map => { diff --git a/src/app/hooks/useRoomAliases.ts b/src/app/hooks/useRoomAliases.ts index 36fff1ad9..ab6fcabae 100644 --- a/src/app/hooks/useRoomAliases.ts +++ b/src/app/hooks/useRoomAliases.ts @@ -1,8 +1,12 @@ import { useCallback, useEffect, useMemo } from 'react'; -import { MatrixError, Room, RoomCanonicalAliasEventContent } from '$types/matrix-sdk'; +import { + type MatrixError, + type Room, + type RoomCanonicalAliasEventContent, +} from '$types/matrix-sdk'; import { StateEvent } from '$types/matrix/room'; import { getStateEvent } from '$utils/room'; -import { AsyncState, useAsyncCallback } from './useAsyncCallback'; +import { type AsyncState, useAsyncCallback } from './useAsyncCallback'; import { useMatrixClient } from './useMatrixClient'; import { useAlive } from './useAlive'; import { useStateEvent } from './useStateEvent'; diff --git a/src/app/hooks/useRoomCreators.ts b/src/app/hooks/useRoomCreators.ts index 6c4f740c1..f041d0682 100644 --- a/src/app/hooks/useRoomCreators.ts +++ b/src/app/hooks/useRoomCreators.ts @@ -1,6 +1,6 @@ -import { MatrixClient, MatrixEvent, Room } from '$types/matrix-sdk'; +import { type MatrixClient, type MatrixEvent, type Room } from '$types/matrix-sdk'; import { useMemo } from 'react'; -import { IRoomCreateContent, StateEvent } from '$types/matrix/room'; +import { type IRoomCreateContent, StateEvent } from '$types/matrix/room'; import { creatorsSupported } from '$utils/matrix'; import { getStateEvent } from '$utils/room'; import { useStateEvent } from './useStateEvent'; diff --git a/src/app/hooks/useRoomCreatorsTag.ts b/src/app/hooks/useRoomCreatorsTag.ts index f1a31de15..081d61d43 100644 --- a/src/app/hooks/useRoomCreatorsTag.ts +++ b/src/app/hooks/useRoomCreatorsTag.ts @@ -1,4 +1,4 @@ -import { MemberPowerTag } from '$types/matrix/room'; +import { type MemberPowerTag } from '$types/matrix/room'; const DEFAULT_TAG: MemberPowerTag = { name: 'Founder', diff --git a/src/app/hooks/useRoomEvent.ts b/src/app/hooks/useRoomEvent.ts index 703353669..f5bf22dcb 100644 --- a/src/app/hooks/useRoomEvent.ts +++ b/src/app/hooks/useRoomEvent.ts @@ -1,10 +1,10 @@ import { - IEvent, + type IEvent, MatrixEvent, MatrixEventEvent, - Room, + type Room, RoomEvent, - CryptoBackend, + type CryptoBackend, } from '$types/matrix-sdk'; import { useCallback, useEffect, useMemo, useState } from 'react'; import to from 'await-to-js'; diff --git a/src/app/hooks/useRoomEventReaders.ts b/src/app/hooks/useRoomEventReaders.ts index 8a0236685..52147c60d 100644 --- a/src/app/hooks/useRoomEventReaders.ts +++ b/src/app/hooks/useRoomEventReaders.ts @@ -1,4 +1,4 @@ -import { Room, RoomEvent, RoomEventHandlerMap } from '$types/matrix-sdk'; +import { type Room, RoomEvent, type RoomEventHandlerMap } from '$types/matrix-sdk'; import { useEffect, useState } from 'react'; const getEventReaders = (room: Room, evtId?: string) => { diff --git a/src/app/hooks/useRoomLatestRenderedEvent.ts b/src/app/hooks/useRoomLatestRenderedEvent.ts index 07b2a28d9..9c5aa4526 100644 --- a/src/app/hooks/useRoomLatestRenderedEvent.ts +++ b/src/app/hooks/useRoomLatestRenderedEvent.ts @@ -1,5 +1,10 @@ /* eslint-disable no-continue */ -import { MatrixEvent, Room, RoomEvent, RoomEventHandlerMap } from '$types/matrix-sdk'; +import { + type MatrixEvent, + type Room, + RoomEvent, + type RoomEventHandlerMap, +} from '$types/matrix-sdk'; import { useEffect, useState } from 'react'; import { MessageEvent, StateEvent } from '$types/matrix/room'; import { settingsAtom } from '$state/settings'; diff --git a/src/app/hooks/useRoomMembers.ts b/src/app/hooks/useRoomMembers.ts index fbfdbdd3c..e7271b039 100644 --- a/src/app/hooks/useRoomMembers.ts +++ b/src/app/hooks/useRoomMembers.ts @@ -1,4 +1,9 @@ -import { MatrixClient, MatrixEvent, RoomMember, RoomMemberEvent } from '$types/matrix-sdk'; +import { + type MatrixClient, + type MatrixEvent, + type RoomMember, + RoomMemberEvent, +} from '$types/matrix-sdk'; import { useEffect, useState } from 'react'; export const useRoomMembers = (mx: MatrixClient, roomId: string): RoomMember[] => { diff --git a/src/app/hooks/useRoomMeta.ts b/src/app/hooks/useRoomMeta.ts index eee1385fd..6cc70b2e6 100644 --- a/src/app/hooks/useRoomMeta.ts +++ b/src/app/hooks/useRoomMeta.ts @@ -1,5 +1,10 @@ import { useEffect, useState } from 'react'; -import { RoomJoinRulesEventContent, Room, RoomEvent, RoomStateEvent } from '$types/matrix-sdk'; +import { + type RoomJoinRulesEventContent, + type Room, + RoomEvent, + RoomStateEvent, +} from '$types/matrix-sdk'; import { StateEvent } from '$types/matrix/room'; import { useStateEvent } from './useStateEvent'; import { useNickname } from './useNickname'; diff --git a/src/app/hooks/useRoomNavigate.ts b/src/app/hooks/useRoomNavigate.ts index 51555125c..387657b3f 100644 --- a/src/app/hooks/useRoomNavigate.ts +++ b/src/app/hooks/useRoomNavigate.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import { NavigateOptions, useNavigate } from 'react-router-dom'; +import { type NavigateOptions, useNavigate } from 'react-router-dom'; import { useAtomValue } from 'jotai'; import { getCanonicalAliasOrRoomId } from '$utils/matrix'; import { diff --git a/src/app/hooks/useRoomPermissions.ts b/src/app/hooks/useRoomPermissions.ts index cb6f69a25..5046d6a10 100644 --- a/src/app/hooks/useRoomPermissions.ts +++ b/src/app/hooks/useRoomPermissions.ts @@ -1,8 +1,8 @@ import { useMemo } from 'react'; import { - IPowerLevels, - PowerLevelActions, - PowerLevelNotificationsAction, + type IPowerLevels, + type PowerLevelActions, + type PowerLevelNotificationsAction, readPowerLevel, } from './usePowerLevels'; diff --git a/src/app/hooks/useRoomPinnedEvents.ts b/src/app/hooks/useRoomPinnedEvents.ts index cb6106461..ae6dfeb4c 100644 --- a/src/app/hooks/useRoomPinnedEvents.ts +++ b/src/app/hooks/useRoomPinnedEvents.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { RoomPinnedEventsEventContent, Room } from '$types/matrix-sdk'; +import { type RoomPinnedEventsEventContent, type Room } from '$types/matrix-sdk'; import { StateEvent } from '$types/matrix/room'; import { useStateEvent } from './useStateEvent'; diff --git a/src/app/hooks/useRoomState.ts b/src/app/hooks/useRoomState.ts index 532bfb7d8..3142e63bf 100644 --- a/src/app/hooks/useRoomState.ts +++ b/src/app/hooks/useRoomState.ts @@ -1,9 +1,9 @@ import { Direction, - MatrixEvent, - Room, + type MatrixEvent, + type Room, RoomStateEvent, - RoomStateEventHandlerMap, + type RoomStateEventHandlerMap, } from '$types/matrix-sdk'; import { useCallback, useEffect, useState } from 'react'; import { StateEvent } from '$types/matrix/room'; diff --git a/src/app/hooks/useRoomTypingMembers.ts b/src/app/hooks/useRoomTypingMembers.ts index 5d06baded..424bb7e20 100644 --- a/src/app/hooks/useRoomTypingMembers.ts +++ b/src/app/hooks/useRoomTypingMembers.ts @@ -2,8 +2,8 @@ import { useAtomValue } from 'jotai'; import { selectAtom } from 'jotai/utils'; import { useCallback } from 'react'; import { - IRoomIdToTypingMembers, - TypingReceipt, + type IRoomIdToTypingMembers, + type TypingReceipt, roomIdToTypingMembersAtom, } from '$state/typingMembers'; diff --git a/src/app/hooks/useRoomWidgets.ts b/src/app/hooks/useRoomWidgets.ts index 65381ddd3..3c1a43444 100644 --- a/src/app/hooks/useRoomWidgets.ts +++ b/src/app/hooks/useRoomWidgets.ts @@ -1,6 +1,6 @@ -import { Room, MatrixEvent, MatrixClient } from '$types/matrix-sdk'; +import { type Room, type MatrixEvent, type MatrixClient } from '$types/matrix-sdk'; import { useCallback, useMemo } from 'react'; -import { IWidget } from 'matrix-widget-api'; +import { type IWidget } from 'matrix-widget-api'; import { StateEvent } from '$types/matrix/room'; import { getStateEvents } from '$utils/room'; import { useStateEventCallback } from './useStateEventCallback'; diff --git a/src/app/hooks/useRoomsNotificationPreferences.ts b/src/app/hooks/useRoomsNotificationPreferences.ts index 65626bc12..e56ae0bbd 100644 --- a/src/app/hooks/useRoomsNotificationPreferences.ts +++ b/src/app/hooks/useRoomsNotificationPreferences.ts @@ -1,6 +1,6 @@ import { createContext, useCallback, useContext, useMemo } from 'react'; -import { ConditionKind, IPushRules, MatrixClient, PushRuleKind } from '$types/matrix-sdk'; -import { Icons, IconSrc } from 'folds'; +import { ConditionKind, type IPushRules, type MatrixClient, PushRuleKind } from '$types/matrix-sdk'; +import { Icons, type IconSrc } from 'folds'; import { AccountDataEvent } from '$types/matrix/accountData'; import { isRoomId } from '$utils/matrix'; import { useAccountData } from './useAccountData'; diff --git a/src/app/hooks/useSableCosmetics.ts b/src/app/hooks/useSableCosmetics.ts index b9b54c7e3..52a7d44fa 100644 --- a/src/app/hooks/useSableCosmetics.ts +++ b/src/app/hooks/useSableCosmetics.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { usePowerLevels } from './usePowerLevels'; import { useRoomCreators } from './useRoomCreators'; import { useAccessiblePowerTagColors, useGetMemberPowerTag } from './useMemberPowerTag'; diff --git a/src/app/hooks/useSecretStorage.ts b/src/app/hooks/useSecretStorage.ts index 53829cf8d..970b430be 100644 --- a/src/app/hooks/useSecretStorage.ts +++ b/src/app/hooks/useSecretStorage.ts @@ -1,7 +1,7 @@ import { AccountDataEvent, - SecretStorageDefaultKeyContent, - SecretStorageKeyContent, + type SecretStorageDefaultKeyContent, + type SecretStorageKeyContent, } from '$types/matrix/accountData'; import { useAccountData } from './useAccountData'; diff --git a/src/app/hooks/useSessionProfiles.ts b/src/app/hooks/useSessionProfiles.ts index 2cb03c358..5effad9ea 100644 --- a/src/app/hooks/useSessionProfiles.ts +++ b/src/app/hooks/useSessionProfiles.ts @@ -1,5 +1,5 @@ import { useEffect, useRef, useState } from 'react'; -import { Session } from '$state/sessions'; +import { type Session } from '$state/sessions'; export type SessionProfile = { displayName?: string; diff --git a/src/app/hooks/useSettingsSync.ts b/src/app/hooks/useSettingsSync.ts index 9fd452963..86cdd392a 100644 --- a/src/app/hooks/useSettingsSync.ts +++ b/src/app/hooks/useSettingsSync.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useRef } from 'react'; import { atom, useAtom, useSetAtom } from 'jotai'; -import { MatrixEvent } from '$types/matrix-sdk'; +import { type MatrixEvent } from '$types/matrix-sdk'; import { AccountDataEvent } from '$types/matrix/accountData'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useAccountDataCallback } from '$hooks/useAccountDataCallback'; diff --git a/src/app/hooks/useSidebarItems.ts b/src/app/hooks/useSidebarItems.ts index dba7b2f28..b3fa793a4 100644 --- a/src/app/hooks/useSidebarItems.ts +++ b/src/app/hooks/useSidebarItems.ts @@ -1,5 +1,5 @@ -import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type Dispatch, type SetStateAction, useCallback, useEffect, useState } from 'react'; +import { type MatrixClient } from '$types/matrix-sdk'; import { AccountDataEvent } from '$types/matrix/accountData'; import { Membership } from '$types/matrix/room'; import { getAccountData, isSpace } from '$utils/room'; diff --git a/src/app/hooks/useSpace.ts b/src/app/hooks/useSpace.ts index ea53a0d0a..d9976a5ba 100644 --- a/src/app/hooks/useSpace.ts +++ b/src/app/hooks/useSpace.ts @@ -1,4 +1,4 @@ -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { createContext, useContext } from 'react'; const SpaceContext = createContext(null); diff --git a/src/app/hooks/useSpaceHierarchy.ts b/src/app/hooks/useSpaceHierarchy.ts index b5c088750..bea8a2a40 100644 --- a/src/app/hooks/useSpaceHierarchy.ts +++ b/src/app/hooks/useSpaceHierarchy.ts @@ -1,12 +1,12 @@ import { atom, useAtom, useAtomValue } from 'jotai'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { MatrixError, MatrixEvent, Room, IHierarchyRoom } from '$types/matrix-sdk'; -import { QueryFunction, useInfiniteQuery } from '@tanstack/react-query'; -import { MSpaceChildContent, StateEvent } from '$types/matrix/room'; +import { MatrixError, type MatrixEvent, type Room, type IHierarchyRoom } from '$types/matrix-sdk'; +import { type QueryFunction, useInfiniteQuery } from '@tanstack/react-query'; +import { type MSpaceChildContent, StateEvent } from '$types/matrix/room'; import { roomToParentsAtom } from '$state/room/roomToParents'; import { getAllParents, getStateEvents, isValidChild } from '$utils/room'; import { isRoomId } from '$utils/matrix'; -import { SortFunc, byOrderKey, byTsOldToNew, factoryRoomIdByActivity } from '$utils/sort'; +import { type SortFunc, byOrderKey, byTsOldToNew, factoryRoomIdByActivity } from '$utils/sort'; import { useMatrixClient } from './useMatrixClient'; import { makeLobbyCategoryId } from '../state/closedLobbyCategories'; import { useStateEventCallback } from './useStateEventCallback'; diff --git a/src/app/hooks/useSpecVersions.ts b/src/app/hooks/useSpecVersions.ts index 42403c61c..20d17c98a 100644 --- a/src/app/hooks/useSpecVersions.ts +++ b/src/app/hooks/useSpecVersions.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { SpecVersions } from '../cs-api'; +import { type SpecVersions } from '../cs-api'; const SpecVersionsContext = createContext(null); diff --git a/src/app/hooks/useSpoilerClickHandler.ts b/src/app/hooks/useSpoilerClickHandler.ts index b21011880..b92a788b7 100644 --- a/src/app/hooks/useSpoilerClickHandler.ts +++ b/src/app/hooks/useSpoilerClickHandler.ts @@ -1,4 +1,4 @@ -import { ReactEventHandler, useCallback } from 'react'; +import { type ReactEventHandler, useCallback } from 'react'; export const useSpoilerClickHandler = (): ReactEventHandler => { const handleClick: ReactEventHandler = useCallback((evt) => { diff --git a/src/app/hooks/useStateEvent.ts b/src/app/hooks/useStateEvent.ts index ba99eff51..f50b8f28c 100644 --- a/src/app/hooks/useStateEvent.ts +++ b/src/app/hooks/useStateEvent.ts @@ -1,6 +1,6 @@ -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useCallback, useMemo } from 'react'; -import { StateEvent } from '$types/matrix/room'; +import { type StateEvent } from '$types/matrix/room'; import { getStateEvent } from '$utils/room'; import { useStateEventCallback } from './useStateEventCallback'; import { useForceUpdate } from './useForceUpdate'; diff --git a/src/app/hooks/useStateEventCallback.ts b/src/app/hooks/useStateEventCallback.ts index 512378c3e..031af47aa 100644 --- a/src/app/hooks/useStateEventCallback.ts +++ b/src/app/hooks/useStateEventCallback.ts @@ -1,4 +1,9 @@ -import { MatrixClient, MatrixEvent, RoomState, RoomStateEvent } from '$types/matrix-sdk'; +import { + type MatrixClient, + type MatrixEvent, + type RoomState, + RoomStateEvent, +} from '$types/matrix-sdk'; import { useEffect } from 'react'; export type StateEventCallback = ( diff --git a/src/app/hooks/useSyncState.ts b/src/app/hooks/useSyncState.ts index d7763050d..d8ee3c89b 100644 --- a/src/app/hooks/useSyncState.ts +++ b/src/app/hooks/useSyncState.ts @@ -1,4 +1,4 @@ -import { ClientEvent, ClientEventHandlerMap, MatrixClient } from '$types/matrix-sdk'; +import { ClientEvent, type ClientEventHandlerMap, type MatrixClient } from '$types/matrix-sdk'; import { useEffect } from 'react'; export const useSyncState = ( diff --git a/src/app/hooks/useTextAreaCodeEditor.ts b/src/app/hooks/useTextAreaCodeEditor.ts index ff44e934e..c8c673782 100644 --- a/src/app/hooks/useTextAreaCodeEditor.ts +++ b/src/app/hooks/useTextAreaCodeEditor.ts @@ -1,7 +1,7 @@ -import { useMemo, useCallback, KeyboardEventHandler, MutableRefObject } from 'react'; +import { useMemo, useCallback, type KeyboardEventHandler, type MutableRefObject } from 'react'; import { isKeyHotkey } from 'is-hotkey'; import { TextArea, Intent, TextAreaOperations, Cursor } from '$plugins/text-area'; -import { GetTarget } from '$plugins/text-area/type'; +import { type GetTarget } from '$plugins/text-area/type'; import { useTextAreaIntentHandler } from './useTextAreaIntent'; export const useTextAreaCodeEditor = ( diff --git a/src/app/hooks/useTextAreaIntent.ts b/src/app/hooks/useTextAreaIntent.ts index e3e355145..4acf7d68f 100644 --- a/src/app/hooks/useTextAreaIntent.ts +++ b/src/app/hooks/useTextAreaIntent.ts @@ -1,6 +1,6 @@ import { isKeyHotkey } from 'is-hotkey'; -import { KeyboardEventHandler, useCallback } from 'react'; -import { Cursor, Intent, Operations, TextArea } from '$plugins/text-area'; +import { type KeyboardEventHandler, useCallback } from 'react'; +import { Cursor, type Intent, type Operations, type TextArea } from '$plugins/text-area'; export const useTextAreaIntentHandler = ( textArea: TextArea, diff --git a/src/app/hooks/useTypingStatusUpdater.ts b/src/app/hooks/useTypingStatusUpdater.ts index 9bbda0900..b1ccaee1b 100644 --- a/src/app/hooks/useTypingStatusUpdater.ts +++ b/src/app/hooks/useTypingStatusUpdater.ts @@ -1,4 +1,4 @@ -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { useMemo, useRef } from 'react'; import { TYPING_TIMEOUT_MS } from '$state/typingMembers'; diff --git a/src/app/hooks/useUIAFlows.ts b/src/app/hooks/useUIAFlows.ts index f7e04f2e3..d2f94d956 100644 --- a/src/app/hooks/useUIAFlows.ts +++ b/src/app/hooks/useUIAFlows.ts @@ -1,4 +1,4 @@ -import { AuthType, IAuthData, MatrixError, UIAFlow } from '$types/matrix-sdk'; +import { AuthType, type IAuthData, type MatrixError, type UIAFlow } from '$types/matrix-sdk'; import { useCallback, useMemo } from 'react'; import { getSupportedUIAFlows, diff --git a/src/app/hooks/useUserPresence.ts b/src/app/hooks/useUserPresence.ts index f1b858422..3541b205f 100644 --- a/src/app/hooks/useUserPresence.ts +++ b/src/app/hooks/useUserPresence.ts @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState } from 'react'; -import { User, UserEvent, UserEventHandlerMap } from '$types/matrix-sdk'; +import { type User, UserEvent, type UserEventHandlerMap } from '$types/matrix-sdk'; import { useMatrixClient } from './useMatrixClient'; export enum Presence { diff --git a/src/app/hooks/useUserProfile.ts b/src/app/hooks/useUserProfile.ts index d1de6e890..4b31a60c3 100644 --- a/src/app/hooks/useUserProfile.ts +++ b/src/app/hooks/useUserProfile.ts @@ -1,13 +1,13 @@ import { useEffect, useMemo } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; import { selectAtom } from 'jotai/utils'; -import { EventTimeline, Room } from '$types/matrix-sdk'; +import { EventTimeline, type Room } from '$types/matrix-sdk'; import { StateEvent } from '$types/matrix/room'; import colorMXID from '$utils/colorMXID'; import { profilesCacheAtom } from '$state/userRoomProfile'; import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; -import { MSC1767Text } from '$types/matrix/common'; +import { type MSC1767Text } from '$types/matrix/common'; import { useMatrixClient } from './useMatrixClient'; const inFlightProfiles = new Map>(); diff --git a/src/app/hooks/useVerificationRequest.ts b/src/app/hooks/useVerificationRequest.ts index 38d08d859..a571a1539 100644 --- a/src/app/hooks/useVerificationRequest.ts +++ b/src/app/hooks/useVerificationRequest.ts @@ -1,14 +1,14 @@ import { useCallback, useEffect, useState } from 'react'; import { CryptoEvent, - CryptoEventHandlerMap, - VerificationPhase, - VerificationRequest, + type CryptoEventHandlerMap, + type VerificationPhase, + type VerificationRequest, VerificationRequestEvent, - VerificationRequestEventHandlerMap, - Verifier, + type VerificationRequestEventHandlerMap, + type Verifier, VerifierEvent, - VerifierEventHandlerMap, + type VerifierEventHandlerMap, } from '$types/matrix-sdk'; import { useMatrixClient } from './useMatrixClient'; diff --git a/src/app/i18n.ts b/src/app/i18n.ts index 9e83805d3..08750eeb7 100644 --- a/src/app/i18n.ts +++ b/src/app/i18n.ts @@ -1,6 +1,6 @@ import i18n from 'i18next'; import LanguageDetector from 'i18next-browser-languagedetector'; -import Backend, { HttpBackendOptions } from 'i18next-http-backend'; +import Backend, { type HttpBackendOptions } from 'i18next-http-backend'; import { initReactI18next } from 'react-i18next'; import { trimTrailingSlash } from './utils/common'; diff --git a/src/app/pages/FeatureCheck.tsx b/src/app/pages/FeatureCheck.tsx index dd621c90a..64eb54981 100644 --- a/src/app/pages/FeatureCheck.tsx +++ b/src/app/pages/FeatureCheck.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useEffect } from 'react'; +import { type ReactNode, useEffect } from 'react'; import { Box, Dialog, Text, config } from 'folds'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { checkIndexedDBSupport } from '$utils/featureCheck'; diff --git a/src/app/pages/MobileFriendly.tsx b/src/app/pages/MobileFriendly.tsx index 2fe174fe5..f49327ff2 100644 --- a/src/app/pages/MobileFriendly.tsx +++ b/src/app/pages/MobileFriendly.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { useMatch } from 'react-router-dom'; import { ScreenSize, useScreenSizeContext } from '$hooks/useScreenSize'; import { DIRECT_PATH, EXPLORE_PATH, HOME_PATH, INBOX_PATH, SPACE_PATH } from './paths'; diff --git a/src/app/pages/Router.tsx b/src/app/pages/Router.tsx index 15fecbda9..ee27caa76 100644 --- a/src/app/pages/Router.tsx +++ b/src/app/pages/Router.tsx @@ -8,7 +8,7 @@ import { } from 'react-router-dom'; import * as Sentry from '@sentry/react'; -import { ClientConfig } from '$hooks/useClientConfig'; +import { type ClientConfig } from '$hooks/useClientConfig'; import { ErrorPage } from '$components/DefaultErrorPage'; import { Room } from '$features/room'; import { Lobby } from '$features/lobby'; @@ -22,7 +22,7 @@ import { UserRoomProfileRenderer } from '$components/UserRoomProfileRenderer'; import { CreateRoomModalRenderer } from '$features/create-room'; import { CreateSpaceModalRenderer } from '$features/create-space'; import { BugReportModalRenderer } from '$features/bug-report'; -import { getFallbackSession, MATRIX_SESSIONS_KEY, Sessions } from '$state/sessions'; +import { getFallbackSession, MATRIX_SESSIONS_KEY, type Sessions } from '$state/sessions'; import { getLocalStorageItem } from '$state/utils/atomWithLocalStorage'; import { NotificationJumper } from '$hooks/useNotificationJumper'; import { SearchModalRenderer } from '$features/search'; diff --git a/src/app/pages/ThemeManager.tsx b/src/app/pages/ThemeManager.tsx index 90a7e5783..2510c5ff1 100644 --- a/src/app/pages/ThemeManager.tsx +++ b/src/app/pages/ThemeManager.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useEffect } from 'react'; +import { type ReactNode, useEffect } from 'react'; import { configClass, varsClass } from 'folds'; import { DarkTheme, diff --git a/src/app/pages/auth/SSOLogin.tsx b/src/app/pages/auth/SSOLogin.tsx index eabb23602..436bf2e5c 100644 --- a/src/app/pages/auth/SSOLogin.tsx +++ b/src/app/pages/auth/SSOLogin.tsx @@ -1,5 +1,5 @@ import { Avatar, AvatarImage, Box, Button, Text } from 'folds'; -import { IIdentityProvider, SSOAction, createClient } from '$types/matrix-sdk'; +import { type IIdentityProvider, type SSOAction, createClient } from '$types/matrix-sdk'; import { useMemo } from 'react'; import { useAutoDiscoveryInfo } from '$hooks/useAutoDiscoveryInfo'; diff --git a/src/app/pages/auth/ServerPicker.tsx b/src/app/pages/auth/ServerPicker.tsx index e8a4984b2..3542ee2f2 100644 --- a/src/app/pages/auth/ServerPicker.tsx +++ b/src/app/pages/auth/ServerPicker.tsx @@ -1,8 +1,8 @@ import { - ChangeEventHandler, - FocusEventHandler, - KeyboardEventHandler, - MouseEventHandler, + type ChangeEventHandler, + type FocusEventHandler, + type KeyboardEventHandler, + type MouseEventHandler, useEffect, useRef, useState, @@ -16,7 +16,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Text, config, } from 'folds'; diff --git a/src/app/pages/auth/login/Login.tsx b/src/app/pages/auth/login/Login.tsx index fe895332b..2a2da65c9 100644 --- a/src/app/pages/auth/login/Login.tsx +++ b/src/app/pages/auth/login/Login.tsx @@ -7,7 +7,7 @@ import { useAuthServer } from '$hooks/useAuthServer'; import { useParsedLoginFlows } from '$hooks/useParsedLoginFlows'; import { getLoginPath, getRegisterPath, withSearchParam } from '$pages/pathUtils'; import { usePathWithOrigin } from '$hooks/usePathWithOrigin'; -import { LoginPathSearchParams } from '$pages/paths'; +import { type LoginPathSearchParams } from '$pages/paths'; import { useClientConfig } from '$hooks/useClientConfig'; import { SSOLogin } from '$pages/auth/SSOLogin'; import { OrDivider } from '$pages/auth/OrDivider'; diff --git a/src/app/pages/auth/login/PasswordLoginForm.tsx b/src/app/pages/auth/login/PasswordLoginForm.tsx index ba888bda5..f4875177f 100644 --- a/src/app/pages/auth/login/PasswordLoginForm.tsx +++ b/src/app/pages/auth/login/PasswordLoginForm.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, MouseEventHandler, useCallback, useState } from 'react'; +import { type FormEventHandler, type MouseEventHandler, useCallback, useState } from 'react'; import { Box, Button, @@ -12,14 +12,14 @@ import { OverlayBackdrop, OverlayCenter, PopOut, - RectCords, + type RectCords, Spinner, Text, config, } from 'folds'; import FocusTrap from 'focus-trap-react'; import { Link } from 'react-router-dom'; -import { MatrixError } from '$types/matrix-sdk'; +import { type MatrixError } from '$types/matrix-sdk'; import { getMxIdLocalPart, getMxIdServer, isUserId } from '$utils/matrix'; import { EMAIL_REGEX } from '$utils/regex'; import { useAutoDiscoveryInfo } from '$hooks/useAutoDiscoveryInfo'; @@ -32,7 +32,7 @@ import { stopPropagation } from '$utils/keyboard'; import { FieldError } from '$pages/auth/FiledError'; import { deviceDisplayName } from '$utils/user-agent'; import { - CustomLoginResponse, + type CustomLoginResponse, LoginError, factoryGetBaseUrl, login, diff --git a/src/app/pages/auth/login/TokenLogin.tsx b/src/app/pages/auth/login/TokenLogin.tsx index 7acf3e9b8..50ba7892e 100644 --- a/src/app/pages/auth/login/TokenLogin.tsx +++ b/src/app/pages/auth/login/TokenLogin.tsx @@ -11,11 +11,11 @@ import { config, } from 'folds'; import { useCallback, useEffect } from 'react'; -import { MatrixError } from '$types/matrix-sdk'; +import { type MatrixError } from '$types/matrix-sdk'; import { useAutoDiscoveryInfo } from '$hooks/useAutoDiscoveryInfo'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { deviceDisplayName } from '$utils/user-agent'; -import { CustomLoginResponse, LoginError, login, useLoginComplete } from './loginUtil'; +import { type CustomLoginResponse, LoginError, login, useLoginComplete } from './loginUtil'; function LoginTokenError({ message }: { message: string }) { return ( diff --git a/src/app/pages/auth/login/loginUtil.ts b/src/app/pages/auth/login/loginUtil.ts index 81371a614..fc7ace99d 100644 --- a/src/app/pages/auth/login/loginUtil.ts +++ b/src/app/pages/auth/login/loginUtil.ts @@ -1,10 +1,15 @@ import to from 'await-to-js'; -import { createClient, LoginRequest, LoginResponse, MatrixError } from '$types/matrix-sdk'; +import { + createClient, + type LoginRequest, + type LoginResponse, + MatrixError, +} from '$types/matrix-sdk'; import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useSetAtom } from 'jotai'; import * as Sentry from '@sentry/react'; -import { clientAllowedServer, ClientConfig } from '$hooks/useClientConfig'; +import { clientAllowedServer, type ClientConfig } from '$hooks/useClientConfig'; import { deleteAfterLoginRedirectPath, getAfterLoginRedirectPath, diff --git a/src/app/pages/auth/register/PasswordRegisterForm.tsx b/src/app/pages/auth/register/PasswordRegisterForm.tsx index e8e991022..660a1d3f7 100644 --- a/src/app/pages/auth/register/PasswordRegisterForm.tsx +++ b/src/app/pages/auth/register/PasswordRegisterForm.tsx @@ -10,14 +10,14 @@ import { Text, color, } from 'folds'; -import { ChangeEventHandler, useCallback, useMemo, useState } from 'react'; +import { type ChangeEventHandler, useCallback, useMemo, useState } from 'react'; import { - AuthDict, + type AuthDict, AuthType, - IAuthData, - MatrixError, - RegisterRequest, - UIAFlow, + type IAuthData, + type MatrixError, + type RegisterRequest, + type UIAFlow, createClient, } from '$types/matrix-sdk'; import { PasswordInput } from '$components/password-input'; @@ -28,7 +28,7 @@ import { requiredStageInFlows, } from '$utils/matrix-uia'; import { useUIACompleted, useUIAFlow, useUIAParams } from '$hooks/useUIAFlows'; -import { AsyncState, AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; +import { type AsyncState, AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useAutoDiscoveryInfo } from '$hooks/useAutoDiscoveryInfo'; import { AutoDummyStageDialog, @@ -40,10 +40,10 @@ import { import { useRegisterEmail } from '$hooks/useRegisterEmail'; import { ConfirmPasswordMatch } from '$components/ConfirmPasswordMatch'; import { UIAFlowOverlay } from '$components/UIAFlowOverlay'; -import { RequestEmailTokenCallback, RequestEmailTokenResponse } from '$hooks/types'; +import { type RequestEmailTokenCallback, type RequestEmailTokenResponse } from '$hooks/types'; import { FieldError } from '$pages/auth/FiledError'; import { deviceDisplayName } from '$utils/user-agent'; -import { RegisterError, RegisterResult, register, useRegisterComplete } from './registerUtil'; +import { RegisterError, type RegisterResult, register, useRegisterComplete } from './registerUtil'; export const SUPPORTED_REGISTER_STAGES = [ AuthType.RegistrationToken, diff --git a/src/app/pages/auth/register/Register.tsx b/src/app/pages/auth/register/Register.tsx index 11bee338e..5e48cc819 100644 --- a/src/app/pages/auth/register/Register.tsx +++ b/src/app/pages/auth/register/Register.tsx @@ -8,7 +8,7 @@ import { useParsedLoginFlows } from '$hooks/useParsedLoginFlows'; import { SupportedUIAFlowsLoader } from '$components/SupportedUIAFlowsLoader'; import { getLoginPath } from '$pages/pathUtils'; import { usePathWithOrigin } from '$hooks/usePathWithOrigin'; -import { RegisterPathSearchParams } from '$pages/paths'; +import { type RegisterPathSearchParams } from '$pages/paths'; import { SSOLogin } from '$pages/auth/SSOLogin'; import { OrDivider } from '$pages/auth/OrDivider'; import { PasswordRegisterForm, SUPPORTED_REGISTER_STAGES } from './PasswordRegisterForm'; diff --git a/src/app/pages/auth/register/registerUtil.ts b/src/app/pages/auth/register/registerUtil.ts index 513aabfc0..2013312c2 100644 --- a/src/app/pages/auth/register/registerUtil.ts +++ b/src/app/pages/auth/register/registerUtil.ts @@ -1,15 +1,15 @@ import to from 'await-to-js'; import { - IAuthData, - MatrixClient, + type IAuthData, + type MatrixClient, MatrixError, - RegisterRequest, - RegisterResponse, + type RegisterRequest, + type RegisterResponse, } from '$types/matrix-sdk'; import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useSetAtom } from 'jotai'; -import { LoginPathSearchParams } from '$pages/paths'; +import { type LoginPathSearchParams } from '$pages/paths'; import { deleteAfterLoginRedirectPath, getAfterLoginRedirectPath, diff --git a/src/app/pages/auth/reset-password/PasswordResetForm.tsx b/src/app/pages/auth/reset-password/PasswordResetForm.tsx index af4c57526..8ed1d654a 100644 --- a/src/app/pages/auth/reset-password/PasswordResetForm.tsx +++ b/src/app/pages/auth/reset-password/PasswordResetForm.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useEffect, useMemo, useState } from 'react'; +import { type FormEventHandler, useCallback, useEffect, useMemo, useState } from 'react'; import { Box, Button, @@ -14,7 +14,7 @@ import { } from 'folds'; import { useNavigate } from 'react-router-dom'; import FocusTrap from 'focus-trap-react'; -import { AuthDict, AuthType, MatrixError, createClient } from '$types/matrix-sdk'; +import { type AuthDict, AuthType, type MatrixError, createClient } from '$types/matrix-sdk'; import { useAutoDiscoveryInfo } from '$hooks/useAutoDiscoveryInfo'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { useAuthServer } from '$hooks/useAuthServer'; @@ -24,10 +24,10 @@ import { ConfirmPasswordMatch } from '$components/ConfirmPasswordMatch'; import { UIAFlowOverlay } from '$components/UIAFlowOverlay'; import { EmailStageDialog } from '$components/uia-stages'; import { getLoginPath, withSearchParam } from '$pages/pathUtils'; -import { LoginPathSearchParams } from '$pages/paths'; +import { type LoginPathSearchParams } from '$pages/paths'; import { getUIAError, getUIAErrorCode } from '$utils/matrix-uia'; import { FieldError } from '$pages/auth/FiledError'; -import { ResetPasswordResult, resetPassword } from './resetPasswordUtil'; +import { type ResetPasswordResult, resetPassword } from './resetPasswordUtil'; type FormData = { email: string; diff --git a/src/app/pages/auth/reset-password/ResetPassword.tsx b/src/app/pages/auth/reset-password/ResetPassword.tsx index 718101fab..439e35af4 100644 --- a/src/app/pages/auth/reset-password/ResetPassword.tsx +++ b/src/app/pages/auth/reset-password/ResetPassword.tsx @@ -3,7 +3,7 @@ import { useMemo } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; import { getLoginPath } from '$pages/pathUtils'; import { useAuthServer } from '$hooks/useAuthServer'; -import { ResetPasswordPathSearchParams } from '$pages/paths'; +import { type ResetPasswordPathSearchParams } from '$pages/paths'; import { PasswordResetForm } from './PasswordResetForm'; const useResetPasswordSearchParams = ( diff --git a/src/app/pages/auth/reset-password/resetPasswordUtil.ts b/src/app/pages/auth/reset-password/resetPasswordUtil.ts index 65f0c7e7c..98e0891b7 100644 --- a/src/app/pages/auth/reset-password/resetPasswordUtil.ts +++ b/src/app/pages/auth/reset-password/resetPasswordUtil.ts @@ -1,5 +1,10 @@ import to from 'await-to-js'; -import { AuthDict, IAuthData, MatrixClient, MatrixError } from '$types/matrix-sdk'; +import { + type AuthDict, + type IAuthData, + type MatrixClient, + type MatrixError, +} from '$types/matrix-sdk'; export type ResetPasswordResponse = Record; export type ResetPasswordResult = [IAuthData, undefined] | [undefined, ResetPasswordResponse]; diff --git a/src/app/pages/client/AutoDiscovery.tsx b/src/app/pages/client/AutoDiscovery.tsx index c39f16cd3..797d55248 100644 --- a/src/app/pages/client/AutoDiscovery.tsx +++ b/src/app/pages/client/AutoDiscovery.tsx @@ -1,7 +1,7 @@ -import { ReactNode, useCallback, useMemo } from 'react'; +import { type ReactNode, useCallback, useMemo } from 'react'; import { AutoDiscoveryInfoProvider } from '../../hooks/useAutoDiscoveryInfo'; import { AsyncStatus, useAsyncCallbackValue } from '../../hooks/useAsyncCallback'; -import { autoDiscovery, AutoDiscoveryInfo } from '../../cs-api'; +import { autoDiscovery, type AutoDiscoveryInfo } from '../../cs-api'; import { getMxIdServer } from '../../utils/matrix'; type AutoDiscoveryProps = { diff --git a/src/app/pages/client/BackgroundNotifications.tsx b/src/app/pages/client/BackgroundNotifications.tsx index 395718223..44af1ed91 100644 --- a/src/app/pages/client/BackgroundNotifications.tsx +++ b/src/app/pages/client/BackgroundNotifications.tsx @@ -2,10 +2,10 @@ import { useEffect, useMemo, useRef } from 'react'; import { ClientEvent, createClient, - MatrixClient, - MatrixEvent, + type MatrixClient, + type MatrixEvent, MatrixEventEvent, - Room, + type Room, RoomEvent, SyncState, PushProcessor, @@ -14,7 +14,7 @@ import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import { sessionsAtom, activeSessionIdAtom, - Session, + type Session, pendingNotificationAtom, backgroundUnreadCountsAtom, inAppBannerAtom, diff --git a/src/app/pages/client/ClientBindAtoms.ts b/src/app/pages/client/ClientBindAtoms.ts index aac351062..5ddfb67dc 100644 --- a/src/app/pages/client/ClientBindAtoms.ts +++ b/src/app/pages/client/ClientBindAtoms.ts @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useBindAtoms } from '$state/hooks/useBindAtoms'; diff --git a/src/app/pages/client/ClientInitStorageAtom.tsx b/src/app/pages/client/ClientInitStorageAtom.tsx index 90f6d914f..1eab6ceee 100644 --- a/src/app/pages/client/ClientInitStorageAtom.tsx +++ b/src/app/pages/client/ClientInitStorageAtom.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useMemo } from 'react'; +import { type ReactNode, useMemo } from 'react'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { makeClosedNavCategoriesAtom } from '$state/closedNavCategories'; import { ClosedNavCategoriesProvider } from '$state/hooks/closedNavCategories'; diff --git a/src/app/pages/client/ClientLayout.tsx b/src/app/pages/client/ClientLayout.tsx index 4bbd4068f..a9a97483a 100644 --- a/src/app/pages/client/ClientLayout.tsx +++ b/src/app/pages/client/ClientLayout.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { Box } from 'folds'; type ClientLayoutProps = { diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index dc9bf984f..556fd6140 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -1,13 +1,13 @@ import { useAtomValue, useSetAtom } from 'jotai'; import * as Sentry from '@sentry/react'; -import { ReactNode, useCallback, useEffect, useRef } from 'react'; +import { type ReactNode, useCallback, useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import { MatrixEvent, MatrixEventEvent, PushProcessor, RoomEvent, - RoomEventHandlerMap, + type RoomEventHandlerMap, SetPresence, } from '$types/matrix-sdk'; import parse from 'html-react-parser'; diff --git a/src/app/pages/client/ClientRoomsNotificationPreferences.tsx b/src/app/pages/client/ClientRoomsNotificationPreferences.tsx index c6ef04a4c..056072097 100644 --- a/src/app/pages/client/ClientRoomsNotificationPreferences.tsx +++ b/src/app/pages/client/ClientRoomsNotificationPreferences.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { RoomsNotificationPreferencesProvider, useRoomsNotificationPreferences, diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx index 1a653e950..daade38e9 100644 --- a/src/app/pages/client/ClientRoot.tsx +++ b/src/app/pages/client/ClientRoot.tsx @@ -9,13 +9,20 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Spinner, Text, } from 'folds'; -import { HttpApiEvent, HttpApiEventHandlerMap, MatrixClient } from '$types/matrix-sdk'; +import { HttpApiEvent, type HttpApiEventHandlerMap, type MatrixClient } from '$types/matrix-sdk'; import FocusTrap from 'focus-trap-react'; -import { useRef, MouseEventHandler, ReactNode, useCallback, useEffect, useState } from 'react'; +import { + useRef, + type MouseEventHandler, + type ReactNode, + useCallback, + useEffect, + useState, +} from 'react'; import * as Sentry from '@sentry/react'; import { useNavigate } from 'react-router-dom'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; diff --git a/src/app/pages/client/SidebarNav.tsx b/src/app/pages/client/SidebarNav.tsx index 507fa37c4..b563216c7 100644 --- a/src/app/pages/client/SidebarNav.tsx +++ b/src/app/pages/client/SidebarNav.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useRef, useState } from 'react'; +import { type MouseEventHandler, useRef, useState } from 'react'; import { Box, Checkbox, config, Line, Menu, MenuItem, PopOut, Scroll, Text, toRem } from 'folds'; import FocusTrap from 'focus-trap-react'; import { stopPropagation } from '$utils/keyboard'; diff --git a/src/app/pages/client/SpecVersions.tsx b/src/app/pages/client/SpecVersions.tsx index 75cb3cafc..f5c16a855 100644 --- a/src/app/pages/client/SpecVersions.tsx +++ b/src/app/pages/client/SpecVersions.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { Box, Dialog, config, Text, Button, Spinner } from 'folds'; import { SpecVersionsLoader } from '$components/SpecVersionsLoader'; import { SpecVersionsProvider } from '$hooks/useSpecVersions'; diff --git a/src/app/pages/client/SyncStatus.tsx b/src/app/pages/client/SyncStatus.tsx index f55fe5e59..4c3398bda 100644 --- a/src/app/pages/client/SyncStatus.tsx +++ b/src/app/pages/client/SyncStatus.tsx @@ -1,4 +1,4 @@ -import { MatrixClient, SyncState } from '$types/matrix-sdk'; +import { type MatrixClient, SyncState } from '$types/matrix-sdk'; import { useCallback, useState } from 'react'; import { Box, config, Line, Text } from 'folds'; import * as Sentry from '@sentry/react'; diff --git a/src/app/pages/client/direct/Direct.tsx b/src/app/pages/client/direct/Direct.tsx index 43ccb6be1..67c1cdb71 100644 --- a/src/app/pages/client/direct/Direct.tsx +++ b/src/app/pages/client/direct/Direct.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, forwardRef, useEffect, useMemo, useRef, useState } from 'react'; +import { type MouseEventHandler, forwardRef, useEffect, useMemo, useRef, useState } from 'react'; import { useAtom, useAtomValue } from 'jotai'; import { Avatar, @@ -10,7 +10,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Text, config, toRem, diff --git a/src/app/pages/client/direct/RoomProvider.tsx b/src/app/pages/client/direct/RoomProvider.tsx index 1780fa728..5a00678aa 100644 --- a/src/app/pages/client/direct/RoomProvider.tsx +++ b/src/app/pages/client/direct/RoomProvider.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { useParams } from 'react-router-dom'; import { useSelectedRoom } from '$hooks/router/useSelectedRoom'; import { IsDirectRoomProvider, RoomProvider } from '$hooks/useRoom'; diff --git a/src/app/pages/client/explore/Explore.tsx b/src/app/pages/client/explore/Explore.tsx index 9ac55e2d2..dcdb670bd 100644 --- a/src/app/pages/client/explore/Explore.tsx +++ b/src/app/pages/client/explore/Explore.tsx @@ -1,4 +1,4 @@ -import { FormEventHandler, useCallback, useRef, useState } from 'react'; +import { type FormEventHandler, useCallback, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import FocusTrap from 'focus-trap-react'; import { diff --git a/src/app/pages/client/explore/Server.tsx b/src/app/pages/client/explore/Server.tsx index d58aa2a10..403d15ff5 100644 --- a/src/app/pages/client/explore/Server.tsx +++ b/src/app/pages/client/explore/Server.tsx @@ -1,7 +1,7 @@ import { - FormEventHandler, - MouseEventHandler, - RefObject, + type FormEventHandler, + type MouseEventHandler, + type RefObject, useCallback, useEffect, useMemo, @@ -20,7 +20,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Scroll, Spinner, Text, @@ -31,12 +31,12 @@ import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; import FocusTrap from 'focus-trap-react'; import { useAtomValue } from 'jotai'; import { useQuery } from '@tanstack/react-query'; -import { MatrixClient, Method, RoomType } from '$types/matrix-sdk'; +import { type MatrixClient, Method, RoomType } from '$types/matrix-sdk'; import { Page, PageContent, PageContentCenter, PageHeader } from '$components/page'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { RoomTopicViewer } from '$components/room-topic-viewer'; import { RoomCard, RoomCardBase, RoomCardGrid } from '$components/room-card'; -import { ExploreServerPathSearchParams } from '$pages/paths'; +import { type ExploreServerPathSearchParams } from '$pages/paths'; import { getExploreServerPath, withSearchParam } from '$pages/pathUtils'; import { allRoomsAtom } from '$state/room-list/roomList'; import { useRoomNavigate } from '$hooks/useRoomNavigate'; diff --git a/src/app/pages/client/home/Home.tsx b/src/app/pages/client/home/Home.tsx index c25d99e30..8a114f07d 100644 --- a/src/app/pages/client/home/Home.tsx +++ b/src/app/pages/client/home/Home.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, forwardRef, useMemo, useRef, useState } from 'react'; +import { type MouseEventHandler, forwardRef, useMemo, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Avatar, @@ -10,7 +10,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Text, config, toRem, @@ -60,7 +60,7 @@ import { } from '$hooks/useRoomsNotificationPreferences'; import { UseStateProvider } from '$components/UseStateProvider'; import { JoinAddressPrompt } from '$components/join-address-prompt'; -import { RoomSearchParams } from '$pages/paths'; +import { type RoomSearchParams } from '$pages/paths'; import { useHomeRooms } from './useHomeRooms'; type HomeMenuProps = { diff --git a/src/app/pages/client/home/RoomProvider.tsx b/src/app/pages/client/home/RoomProvider.tsx index b6f7ba7e3..6d04c8c60 100644 --- a/src/app/pages/client/home/RoomProvider.tsx +++ b/src/app/pages/client/home/RoomProvider.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { useParams } from 'react-router-dom'; import { useSelectedRoom } from '$hooks/router/useSelectedRoom'; import { IsDirectRoomProvider, RoomProvider } from '$hooks/useRoom'; diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx index 8eeff6ad4..831a50238 100644 --- a/src/app/pages/client/inbox/Invites.tsx +++ b/src/app/pages/client/inbox/Invites.tsx @@ -19,7 +19,12 @@ import { } from 'folds'; import { useAtomValue } from 'jotai'; import { nicknamesAtom } from '$state/nicknames'; -import { RoomTopicEventContent, MatrixClient, MatrixError, Room } from '$types/matrix-sdk'; +import { + type RoomTopicEventContent, + type MatrixClient, + type MatrixError, + type Room, +} from '$types/matrix-sdk'; import FocusTrap from 'focus-trap-react'; import { Page, diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index dc3d35297..87613dec1 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -1,5 +1,5 @@ /* eslint-disable react/destructuring-assignment */ -import { MouseEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { type MouseEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Avatar, Box, @@ -15,23 +15,23 @@ import { } from 'folds'; import { useSearchParams } from 'react-router-dom'; import { - INotification, - INotificationsResponse, - IRoomEvent, + type INotification, + type INotificationsResponse, + type IRoomEvent, JoinRule, Method, RelationType, - Room, + type Room, } from '$types/matrix-sdk'; import { useVirtualizer } from '@tanstack/react-virtual'; -import { HTMLReactParserOptions } from 'html-react-parser'; -import { Opts as LinkifyOpts } from 'linkifyjs'; +import { type HTMLReactParserOptions } from 'html-react-parser'; +import { type Opts as LinkifyOpts } from 'linkifyjs'; import { useAtomValue } from 'jotai'; import { nicknamesAtom } from '$state/nicknames'; import { Page, PageContent, PageContentCenter, PageHeader } from '$components/page'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { getMxIdLocalPart, mxcUrlToHttp } from '$utils/matrix'; -import { InboxNotificationsPathSearchParams } from '$pages/paths'; +import { type InboxNotificationsPathSearchParams } from '$pages/paths'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { SequenceCard } from '$components/sequence-card'; import { RoomAvatar, RoomIcon } from '$components/room-avatar'; @@ -68,7 +68,7 @@ import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { Image } from '$components/media'; import { ImageViewer } from '$components/image-viewer'; -import { GetContentCallback, MessageEvent, StateEvent } from '$types/matrix/room'; +import { type GetContentCallback, MessageEvent, StateEvent } from '$types/matrix/room'; import { useMatrixEventRenderer } from '$hooks/useMatrixEventRenderer'; import * as customHtmlCss from '$styles/CustomHtml.css'; import { useRoomNavigate } from '$hooks/useRoomNavigate'; diff --git a/src/app/pages/client/sidebar/AccountSwitcherTab.tsx b/src/app/pages/client/sidebar/AccountSwitcherTab.tsx index 089c7b84b..28c3a413c 100644 --- a/src/app/pages/client/sidebar/AccountSwitcherTab.tsx +++ b/src/app/pages/client/sidebar/AccountSwitcherTab.tsx @@ -1,4 +1,4 @@ -import { MouseEvent, MouseEventHandler, useCallback, useState } from 'react'; +import { type MouseEvent, type MouseEventHandler, useCallback, useState } from 'react'; import { Box, Button, @@ -9,7 +9,7 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Text, config, toRem, @@ -23,7 +23,7 @@ import { useNavigate } from 'react-router-dom'; import { sessionsAtom, activeSessionIdAtom, - Session, + type Session, backgroundUnreadCountsAtom, } from '$state/sessions'; import { diff --git a/src/app/pages/client/sidebar/CreateTab.tsx b/src/app/pages/client/sidebar/CreateTab.tsx index 0d93621a9..bc579520d 100644 --- a/src/app/pages/client/sidebar/CreateTab.tsx +++ b/src/app/pages/client/sidebar/CreateTab.tsx @@ -1,5 +1,5 @@ -import { MouseEventHandler, useState } from 'react'; -import { Box, config, Icon, Icons, Menu, PopOut, RectCords, Text } from 'folds'; +import { type MouseEventHandler, useState } from 'react'; +import { Box, config, Icon, Icons, Menu, PopOut, type RectCords, Text } from 'folds'; import FocusTrap from 'focus-trap-react'; import { useNavigate } from 'react-router-dom'; import { SidebarAvatar, SidebarItem, SidebarItemTooltip } from '$components/sidebar'; @@ -15,7 +15,7 @@ import { } from '$pages/pathUtils'; import { useCreateSelected } from '$hooks/router/useCreateSelected'; import { JoinAddressPrompt } from '$components/join-address-prompt'; -import { RoomSearchParams } from '$pages/paths'; +import { type RoomSearchParams } from '$pages/paths'; export function CreateTab() { const createSelected = useCreateSelected(); diff --git a/src/app/pages/client/sidebar/DirectDMsList.tsx b/src/app/pages/client/sidebar/DirectDMsList.tsx index 16e829ce5..b7a1927ed 100644 --- a/src/app/pages/client/sidebar/DirectDMsList.tsx +++ b/src/app/pages/client/sidebar/DirectDMsList.tsx @@ -3,7 +3,7 @@ import * as Sentry from '@sentry/react'; import { useNavigate } from 'react-router-dom'; import { Avatar, Text, Box } from 'folds'; import { useAtomValue } from 'jotai'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { roomToUnreadAtom } from '$state/room/roomToUnread'; import { getDirectRoomPath } from '$pages/pathUtils'; diff --git a/src/app/pages/client/sidebar/DirectTab.tsx b/src/app/pages/client/sidebar/DirectTab.tsx index 17c88a042..4b06a46c8 100644 --- a/src/app/pages/client/sidebar/DirectTab.tsx +++ b/src/app/pages/client/sidebar/DirectTab.tsx @@ -1,6 +1,17 @@ -import { MouseEventHandler, forwardRef, useMemo, useState } from 'react'; +import { type MouseEventHandler, forwardRef, useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Box, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds'; +import { + Box, + Icon, + Icons, + Menu, + MenuItem, + PopOut, + type RectCords, + Text, + config, + toRem, +} from 'folds'; import FocusTrap from 'focus-trap-react'; import { useAtomValue } from 'jotai'; import { useDirects } from '$state/hooks/roomList'; diff --git a/src/app/pages/client/sidebar/HomeTab.tsx b/src/app/pages/client/sidebar/HomeTab.tsx index 4d32c0304..d345c8dec 100644 --- a/src/app/pages/client/sidebar/HomeTab.tsx +++ b/src/app/pages/client/sidebar/HomeTab.tsx @@ -1,6 +1,17 @@ -import { MouseEventHandler, forwardRef, useState } from 'react'; +import { type MouseEventHandler, forwardRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Box, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds'; +import { + Box, + Icon, + Icons, + Menu, + MenuItem, + PopOut, + type RectCords, + Text, + config, + toRem, +} from 'folds'; import { useAtomValue } from 'jotai'; import FocusTrap from 'focus-trap-react'; import { useOrphanRooms } from '$state/hooks/roomList'; diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx index 5370aff2e..e34873cfe 100644 --- a/src/app/pages/client/sidebar/SpaceTabs.tsx +++ b/src/app/pages/client/sidebar/SpaceTabs.tsx @@ -1,7 +1,7 @@ import { - MouseEventHandler, - ReactNode, - RefObject, + type MouseEventHandler, + type ReactNode, + type RefObject, forwardRef, useCallback, useEffect, @@ -19,13 +19,13 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Text, config, toRem, } from 'folds'; import { useAtom, useAtomValue } from 'jotai'; -import { Room } from '$types/matrix-sdk'; +import { type Room } from '$types/matrix-sdk'; import { draggable, dropTargetForElements, @@ -34,7 +34,7 @@ import { import { attachInstruction, extractInstruction, - Instruction, + type Instruction, } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item'; import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element'; import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine'; @@ -64,9 +64,9 @@ import { getCanonicalAliasOrRoomId, isRoomAlias } from '$utils/matrix'; import { RoomAvatar } from '$components/room-avatar'; import { nameInitials, randomStr } from '$utils/common'; import { - ISidebarFolder, - SidebarItems, - TSidebarItem, + type ISidebarFolder, + type SidebarItems, + type TSidebarItem, makeCinnySpacesContent, parseSidebar, sidebarItemWithout, diff --git a/src/app/pages/client/space/RoomProvider.tsx b/src/app/pages/client/space/RoomProvider.tsx index 411efc163..26df3f26e 100644 --- a/src/app/pages/client/space/RoomProvider.tsx +++ b/src/app/pages/client/space/RoomProvider.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { useParams } from 'react-router-dom'; import { useAtom, useAtomValue } from 'jotai'; import { useSelectedRoom } from '$hooks/router/useSelectedRoom'; diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx index 4eb7b117c..6d710f8b5 100644 --- a/src/app/pages/client/space/Space.tsx +++ b/src/app/pages/client/space/Space.tsx @@ -1,6 +1,6 @@ import { - MouseEventHandler, - ReactElement, + type MouseEventHandler, + type ReactElement, forwardRef, useCallback, useEffect, @@ -20,17 +20,17 @@ import { Menu, MenuItem, PopOut, - RectCords, + type RectCords, Spinner, Text, color, config, toRem, } from 'folds'; -import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual'; +import { useVirtualizer, type VirtualItem } from '@tanstack/react-virtual'; import FocusTrap from 'focus-trap-react'; import { useNavigate } from 'react-router-dom'; -import { JoinRule, Room, RoomJoinRulesEventContent } from '$types/matrix-sdk'; +import { JoinRule, type Room, type RoomJoinRulesEventContent } from '$types/matrix-sdk'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { mDirectAtom } from '$state/mDirectList'; import { NavCategory, NavCategoryHeader, NavItem, NavItemContent, NavLink } from '$components/nav'; @@ -48,7 +48,7 @@ import { roomToUnreadAtom } from '$state/room/roomToUnread'; import { useCategoryHandler } from '$hooks/useCategoryHandler'; import { useNavToActivePathMapper } from '$hooks/useNavToActivePathMapper'; import { useRoomName } from '$hooks/useRoomMeta'; -import { HierarchyItem, useSpaceJoinedHierarchy } from '$hooks/useSpaceHierarchy'; +import { type HierarchyItem, useSpaceJoinedHierarchy } from '$hooks/useSpaceHierarchy'; import { allRoomsAtom } from '$state/room-list/roomList'; import { PageNav, PageNavContent, PageNavHeader } from '$components/page'; import { usePowerLevels } from '$hooks/usePowerLevels'; diff --git a/src/app/pages/client/space/SpaceProvider.tsx b/src/app/pages/client/space/SpaceProvider.tsx index cc2eb5bde..16ec9c199 100644 --- a/src/app/pages/client/space/SpaceProvider.tsx +++ b/src/app/pages/client/space/SpaceProvider.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { useParams } from 'react-router-dom'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useSpaces } from '$state/hooks/roomList'; diff --git a/src/app/pages/pathSearchParam.ts b/src/app/pages/pathSearchParam.ts index 813abc3d9..9bfedc3ea 100644 --- a/src/app/pages/pathSearchParam.ts +++ b/src/app/pages/pathSearchParam.ts @@ -1,4 +1,4 @@ -import { RoomSearchParams, DirectCreateSearchParams } from './paths'; +import { type RoomSearchParams, type DirectCreateSearchParams } from './paths'; type SearchParamsGetter = (searchParams: URLSearchParams) => T; diff --git a/src/app/pages/pathUtils.ts b/src/app/pages/pathUtils.ts index 3872c9290..778becc83 100644 --- a/src/app/pages/pathUtils.ts +++ b/src/app/pages/pathUtils.ts @@ -1,6 +1,6 @@ -import { generatePath, Path } from 'react-router-dom'; +import { generatePath, type Path } from 'react-router-dom'; import { trimLeadingSlash, trimTrailingSlash } from '$utils/common'; -import { HashRouterConfig } from '$hooks/useClientConfig'; +import { type HashRouterConfig } from '$hooks/useClientConfig'; import { DIRECT_CREATE_PATH, DIRECT_PATH, diff --git a/src/app/plugins/call/CallControl.ts b/src/app/plugins/call/CallControl.ts index c30ffc1c7..84c571cc1 100644 --- a/src/app/plugins/call/CallControl.ts +++ b/src/app/plugins/call/CallControl.ts @@ -1,7 +1,11 @@ -import { ClientWidgetApi } from 'matrix-widget-api'; +import { type ClientWidgetApi } from 'matrix-widget-api'; import EventEmitter from 'eventemitter3'; import { CallControlState } from './CallControlState'; -import { ElementMediaStateDetail, ElementMediaStatePayload, ElementWidgetActions } from './types'; +import { + type ElementMediaStateDetail, + type ElementMediaStatePayload, + ElementWidgetActions, +} from './types'; export enum CallControlEvent { StateUpdate = 'state_update', diff --git a/src/app/plugins/call/CallEmbed.ts b/src/app/plugins/call/CallEmbed.ts index 1a12211d4..f746e5969 100644 --- a/src/app/plugins/call/CallEmbed.ts +++ b/src/app/plugins/call/CallEmbed.ts @@ -1,28 +1,28 @@ import { ClientEvent, KnownMembership, - MatrixClient, - MatrixEvent, + type MatrixClient, + type MatrixEvent, MatrixEventEvent, - Room, + type Room, RoomStateEvent, } from 'matrix-js-sdk'; import { ClientWidgetApi, type IWidgetApiRequest, - IRoomEvent, - IWidget, + type IRoomEvent, + type IWidget, Widget, WidgetApiFromWidgetAction, WidgetApiToWidgetAction, - WidgetDriver, + type WidgetDriver, } from 'matrix-widget-api'; import { CallWidgetDriver } from './CallWidgetDriver'; import { trimTrailingSlash } from '../../utils/common'; import { ElementCallIntent, - ElementCallThemeKind, - ElementMediaStateDetail, + type ElementCallThemeKind, + type ElementMediaStateDetail, ElementWidgetActions, } from './types'; import { CallControl } from './CallControl'; diff --git a/src/app/plugins/call/CallWidgetDriver.ts b/src/app/plugins/call/CallWidgetDriver.ts index 6d94891f8..a53a7dca6 100644 --- a/src/app/plugins/call/CallWidgetDriver.ts +++ b/src/app/plugins/call/CallWidgetDriver.ts @@ -10,8 +10,8 @@ import { type IGetMediaConfigResult, UpdateDelayedEventAction, OpenIDRequestState, - SimpleObservable, - IOpenIDUpdate, + type SimpleObservable, + type IOpenIDUpdate, } from 'matrix-widget-api'; import { EventType, @@ -22,7 +22,7 @@ import { type SendDelayedEventResponse, type StateEvents, type TimelineEvents, - MatrixClient, + type MatrixClient, } from 'matrix-js-sdk'; import { getCallCapabilities } from './utils'; import { downloadMedia, mxcUrlToHttp } from '../../utils/matrix'; diff --git a/src/app/plugins/call/hooks.ts b/src/app/plugins/call/hooks.ts index f5b3ff933..25cf04f39 100644 --- a/src/app/plugins/call/hooks.ts +++ b/src/app/plugins/call/hooks.ts @@ -1,11 +1,11 @@ import { - ClientWidgetApi, - IWidgetApiAcknowledgeResponseData, - IWidgetApiRequestData, + type ClientWidgetApi, + type IWidgetApiAcknowledgeResponseData, + type IWidgetApiRequestData, } from 'matrix-widget-api'; import { useCallback, useEffect, useState } from 'react'; -import { CallControl, CallControlEvent } from './CallControl'; -import { CallControlState } from './CallControlState'; +import { type CallControl, CallControlEvent } from './CallControl'; +import { type CallControlState } from './CallControlState'; export const useClientWidgetApiEvent = ( api: ClientWidgetApi | undefined, diff --git a/src/app/plugins/custom-emoji/ImagePack.ts b/src/app/plugins/custom-emoji/ImagePack.ts index d7aa9941a..127b558ba 100644 --- a/src/app/plugins/custom-emoji/ImagePack.ts +++ b/src/app/plugins/custom-emoji/ImagePack.ts @@ -1,9 +1,9 @@ -import { MatrixEvent } from '$types/matrix-sdk'; +import { type MatrixEvent } from '$types/matrix-sdk'; import { PackAddress } from './PackAddress'; -import { PackImageReader } from './PackImageReader'; +import { type PackImageReader } from './PackImageReader'; import { PackImagesReader } from './PackImagesReader'; import { PackMetaReader } from './PackMetaReader'; -import { ImageUsage, PackContent } from './types'; +import { ImageUsage, type PackContent } from './types'; export class ImagePack { public readonly id: string; diff --git a/src/app/plugins/custom-emoji/PackImageReader.ts b/src/app/plugins/custom-emoji/PackImageReader.ts index 51e5114f2..0b083fcef 100644 --- a/src/app/plugins/custom-emoji/PackImageReader.ts +++ b/src/app/plugins/custom-emoji/PackImageReader.ts @@ -1,5 +1,5 @@ -import { IImageInfo } from '$types/matrix/common'; -import { ImageUsage, PackImage } from './types'; +import { type IImageInfo } from '$types/matrix/common'; +import { ImageUsage, type PackImage } from './types'; export class PackImageReader { public readonly shortcode: string; diff --git a/src/app/plugins/custom-emoji/PackImagesReader.ts b/src/app/plugins/custom-emoji/PackImagesReader.ts index 1531218ae..a75657d10 100644 --- a/src/app/plugins/custom-emoji/PackImagesReader.ts +++ b/src/app/plugins/custom-emoji/PackImagesReader.ts @@ -1,5 +1,5 @@ import { PackImageReader } from './PackImageReader'; -import { PackImages } from './types'; +import { type PackImages } from './types'; export class PackImagesReader { private readonly rawImages: PackImages; diff --git a/src/app/plugins/custom-emoji/PackMetaReader.ts b/src/app/plugins/custom-emoji/PackMetaReader.ts index 537addf46..5153e2deb 100644 --- a/src/app/plugins/custom-emoji/PackMetaReader.ts +++ b/src/app/plugins/custom-emoji/PackMetaReader.ts @@ -1,4 +1,4 @@ -import { PackMeta, ImageUsage } from './types'; +import { type PackMeta, ImageUsage } from './types'; export class PackMetaReader { private readonly meta: PackMeta; diff --git a/src/app/plugins/custom-emoji/imagePackCache.ts b/src/app/plugins/custom-emoji/imagePackCache.ts index f15f1fba0..3773d00f0 100644 --- a/src/app/plugins/custom-emoji/imagePackCache.ts +++ b/src/app/plugins/custom-emoji/imagePackCache.ts @@ -15,7 +15,7 @@ import { PackAddress } from './PackAddress'; import { ImagePack } from './ImagePack'; -import { PackContent, PackImages } from './types'; +import { type PackContent, type PackImages } from './types'; // -------------------------------------------------------------------------- // Types stored in localStorage diff --git a/src/app/plugins/custom-emoji/types.ts b/src/app/plugins/custom-emoji/types.ts index 8794beda5..8d84f4c37 100644 --- a/src/app/plugins/custom-emoji/types.ts +++ b/src/app/plugins/custom-emoji/types.ts @@ -1,4 +1,4 @@ -import { IImageInfo } from '$types/matrix/common'; +import { type IImageInfo } from '$types/matrix/common'; // https://github.com/Sorunome/matrix-doc/blob/soru/emotes/proposals/2545-emotes.md diff --git a/src/app/plugins/custom-emoji/utils.ts b/src/app/plugins/custom-emoji/utils.ts index 4b35cad19..7e7f3d04b 100644 --- a/src/app/plugins/custom-emoji/utils.ts +++ b/src/app/plugins/custom-emoji/utils.ts @@ -1,11 +1,11 @@ -import { MatrixClient, MatrixEvent, Room } from '$types/matrix-sdk'; +import { type MatrixClient, type MatrixEvent, type Room } from '$types/matrix-sdk'; import { StateEvent } from '$types/matrix/room'; import { getAccountData, getStateEvent, getStateEvents } from '$utils/room'; import { AccountDataEvent } from '$types/matrix/accountData'; -import { ImageUsage } from './types'; +import { type ImageUsage } from './types'; import { ImagePack } from './ImagePack'; -import { PackMetaReader } from './PackMetaReader'; -import { PackAddress } from './PackAddress'; +import { type PackMetaReader } from './PackMetaReader'; +import { type PackAddress } from './PackAddress'; export function packAddressEqual(a1?: PackAddress, a2?: PackAddress): boolean { if (!a1 && !a2) return true; diff --git a/src/app/plugins/emoji.ts b/src/app/plugins/emoji.ts index 2462b7ffe..d75491b38 100644 --- a/src/app/plugins/emoji.ts +++ b/src/app/plugins/emoji.ts @@ -1,4 +1,4 @@ -import { CompactEmoji, fromUnicodeToHexcode } from 'emojibase'; +import { type CompactEmoji, fromUnicodeToHexcode } from 'emojibase'; import emojisData from 'emojibase-data/en/compact.json'; import joypixels from 'emojibase-data/en/shortcodes/joypixels.json'; import emojibase from 'emojibase-data/en/shortcodes/emojibase.json'; diff --git a/src/app/plugins/markdown/block/parser.ts b/src/app/plugins/markdown/block/parser.ts index b56d3e3b6..75b457df5 100644 --- a/src/app/plugins/markdown/block/parser.ts +++ b/src/app/plugins/markdown/block/parser.ts @@ -10,7 +10,7 @@ import { HorizontalRuleRule, } from './rules'; import { runBlockRule } from './runner'; -import { BlockMDParser } from './type'; +import { type BlockMDParser } from './type'; /** * Parses block-level markdown text into HTML using defined block rules. diff --git a/src/app/plugins/markdown/block/rules.ts b/src/app/plugins/markdown/block/rules.ts index a5bfe2635..38d3d3f82 100644 --- a/src/app/plugins/markdown/block/rules.ts +++ b/src/app/plugins/markdown/block/rules.ts @@ -1,4 +1,4 @@ -import { BlockMDRule } from './type'; +import { type BlockMDRule } from './type'; const HEADING_REG_1 = /^(#{1,6}) +(.+)\n?/m; export const HeadingRule: BlockMDRule = { diff --git a/src/app/plugins/markdown/block/runner.ts b/src/app/plugins/markdown/block/runner.ts index 8e80c95ff..a151ab5d0 100644 --- a/src/app/plugins/markdown/block/runner.ts +++ b/src/app/plugins/markdown/block/runner.ts @@ -1,5 +1,5 @@ import { replaceMatch } from '$plugins/markdown/internal'; -import { BlockMDParser, BlockMDRule } from './type'; +import { type BlockMDParser, type BlockMDRule } from './type'; /** * Parses block-level markdown text into HTML using defined block rules. diff --git a/src/app/plugins/markdown/block/type.ts b/src/app/plugins/markdown/block/type.ts index 9462e1d50..8bebe6f2c 100644 --- a/src/app/plugins/markdown/block/type.ts +++ b/src/app/plugins/markdown/block/type.ts @@ -1,4 +1,4 @@ -import { MatchResult, MatchRule } from '$plugins/markdown/internal'; +import { type MatchResult, type MatchRule } from '$plugins/markdown/internal'; /** * Type for a function that parses block-level markdown into HTML. diff --git a/src/app/plugins/markdown/inline/parser.ts b/src/app/plugins/markdown/inline/parser.ts index 37c71a661..f8ded2459 100644 --- a/src/app/plugins/markdown/inline/parser.ts +++ b/src/app/plugins/markdown/inline/parser.ts @@ -10,7 +10,7 @@ import { UnderlineRule, } from './rules'; import { runInlineRule, runInlineRules } from './runner'; -import { InlineMDParser } from './type'; +import { type InlineMDParser } from './type'; const LeveledRules = [ BoldRule, diff --git a/src/app/plugins/markdown/inline/rules.ts b/src/app/plugins/markdown/inline/rules.ts index 77bcbd57a..fae82a458 100644 --- a/src/app/plugins/markdown/inline/rules.ts +++ b/src/app/plugins/markdown/inline/rules.ts @@ -1,4 +1,4 @@ -import { InlineMDRule } from './type'; +import { type InlineMDRule } from './type'; const MIN_ANY = '(.+?)'; const URL_NEG_LB = '(? = (item) => { const shortcode = `:${item.shortcode}:`; diff --git a/src/app/plugins/via-servers.ts b/src/app/plugins/via-servers.ts index e789e5f8f..8e7c44c3b 100644 --- a/src/app/plugins/via-servers.ts +++ b/src/app/plugins/via-servers.ts @@ -1,6 +1,6 @@ -import { Room } from '$types/matrix-sdk'; -import { IRoomCreateContent, StateEvent } from '$types/matrix/room'; -import { IPowerLevels } from '$hooks/usePowerLevels'; +import { type Room } from '$types/matrix-sdk'; +import { type IRoomCreateContent, StateEvent } from '$types/matrix/room'; +import { type IPowerLevels } from '$hooks/usePowerLevels'; import { creatorsSupported, getMxIdServer } from '$utils/matrix'; import { getStateEvent } from '$utils/room'; diff --git a/src/app/state/backupRestore.ts b/src/app/state/backupRestore.ts index 9c1c11479..223a8e0fc 100644 --- a/src/app/state/backupRestore.ts +++ b/src/app/state/backupRestore.ts @@ -1,5 +1,5 @@ import { atom } from 'jotai'; -import { ImportRoomKeyProgressData, ImportRoomKeyStage } from '$types/matrix-sdk'; +import { type ImportRoomKeyProgressData, ImportRoomKeyStage } from '$types/matrix-sdk'; export enum BackupProgressStatus { Idle, diff --git a/src/app/state/callEmbed.ts b/src/app/state/callEmbed.ts index b05055c43..126520122 100644 --- a/src/app/state/callEmbed.ts +++ b/src/app/state/callEmbed.ts @@ -1,6 +1,6 @@ import { atom } from 'jotai'; import * as Sentry from '@sentry/react'; -import { CallEmbed } from '../plugins/call'; +import { type CallEmbed } from '../plugins/call'; const baseCallEmbedAtom = atom(undefined); diff --git a/src/app/state/callPreferences.ts b/src/app/state/callPreferences.ts index a8e82067f..541f610c3 100644 --- a/src/app/state/callPreferences.ts +++ b/src/app/state/callPreferences.ts @@ -1,4 +1,4 @@ -import { WritableAtom } from 'jotai'; +import { type WritableAtom } from 'jotai'; import { atomWithLocalStorage, getLocalStorageItem, diff --git a/src/app/state/closedLobbyCategories.ts b/src/app/state/closedLobbyCategories.ts index 3c5c99e16..6e1b2325e 100644 --- a/src/app/state/closedLobbyCategories.ts +++ b/src/app/state/closedLobbyCategories.ts @@ -1,4 +1,4 @@ -import { WritableAtom, atom } from 'jotai'; +import { type WritableAtom, atom } from 'jotai'; import { produce } from 'immer'; import { atomWithLocalStorage, diff --git a/src/app/state/closedNavCategories.ts b/src/app/state/closedNavCategories.ts index 8c2348902..4126d6e73 100644 --- a/src/app/state/closedNavCategories.ts +++ b/src/app/state/closedNavCategories.ts @@ -1,4 +1,4 @@ -import { WritableAtom, atom } from 'jotai'; +import { type WritableAtom, atom } from 'jotai'; import { produce } from 'immer'; import { atomWithLocalStorage, diff --git a/src/app/state/createRoomModal.ts b/src/app/state/createRoomModal.ts index 16757ec71..d341da2bc 100644 --- a/src/app/state/createRoomModal.ts +++ b/src/app/state/createRoomModal.ts @@ -1,5 +1,5 @@ import { atom } from 'jotai'; -import { CreateRoomType } from '$components/create-room/types'; +import { type CreateRoomType } from '$components/create-room/types'; export type CreateRoomModalState = { spaceId?: string; diff --git a/src/app/state/hooks/callPreferences.ts b/src/app/state/hooks/callPreferences.ts index d02700f05..ce75555a3 100644 --- a/src/app/state/hooks/callPreferences.ts +++ b/src/app/state/hooks/callPreferences.ts @@ -1,6 +1,6 @@ import { createContext, useCallback, useContext } from 'react'; import { useAtom } from 'jotai'; -import { CallPreferences, CallPreferencesAtom } from '../callPreferences'; +import { type CallPreferences, type CallPreferencesAtom } from '../callPreferences'; const CallPreferencesAtomContext = createContext(null); export const CallPreferencesProvider = CallPreferencesAtomContext.Provider; diff --git a/src/app/state/hooks/closedLobbyCategories.ts b/src/app/state/hooks/closedLobbyCategories.ts index 19843b6e6..eed808009 100644 --- a/src/app/state/hooks/closedLobbyCategories.ts +++ b/src/app/state/hooks/closedLobbyCategories.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { ClosedLobbyCategoriesAtom } from '$state/closedLobbyCategories'; +import { type ClosedLobbyCategoriesAtom } from '$state/closedLobbyCategories'; const ClosedLobbyCategoriesAtomContext = createContext(null); export const ClosedLobbyCategoriesProvider = ClosedLobbyCategoriesAtomContext.Provider; diff --git a/src/app/state/hooks/closedNavCategories.ts b/src/app/state/hooks/closedNavCategories.ts index 38a962e48..ee95e19b6 100644 --- a/src/app/state/hooks/closedNavCategories.ts +++ b/src/app/state/hooks/closedNavCategories.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { ClosedNavCategoriesAtom } from '$state/closedNavCategories'; +import { type ClosedNavCategoriesAtom } from '$state/closedNavCategories'; const ClosedNavCategoriesAtomContext = createContext(null); export const ClosedNavCategoriesProvider = ClosedNavCategoriesAtomContext.Provider; diff --git a/src/app/state/hooks/createRoomModal.ts b/src/app/state/hooks/createRoomModal.ts index 8c1ec8b70..cb7f076b9 100644 --- a/src/app/state/hooks/createRoomModal.ts +++ b/src/app/state/hooks/createRoomModal.ts @@ -1,7 +1,7 @@ import { useCallback } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; -import { CreateRoomType } from '$components/create-room/types'; -import { createRoomModalAtom, CreateRoomModalState } from '$state/createRoomModal'; +import { type CreateRoomType } from '$components/create-room/types'; +import { createRoomModalAtom, type CreateRoomModalState } from '$state/createRoomModal'; export const useCreateRoomModalState = (): CreateRoomModalState | undefined => { const data = useAtomValue(createRoomModalAtom); diff --git a/src/app/state/hooks/createSpaceModal.ts b/src/app/state/hooks/createSpaceModal.ts index 4661712d0..7edf1a0e1 100644 --- a/src/app/state/hooks/createSpaceModal.ts +++ b/src/app/state/hooks/createSpaceModal.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; -import { createSpaceModalAtom, CreateSpaceModalState } from '$state/createSpaceModal'; +import { createSpaceModalAtom, type CreateSpaceModalState } from '$state/createSpaceModal'; export const useCreateSpaceModalState = (): CreateSpaceModalState | undefined => { const data = useAtomValue(createSpaceModalAtom); diff --git a/src/app/state/hooks/navToActivePath.ts b/src/app/state/hooks/navToActivePath.ts index 412247600..cdd22253c 100644 --- a/src/app/state/hooks/navToActivePath.ts +++ b/src/app/state/hooks/navToActivePath.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { NavToActivePathAtom } from '$state/navToActivePath'; +import { type NavToActivePathAtom } from '$state/navToActivePath'; const NavToActivePathAtomContext = createContext(null); export const NavToActivePathProvider = NavToActivePathAtomContext.Provider; diff --git a/src/app/state/hooks/openedSidebarFolder.ts b/src/app/state/hooks/openedSidebarFolder.ts index 6a5e61f92..1d8f32339 100644 --- a/src/app/state/hooks/openedSidebarFolder.ts +++ b/src/app/state/hooks/openedSidebarFolder.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { OpenedSidebarFolderAtom } from '$state/openedSidebarFolder'; +import { type OpenedSidebarFolderAtom } from '$state/openedSidebarFolder'; const OpenedSidebarFolderAtomContext = createContext(null); export const OpenedSidebarFolderProvider = OpenedSidebarFolderAtomContext.Provider; diff --git a/src/app/state/hooks/roomList.ts b/src/app/state/hooks/roomList.ts index 708909266..7de175f6a 100644 --- a/src/app/state/hooks/roomList.ts +++ b/src/app/state/hooks/roomList.ts @@ -1,9 +1,9 @@ -import { Atom, useAtomValue } from 'jotai'; +import { type Atom, useAtomValue } from 'jotai'; import { selectAtom } from 'jotai/utils'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { useCallback, useMemo } from 'react'; import { getAllParents, isRoom, isSpace, isUnsupportedRoom } from '$utils/room'; -import { RoomToParents } from '$types/matrix/room'; +import { type RoomToParents } from '$types/matrix/room'; import { compareRoomsEqual } from '$state/room-list/utils'; export type RoomsAtom = Atom; diff --git a/src/app/state/hooks/roomSettings.ts b/src/app/state/hooks/roomSettings.ts index 8a0784870..f53b29f93 100644 --- a/src/app/state/hooks/roomSettings.ts +++ b/src/app/state/hooks/roomSettings.ts @@ -1,6 +1,10 @@ import { useCallback } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; -import { roomSettingsAtom, RoomSettingsPage, RoomSettingsState } from '$state/roomSettings'; +import { + roomSettingsAtom, + type RoomSettingsPage, + type RoomSettingsState, +} from '$state/roomSettings'; export const useRoomSettingsState = (): RoomSettingsState | undefined => { const data = useAtomValue(roomSettingsAtom); diff --git a/src/app/state/hooks/settings.ts b/src/app/state/hooks/settings.ts index d28c48336..2f49f98fd 100644 --- a/src/app/state/hooks/settings.ts +++ b/src/app/state/hooks/settings.ts @@ -1,7 +1,7 @@ import { atom, useAtomValue, useSetAtom } from 'jotai'; import { selectAtom } from 'jotai/utils'; import { useMemo } from 'react'; -import { Settings, settingsAtom as sAtom } from '$state/settings'; +import { type Settings, type settingsAtom as sAtom } from '$state/settings'; export type SettingSetter = | Settings[K] diff --git a/src/app/state/hooks/spaceSettings.ts b/src/app/state/hooks/spaceSettings.ts index ab3b8da20..e5672efc6 100644 --- a/src/app/state/hooks/spaceSettings.ts +++ b/src/app/state/hooks/spaceSettings.ts @@ -1,6 +1,10 @@ import { useCallback } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; -import { spaceSettingsAtom, SpaceSettingsPage, SpaceSettingsState } from '$state/spaceSettings'; +import { + spaceSettingsAtom, + type SpaceSettingsPage, + type SpaceSettingsState, +} from '$state/spaceSettings'; export const useSpaceSettingsState = (): SpaceSettingsState | undefined => { const data = useAtomValue(spaceSettingsAtom); diff --git a/src/app/state/hooks/unread.ts b/src/app/state/hooks/unread.ts index ac94bb6a3..87e705a37 100644 --- a/src/app/state/hooks/unread.ts +++ b/src/app/state/hooks/unread.ts @@ -1,8 +1,8 @@ import { useCallback } from 'react'; import { useAtomValue } from 'jotai'; import { selectAtom } from 'jotai/utils'; -import { RoomToUnread, Unread } from '$types/matrix/room'; -import { roomToUnreadAtom, unreadEqual } from '$state/room/roomToUnread'; +import { type RoomToUnread, type Unread } from '$types/matrix/room'; +import { type roomToUnreadAtom, unreadEqual } from '$state/room/roomToUnread'; const compareUnreadEqual = (u1?: Unread, u2?: Unread): boolean => { if (!u1 || !u2) return false; diff --git a/src/app/state/hooks/useBindAtoms.ts b/src/app/state/hooks/useBindAtoms.ts index 1d68295d0..6c1d602ed 100644 --- a/src/app/state/hooks/useBindAtoms.ts +++ b/src/app/state/hooks/useBindAtoms.ts @@ -1,4 +1,4 @@ -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { allInvitesAtom, useBindAllInvitesAtom } from '$state/room-list/inviteList'; import { allRoomsAtom, useBindAllRoomsAtom } from '$state/room-list/roomList'; import { mDirectAtom, useBindMDirectAtom } from '$state/mDirectList'; diff --git a/src/app/state/hooks/userRoomProfile.ts b/src/app/state/hooks/userRoomProfile.ts index c0e8edcb6..fe8a2df00 100644 --- a/src/app/state/hooks/userRoomProfile.ts +++ b/src/app/state/hooks/userRoomProfile.ts @@ -1,8 +1,8 @@ import { useCallback } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; -import { Position, RectCords } from 'folds'; -import { UserProfile } from '$hooks/useUserProfile'; -import { userRoomProfileAtom, UserRoomProfileState } from '$state/userRoomProfile'; +import { type Position, type RectCords } from 'folds'; +import { type UserProfile } from '$hooks/useUserProfile'; +import { userRoomProfileAtom, type UserRoomProfileState } from '$state/userRoomProfile'; export const useUserRoomProfileState = (): UserRoomProfileState | undefined => { const data = useAtomValue(userRoomProfileAtom); diff --git a/src/app/state/mDirectList.ts b/src/app/state/mDirectList.ts index 89b3721f4..a80b085b2 100644 --- a/src/app/state/mDirectList.ts +++ b/src/app/state/mDirectList.ts @@ -1,5 +1,5 @@ import { atom, useSetAtom } from 'jotai'; -import { ClientEvent, MatrixClient, MatrixEvent } from '$types/matrix-sdk'; +import { ClientEvent, type MatrixClient, type MatrixEvent } from '$types/matrix-sdk'; import { useEffect } from 'react'; import { AccountDataEvent } from '$types/matrix/accountData'; import { getAccountData, getMDirects } from '$utils/room'; diff --git a/src/app/state/modal.ts b/src/app/state/modal.ts index 5b54dc637..bc027ec7d 100644 --- a/src/app/state/modal.ts +++ b/src/app/state/modal.ts @@ -1,5 +1,5 @@ import { atom } from 'jotai'; -import { MatrixEvent, Room, Relations } from '$types/matrix-sdk'; +import { type MatrixEvent, type Room, type Relations } from '$types/matrix-sdk'; export enum ModalType { Delete = 'delete', diff --git a/src/app/state/navToActivePath.ts b/src/app/state/navToActivePath.ts index affc313da..47191f177 100644 --- a/src/app/state/navToActivePath.ts +++ b/src/app/state/navToActivePath.ts @@ -1,6 +1,6 @@ -import { WritableAtom, atom } from 'jotai'; +import { type WritableAtom, atom } from 'jotai'; import { produce } from 'immer'; -import { Path } from 'react-router-dom'; +import { type Path } from 'react-router-dom'; import { atomWithLocalStorage, getLocalStorageItem, diff --git a/src/app/state/nicknames.ts b/src/app/state/nicknames.ts index ca67302a1..d55f73620 100644 --- a/src/app/state/nicknames.ts +++ b/src/app/state/nicknames.ts @@ -1,5 +1,5 @@ import { atom } from 'jotai'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { AccountDataEvent } from '$types/matrix/accountData'; export const NICKNAMES_KEY = 'sableNicknames'; diff --git a/src/app/state/openedSidebarFolder.ts b/src/app/state/openedSidebarFolder.ts index 743160d4b..837335064 100644 --- a/src/app/state/openedSidebarFolder.ts +++ b/src/app/state/openedSidebarFolder.ts @@ -1,4 +1,4 @@ -import { WritableAtom, atom } from 'jotai'; +import { type WritableAtom, atom } from 'jotai'; import { produce } from 'immer'; import { atomWithLocalStorage, diff --git a/src/app/state/room-list/inviteList.ts b/src/app/state/room-list/inviteList.ts index 4d33b3323..132856039 100644 --- a/src/app/state/room-list/inviteList.ts +++ b/src/app/state/room-list/inviteList.ts @@ -1,8 +1,8 @@ -import { atom, WritableAtom } from 'jotai'; -import { MatrixClient } from '$types/matrix-sdk'; +import { atom, type WritableAtom } from 'jotai'; +import { type MatrixClient } from '$types/matrix-sdk'; import { useMemo } from 'react'; import { Membership } from '$types/matrix/room'; -import { RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; +import { type RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; const baseRoomsAtom = atom([]); export const allInvitesAtom = atom( diff --git a/src/app/state/room-list/roomList.ts b/src/app/state/room-list/roomList.ts index c3437d930..5e1fce982 100644 --- a/src/app/state/room-list/roomList.ts +++ b/src/app/state/room-list/roomList.ts @@ -1,8 +1,8 @@ import { atom } from 'jotai'; -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; import { useMemo } from 'react'; import { Membership } from '$types/matrix/room'; -import { RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; +import { type RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; const baseRoomsAtom = atom([]); export const allRoomsAtom = atom( diff --git a/src/app/state/room-list/utils.ts b/src/app/state/room-list/utils.ts index 9758a1ba6..aad1ecf44 100644 --- a/src/app/state/room-list/utils.ts +++ b/src/app/state/room-list/utils.ts @@ -1,7 +1,7 @@ -import { useSetAtom, WritableAtom } from 'jotai'; -import { ClientEvent, MatrixClient, Room, RoomEvent } from '$types/matrix-sdk'; +import { useSetAtom, type WritableAtom } from 'jotai'; +import { ClientEvent, type MatrixClient, type Room, RoomEvent } from '$types/matrix-sdk'; import { useEffect } from 'react'; -import { Membership } from '$types/matrix/room'; +import { type Membership } from '$types/matrix/room'; export type RoomsAction = | { diff --git a/src/app/state/room/roomInputDrafts.ts b/src/app/state/room/roomInputDrafts.ts index 4b167f220..852c84ac2 100644 --- a/src/app/state/room/roomInputDrafts.ts +++ b/src/app/state/room/roomInputDrafts.ts @@ -1,9 +1,9 @@ import { atom } from 'jotai'; import { atomFamily } from 'jotai/utils'; -import { Descendant } from 'slate'; -import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; -import { IEventRelation } from '$types/matrix-sdk'; -import { TUploadContent } from '$utils/matrix'; +import { type Descendant } from 'slate'; +import { type EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { type IEventRelation } from '$types/matrix-sdk'; +import { type TUploadContent } from '$utils/matrix'; import { createUploadAtomFamily } from '$state/upload'; import { createListAtom } from '$state/list'; diff --git a/src/app/state/room/roomToParents.ts b/src/app/state/room/roomToParents.ts index 65b0a3a36..eda09678f 100644 --- a/src/app/state/room/roomToParents.ts +++ b/src/app/state/room/roomToParents.ts @@ -2,15 +2,15 @@ import { produce } from 'immer'; import { atom, useSetAtom } from 'jotai'; import { ClientEvent, - MatrixClient, - MatrixEvent, - Room, + type MatrixClient, + type MatrixEvent, + type Room, RoomEvent, RoomStateEvent, SyncState, } from '$types/matrix-sdk'; import { useCallback, useEffect } from 'react'; -import { Membership, RoomToParents, StateEvent } from '$types/matrix/room'; +import { Membership, type RoomToParents, StateEvent } from '$types/matrix/room'; import { getRoomToParents, getSpaceChildren, diff --git a/src/app/state/room/roomToUnread.ts b/src/app/state/room/roomToUnread.ts index e70271d2c..06a4b8421 100644 --- a/src/app/state/room/roomToUnread.ts +++ b/src/app/state/room/roomToUnread.ts @@ -1,14 +1,14 @@ import { produce } from 'immer'; import { atom, useAtomValue, useSetAtom } from 'jotai'; import { - IRoomTimelineData, - MatrixClient, - MatrixEvent, - Room, + type IRoomTimelineData, + type MatrixClient, + type MatrixEvent, + type Room, RoomEvent, SyncState, - ReceiptContent, - ReceiptType, + type ReceiptContent, + type ReceiptType, EventType, ClientEvent, } from '$types/matrix-sdk'; @@ -16,9 +16,9 @@ import { useCallback, useEffect, useRef } from 'react'; import { Membership, NotificationType, - RoomToUnread, - UnreadInfo, - Unread, + type RoomToUnread, + type UnreadInfo, + type Unread, StateEvent, } from '$types/matrix/room'; import { diff --git a/src/app/state/sessions.ts b/src/app/state/sessions.ts index aadf20ce9..b90e2e650 100644 --- a/src/app/state/sessions.ts +++ b/src/app/state/sessions.ts @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { atom } from 'jotai'; import { createLogger } from '$utils/debug'; import { diff --git a/src/app/state/typingMembers.ts b/src/app/state/typingMembers.ts index 9f2a357b7..1e31cab0b 100644 --- a/src/app/state/typingMembers.ts +++ b/src/app/state/typingMembers.ts @@ -1,6 +1,10 @@ import { produce } from 'immer'; import { atom, useSetAtom } from 'jotai'; -import { MatrixClient, RoomMemberEvent, RoomMemberEventHandlerMap } from '$types/matrix-sdk'; +import { + type MatrixClient, + RoomMemberEvent, + type RoomMemberEventHandlerMap, +} from '$types/matrix-sdk'; import { useEffect } from 'react'; import { useSetting } from './hooks/settings'; import { settingsAtom } from './settings'; diff --git a/src/app/state/upload.ts b/src/app/state/upload.ts index 827e4bfd4..125db34f2 100644 --- a/src/app/state/upload.ts +++ b/src/app/state/upload.ts @@ -1,9 +1,14 @@ import { atom, useAtom } from 'jotai'; import { atomFamily } from 'jotai/utils'; -import { MatrixClient, UploadResponse, UploadProgress, MatrixError } from '$types/matrix-sdk'; +import { + type MatrixClient, + type UploadResponse, + type UploadProgress, + type MatrixError, +} from '$types/matrix-sdk'; import { useCallback } from 'react'; import { useThrottle } from '$hooks/useThrottle'; -import { uploadContent, TUploadContent } from '$utils/matrix'; +import { uploadContent, type TUploadContent } from '$utils/matrix'; export enum UploadStatus { Idle = 'idle', diff --git a/src/app/state/userRoomProfile.ts b/src/app/state/userRoomProfile.ts index 04540fcd2..1ed20a3a0 100644 --- a/src/app/state/userRoomProfile.ts +++ b/src/app/state/userRoomProfile.ts @@ -1,4 +1,4 @@ -import { Position, RectCords } from 'folds'; +import { type Position, type RectCords } from 'folds'; import { atom } from 'jotai'; import type { UserProfile } from '$hooks/useUserProfile'; diff --git a/src/app/styles/ContainerColor.css.ts b/src/app/styles/ContainerColor.css.ts index cefc5256a..2f8310751 100644 --- a/src/app/styles/ContainerColor.css.ts +++ b/src/app/styles/ContainerColor.css.ts @@ -1,6 +1,6 @@ -import { ComplexStyleRule } from '@vanilla-extract/css'; -import { RecipeVariants, recipe } from '@vanilla-extract/recipes'; -import { ContainerColor as TContainerColor, DefaultReset, color, config } from 'folds'; +import { type ComplexStyleRule } from '@vanilla-extract/css'; +import { type RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { type ContainerColor as TContainerColor, DefaultReset, color, config } from 'folds'; const getVariant = (variant: TContainerColor): ComplexStyleRule => ({ vars: { diff --git a/src/app/utils/addStickerToDefaultStickerPack.ts b/src/app/utils/addStickerToDefaultStickerPack.ts index a9715a05f..d0d40d8b0 100644 --- a/src/app/utils/addStickerToDefaultStickerPack.ts +++ b/src/app/utils/addStickerToDefaultStickerPack.ts @@ -1,7 +1,7 @@ -import { PackContent, ImageUsage } from '$plugins/custom-emoji'; +import { type PackContent, ImageUsage } from '$plugins/custom-emoji'; import { AccountDataEvent } from '$types/matrix/accountData'; -import { IImageInfo } from '$types/matrix/common'; -import { MatrixClient } from 'matrix-js-sdk'; +import { type IImageInfo } from '$types/matrix/common'; +import { type MatrixClient } from 'matrix-js-sdk'; // Utility function to add a sticker to the default sticker pack // For now this only works for unencrypted stickers diff --git a/src/app/utils/common.ts b/src/app/utils/common.ts index fb1e0b16b..8a7fd79a5 100644 --- a/src/app/utils/common.ts +++ b/src/app/utils/common.ts @@ -1,4 +1,4 @@ -import { IconName, IconSrc } from 'folds'; +import { type IconName, type IconSrc } from 'folds'; export const bytesToSize = (bytes: number): string => { const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; diff --git a/src/app/utils/delayedEvents.ts b/src/app/utils/delayedEvents.ts index 488c51d1c..bbf6245f4 100644 --- a/src/app/utils/delayedEvents.ts +++ b/src/app/utils/delayedEvents.ts @@ -1,12 +1,13 @@ import { EventType, - IContent, - MatrixClient, + type IContent, + type MatrixClient, MatrixEvent, - Room, + type Room, UpdateDelayedEventAction, + type DelayedEventInfo, + type SendDelayedEventResponse, } from '$types/matrix-sdk'; -import type { DelayedEventInfo, SendDelayedEventResponse } from '$types/matrix-sdk'; // Grab types needed for encryption interface EncryptableBackend { diff --git a/src/app/utils/keyboard.ts b/src/app/utils/keyboard.ts index ad0463dd1..5933deeef 100644 --- a/src/app/utils/keyboard.ts +++ b/src/app/utils/keyboard.ts @@ -1,5 +1,5 @@ import { isKeyHotkey } from 'is-hotkey'; -import { KeyboardEventHandler } from 'react'; +import { type KeyboardEventHandler } from 'react'; export interface KeyboardEventLike { key: string; diff --git a/src/app/utils/matrix-crypto.ts b/src/app/utils/matrix-crypto.ts index 144a51dfe..da69e01cc 100644 --- a/src/app/utils/matrix-crypto.ts +++ b/src/app/utils/matrix-crypto.ts @@ -1,4 +1,4 @@ -import { CryptoApi } from '$types/matrix-sdk'; +import { type CryptoApi } from '$types/matrix-sdk'; export const verifiedDevice = async ( api: CryptoApi, diff --git a/src/app/utils/matrix-uia.ts b/src/app/utils/matrix-uia.ts index 4fc10e448..6a6af369f 100644 --- a/src/app/utils/matrix-uia.ts +++ b/src/app/utils/matrix-uia.ts @@ -1,4 +1,4 @@ -import { AuthType, IAuthData, UIAFlow } from '$types/matrix-sdk'; +import { AuthType, type IAuthData, type UIAFlow } from '$types/matrix-sdk'; export const getSupportedUIAFlows = (uiaFlows: UIAFlow[], supportedStages: string[]): UIAFlow[] => { const supportedUIAFlows = uiaFlows.filter((flow) => diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index f04f71d90..f7562ce29 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -1,21 +1,21 @@ import { - EncryptedAttachmentInfo, + type EncryptedAttachmentInfo, decryptAttachment, encryptAttachment, } from 'browser-encrypt-attachment'; import { EventTimeline, - EventTimelineSet, - MatrixClient, + type EventTimelineSet, + type MatrixClient, MatrixError, - MatrixEvent, - Room, - RoomMember, - UploadProgress, - UploadResponse, + type MatrixEvent, + type Room, + type RoomMember, + type UploadProgress, + type UploadResponse, } from '$types/matrix-sdk'; import to from 'await-to-js'; -import { IImageInfo, IThumbnailContent, IVideoInfo } from '$types/matrix/common'; +import { type IImageInfo, type IThumbnailContent, type IVideoInfo } from '$types/matrix/common'; import { AccountDataEvent } from '$types/matrix/accountData'; import { Membership, MessageEvent, StateEvent } from '$types/matrix/room'; import * as Sentry from '@sentry/react'; diff --git a/src/app/utils/notifications.ts b/src/app/utils/notifications.ts index a6d47b7a8..2454b4f32 100644 --- a/src/app/utils/notifications.ts +++ b/src/app/utils/notifications.ts @@ -1,4 +1,4 @@ -import { MatrixClient, ReceiptType } from '$types/matrix-sdk'; +import { type MatrixClient, ReceiptType } from '$types/matrix-sdk'; export async function markAsRead(mx: MatrixClient, roomId: string, privateReceipt: boolean) { const room = mx.getRoom(roomId); diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index 34fb527d8..4cc6a1af7 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -1,34 +1,34 @@ -import { IconName, IconSrc } from 'folds'; +import { type IconName, type IconSrc } from 'folds'; import { EventTimeline, - EventTimelineSet, + type EventTimelineSet, EventType, - IMentions, - IPowerLevelsContent, - IPushRule, - IPushRules, + type IMentions, + type IPowerLevelsContent, + type IPushRule, + type IPushRules, JoinRule, - MatrixClient, - MatrixEvent, + type MatrixClient, + type MatrixEvent, NotificationCountType, PushProcessor, RelationType, - Room, - RoomMember, - CryptoBackend, + type Room, + type RoomMember, + type CryptoBackend, MsgType, } from '$types/matrix-sdk'; -import { AccountDataEvent } from '$types/matrix/accountData'; +import { type AccountDataEvent } from '$types/matrix/accountData'; import { - IRoomCreateContent, + type IRoomCreateContent, Membership, NotificationType, - RoomToParents, + type RoomToParents, RoomType, MessageEvent, StateEvent, - UnreadInfo, + type UnreadInfo, } from '$types/matrix/room'; import * as Sentry from '@sentry/react'; diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts index e862fa9f3..524357f45 100644 --- a/src/app/utils/sanitize.ts +++ b/src/app/utils/sanitize.ts @@ -1,4 +1,4 @@ -import sanitizeHtml, { Transformer } from 'sanitize-html'; +import sanitizeHtml, { type Transformer } from 'sanitize-html'; const MAX_TAG_NESTING = 100; diff --git a/src/app/utils/sendFeedbackToUser.ts b/src/app/utils/sendFeedbackToUser.ts index c1fa7ab42..8f44b53b3 100644 --- a/src/app/utils/sendFeedbackToUser.ts +++ b/src/app/utils/sendFeedbackToUser.ts @@ -1,4 +1,4 @@ -import { MatrixEvent, Room } from 'matrix-js-sdk'; +import { MatrixEvent, type Room } from 'matrix-js-sdk'; export function sendFeedback(msg: string, room: Room, userId: string) { const localNotice = new MatrixEvent({ diff --git a/src/app/utils/settingsSync.ts b/src/app/utils/settingsSync.ts index a154ff92d..3493187cf 100644 --- a/src/app/utils/settingsSync.ts +++ b/src/app/utils/settingsSync.ts @@ -1,4 +1,4 @@ -import { Settings } from '$state/settings'; +import { type Settings } from '$state/settings'; /** * Keys excluded from cross-device sync. diff --git a/src/app/utils/sort.ts b/src/app/utils/sort.ts index 2f99e757a..42e12801e 100644 --- a/src/app/utils/sort.ts +++ b/src/app/utils/sort.ts @@ -1,4 +1,4 @@ -import { MatrixClient } from '$types/matrix-sdk'; +import { type MatrixClient } from '$types/matrix-sdk'; export type SortFunc = (a: T, b: T) => number; diff --git a/src/app/utils/timeline.ts b/src/app/utils/timeline.ts index 4ed92ab16..3bf61fadf 100644 --- a/src/app/utils/timeline.ts +++ b/src/app/utils/timeline.ts @@ -1,4 +1,4 @@ -import { Direction, EventTimeline, MatrixEvent, Room } from '$types/matrix-sdk'; +import { Direction, type EventTimeline, type MatrixEvent, type Room } from '$types/matrix-sdk'; import { roomHaveNotification, roomHaveUnread, reactionOrEditEvent } from '$utils/room'; export const PAGINATION_LIMIT = 60; diff --git a/src/client/initMatrix.ts b/src/client/initMatrix.ts index 18809c5d2..67dc1ee43 100644 --- a/src/client/initMatrix.ts +++ b/src/client/initMatrix.ts @@ -1,18 +1,18 @@ import { ClientEvent, createClient, - MatrixClient, + type MatrixClient, IndexedDBStore, IndexedDBCryptoStore, SyncState, - ISyncStateData, + type ISyncStateData, } from '$types/matrix-sdk'; import { clearNavToActivePathStore } from '$state/navToActivePath'; import { - Session, - Sessions, - SessionStoreName, + type Session, + type Sessions, + type SessionStoreName, getSessionStoreName, MATRIX_SESSIONS_KEY, } from '$state/sessions'; @@ -22,7 +22,11 @@ import { createDebugLogger } from '$utils/debugLogger'; import * as Sentry from '@sentry/react'; import { pushSessionToSW } from '../sw-session'; import { cryptoCallbacks } from './secretStorageKeys'; -import { SlidingSyncConfig, SlidingSyncDiagnostics, SlidingSyncManager } from './slidingSync'; +import { + type SlidingSyncConfig, + type SlidingSyncDiagnostics, + SlidingSyncManager, +} from './slidingSync'; const log = createLogger('initMatrix'); const debugLog = createDebugLogger('initMatrix'); diff --git a/src/client/slidingSync.ts b/src/client/slidingSync.ts index 096f77f43..2e11750ac 100644 --- a/src/client/slidingSync.ts +++ b/src/client/slidingSync.ts @@ -1,13 +1,13 @@ /* eslint-disable max-classes-per-file */ import { ClientEvent, - Extension, + type Extension, ExtensionState, KnownMembership, - MatrixClient, - MSC3575List, - MSC3575RoomData, - MSC3575RoomSubscription, + type MatrixClient, + type MSC3575List, + type MSC3575RoomData, + type MSC3575RoomSubscription, MSC3575_WILDCARD, RoomMemberEvent, SlidingSync, diff --git a/src/index.tsx b/src/index.tsx index 4f2e57245..614ff3dbb 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -21,7 +21,7 @@ import { pushSessionToSW } from './sw-session'; import { getFallbackSession, MATRIX_SESSIONS_KEY, - Sessions, + type Sessions, ACTIVE_SESSION_KEY, } from './app/state/sessions'; import { createLogger } from './app/utils/debug'; diff --git a/src/types/matrix/common.ts b/src/types/matrix/common.ts index e91993578..e0f3a064e 100644 --- a/src/types/matrix/common.ts +++ b/src/types/matrix/common.ts @@ -1,5 +1,5 @@ -import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; -import { MsgType } from '$types/matrix-sdk'; +import { type EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { type MsgType } from '$types/matrix-sdk'; export const MATRIX_BLUR_HASH_PROPERTY_NAME = 'xyz.amorgan.blurhash'; export const MATRIX_SPOILER_PROPERTY_NAME = 'page.codeberg.everypizza.msc4193.spoiler'; diff --git a/src/types/matrix/room.ts b/src/types/matrix/room.ts index f851b9e42..eac297412 100644 --- a/src/types/matrix/room.ts +++ b/src/types/matrix/room.ts @@ -1,4 +1,4 @@ -import { IImageInfo } from './common'; +import { type IImageInfo } from './common'; export enum Membership { Invite = 'invite', diff --git a/tsconfig.json b/tsconfig.json index 35f50caf8..80d6c8ece 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,7 @@ "composite": true, "forceConsistentCasingInFileNames": true, "isolatedModules": true, - // "verbatimModuleSyntax": true, + "verbatimModuleSyntax": true, "noEmit": true, "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.tsbuildinfo", "baseUrl": ".", From 94f7ce909ab0d9b426d45a1776606c86f9525844 Mon Sep 17 00:00:00 2001 From: hazre Date: Mon, 30 Mar 2026 00:19:34 +0200 Subject: [PATCH 06/11] feat: add code quality enforcement Apply code quality enforcement across ESLint, storage guards, coverage checks, and contributor docs. Co-authored-by: Evie Gauthier --- .github/workflows/quality-checks.yml | 106 +++++++++++ CONTRIBUTING.md | 2 + docs/CODE_QUALITY.md | 161 ++++++++++++++++ eslint.config.js | 54 +++++- .../components/GlobalKeyboardShortcuts.tsx | 6 +- src/app/components/LogoutDialog.tsx | 2 +- src/app/components/RenderMessageContent.tsx | 4 +- src/app/components/SwipeableChatWrapper.tsx | 4 +- .../components/SwipeableOverlayWrapper.tsx | 4 +- .../create-room/AdditionalCreatorInput.tsx | 4 +- src/app/components/editor/Editor.tsx | 2 +- src/app/components/editor/Elements.tsx | 7 +- src/app/components/editor/Toolbar.tsx | 2 +- src/app/components/editor/input.ts | 30 +-- src/app/components/editor/output.ts | 2 +- src/app/components/editor/utils.ts | 20 +- src/app/components/emoji-board/EmojiBoard.tsx | 4 +- .../image-pack-view/ImagePackContent.tsx | 8 +- src/app/components/media/Video.tsx | 12 +- .../message/content/AudioContent.tsx | 11 +- .../NotificationBanner.tsx | 2 +- .../TelemetryConsentBanner.tsx | 13 +- src/app/components/time-date/DatePicker.tsx | 111 ++++++----- src/app/components/time-date/TimePicker.tsx | 46 +++-- .../components/url-preview/ClientPreview.tsx | 19 +- src/app/features/add-existing/AddExisting.tsx | 2 +- .../features/call-status/MemberSpeaking.tsx | 3 +- src/app/features/call/CallMemberCard.tsx | 4 +- src/app/features/call/CallView.tsx | 4 +- .../developer-tools/DevelopTools.tsx | 178 +++++++++--------- .../common-settings/general/RoomUpgrade.tsx | 2 +- .../common-settings/members/Members.tsx | 5 +- .../permissions/PowersEditor.tsx | 2 +- src/app/features/lobby/Lobby.tsx | 10 +- src/app/features/lobby/SpaceHierarchyItem.tsx | 2 +- .../features/message-search/MessageSearch.tsx | 4 +- .../features/message-search/SearchFilters.tsx | 2 +- .../message-search/useMessageSearch.ts | 2 +- .../abbreviations/RoomAbbreviations.tsx | 2 +- src/app/features/room/RoomCallButton.tsx | 4 +- src/app/features/room/RoomInput.tsx | 42 ++--- src/app/features/room/RoomTimeline.tsx | 4 +- src/app/features/room/RoomViewHeader.tsx | 8 +- src/app/features/room/ThreadDrawer.tsx | 8 +- src/app/features/room/message/Message.tsx | 2 +- .../features/room/message/MessageEditor.tsx | 2 +- src/app/features/room/message/Reactions.tsx | 2 +- .../room/reaction-viewer/ReactionViewer.tsx | 2 +- .../room/room-pin-menu/RoomPinMenu.tsx | 2 +- src/app/features/search/Search.tsx | 8 +- .../settings/account/TimezoneEditor.tsx | 4 +- .../settings/developer-tools/AccountData.tsx | 4 +- .../developer-tools/SentrySettings.tsx | 3 +- .../developer-tools/SyncDiagnostics.tsx | 6 +- .../settings/devices/OtherDevices.tsx | 2 +- .../settings/emojis-stickers/GlobalPacks.tsx | 18 +- src/app/features/settings/general/General.tsx | 26 +-- .../keyboard-shortcuts/KeyboardShortcuts.tsx | 2 +- .../features/widgets/IntegrationManager.tsx | 4 +- src/app/features/widgets/WidgetIframe.tsx | 8 +- .../hooks/timeline/useProcessedTimeline.ts | 8 +- src/app/hooks/timeline/useTimelineActions.ts | 4 +- .../timeline/useTimelineEventRenderer.tsx | 4 +- src/app/hooks/timeline/useTimelineSync.ts | 4 +- src/app/hooks/useAsyncSearch.ts | 2 +- src/app/hooks/useCallSignaling.ts | 6 +- src/app/hooks/useCommands.ts | 13 +- src/app/hooks/useComposingCheck.ts | 8 +- src/app/hooks/useDebounce.ts | 4 +- src/app/hooks/useImageGestures.ts | 4 +- src/app/hooks/useImagePackRooms.ts | 2 +- src/app/hooks/useImagePacks.ts | 17 +- src/app/hooks/useIntegrationManager.ts | 4 +- src/app/hooks/useMediaConfig.ts | 4 +- src/app/hooks/usePerMessageProfile.ts | 2 +- src/app/hooks/usePowerLevelTags.ts | 2 +- src/app/hooks/usePowerLevels.ts | 2 +- src/app/hooks/useRoomAbbreviations.ts | 2 +- src/app/hooks/useRoomAccountData.ts | 2 +- src/app/hooks/useRoomWidgets.ts | 4 +- src/app/hooks/useSidebarItems.ts | 4 +- src/app/hooks/useThrottle.ts | 4 +- .../pages/client/BackgroundNotifications.tsx | 4 +- src/app/pages/client/ClientRoot.tsx | 3 +- src/app/pages/client/direct/Direct.tsx | 2 +- src/app/pages/client/explore/Server.tsx | 2 +- src/app/pages/client/home/Home.tsx | 2 +- src/app/pages/client/inbox/Invites.tsx | 2 +- src/app/pages/client/inbox/Notifications.tsx | 4 +- src/app/pages/client/sidebar/SpaceTabs.tsx | 4 +- src/app/pages/client/space/Space.tsx | 13 +- src/app/plugins/bad-words.ts | 7 +- src/app/plugins/call/CallEmbed.ts | 4 +- src/app/plugins/call/CallWidgetDriver.ts | 2 +- src/app/plugins/custom-emoji/ImagePack.ts | 2 +- src/app/plugins/react-custom-html-parser.tsx | 2 +- src/app/plugins/text-area/Operations.ts | 4 +- src/app/plugins/text-area/TextUtils.ts | 2 +- src/app/plugins/utils.ts | 2 +- src/app/plugins/via-servers.ts | 2 +- .../voice-recorder-kit/useVoiceRecorder.ts | 14 +- src/app/state/closedLobbyCategories.ts | 2 +- src/app/state/closedNavCategories.ts | 2 +- src/app/state/mediaVolume.ts | 21 +++ src/app/state/openedSidebarFolder.ts | 2 +- src/app/state/room-list/utils.ts | 2 +- src/app/state/sentryStorage.ts | 28 +++ src/app/state/settings.ts | 4 +- src/app/state/spaceRooms.ts | 4 +- src/app/utils/AsyncSearch.ts | 2 +- src/app/utils/MegolmExportEncryption.ts | 2 +- src/app/utils/abbreviations.ts | 2 +- src/app/utils/debugLogger.ts | 6 +- src/app/utils/delayedEvents.ts | 4 +- src/app/utils/featureCheck.ts | 2 +- src/app/utils/keyboard.ts | 4 +- src/app/utils/matrix.ts | 4 +- src/app/utils/room.ts | 12 +- src/client/initMatrix.ts | 2 +- src/client/slidingSync.test.ts | 3 +- src/client/slidingSync.ts | 2 +- src/sw.ts | 4 +- vitest.config.ts | 8 + 123 files changed, 828 insertions(+), 496 deletions(-) create mode 100644 docs/CODE_QUALITY.md create mode 100644 src/app/state/mediaVolume.ts create mode 100644 src/app/state/sentryStorage.ts diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index a9ac43708..5d56101fd 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -97,6 +97,112 @@ jobs: - name: Run tests run: pnpm run test:run + coverage: + name: Coverage thresholds + runs-on: ubuntu-latest + if: github.head_ref != 'release' + permissions: + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Setup app + uses: ./.github/actions/setup + + - name: Run tests with coverage + run: pnpm run test:coverage + + missing-tests: + name: Check for missing tests + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' && github.head_ref != 'release' + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Check changed logic files for missing tests + id: check + run: | + BASE=${{ github.event.pull_request.base.sha }} + HEAD=${{ github.event.pull_request.head.sha }} + changed=$(git diff --name-only "$BASE" "$HEAD" -- 'src/**/*.ts' 'src/**/*.tsx' \ + | grep -v '\.test\.' | grep -v '\.spec\.' | grep -v '\.d\.ts' \ + | grep -v 'src/index\.tsx' | grep -v 'src/sw' | grep -v 'src/instrument' \ + | grep -v 'src/test/' || true) + missing="" + for f in $changed; do + base="${f%.*}" + if ! ls "${base}.test."* "${base}.spec."* 2>/dev/null | grep -q .; then + missing="$missing\n- $f" + fi + done + if [ -n "$missing" ]; then + echo "missing=true" >> $GITHUB_OUTPUT + printf 'files<> $GITHUB_OUTPUT + fi + + - name: Update PR comment + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + continue-on-error: true + with: + script: | + const marker = ''; + const missing = '${{ steps.check.outputs.missing }}' === 'true'; + const files = `${{ steps.check.outputs.files }}`; + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + const existing = comments.find(c => c.body && c.body.includes(marker)); + + if (!missing) { + if (existing) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + }); + } + return; + } + + const body = [ + marker, + '## ⚠️ Logic changes without tests', + '', + 'The following changed files have no corresponding `.test.` file.', + 'Consider adding tests, or note in your PR description why tests are not needed for these changes.', + '', + files, + ].join('\n'); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + } + build: name: Build runs-on: ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 29f53db0b..82eb8b9e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,6 +47,8 @@ Also, we use [ESLint](https://eslint.org/) for clean and stylistically consisten If your change touches logic with testable behaviour, please include tests. See [docs/TESTING.md](./docs/TESTING.md) for a guide on how to write them. +For conventions on code style, naming, and project patterns, see [docs/CODE_QUALITY.md](./docs/CODE_QUALITY.md). + ## Restrictions on Generative AI Usage We expect and appreciate authentic engagement in our community. diff --git a/docs/CODE_QUALITY.md b/docs/CODE_QUALITY.md new file mode 100644 index 000000000..4f4c9cf6e --- /dev/null +++ b/docs/CODE_QUALITY.md @@ -0,0 +1,161 @@ +# Code Quality Guide + +This document describes the coding conventions and standards used throughout Sable. Most rules are enforced automatically in CI or by local linting. Read this to understand the why behind them and to get the conventions right the first time. + +## Enforcement layers + +| Layer | When it runs | What it checks | +| ----------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------- | +| **CI — format / lint / typecheck / knip** | On every PR and push to `dev` | Prettier format, ESLint, TypeScript, Knip dead-code analysis | +| **CI — tests** | On every PR and push to `dev` | Runs the full Vitest suite; fails if any test fails | +| **CI — coverage thresholds** | On every PR and push to `dev` | `pnpm test:coverage`; fails if overall coverage drops below the locked baseline | +| **CI — missing tests warning** | On PRs only | Comments listing changed logic files that have no `.test.` counterpart | +| **Editor** | As you type | ESLint + Prettier via VS Code extensions | + +PRs are not merged unless all CI quality checks are green. + +To fix all violations in the repo at once: + +```sh +pnpm run lint:fix +pnpm run fmt +``` + +## TypeScript + +### Prefer `type` over `interface` + +Use `type` for all type declarations. `interface` is not used in this codebase. + +```ts +type RoomAvatarProps = { + roomId: string; + src?: string; +}; +``` + +Rule: `@typescript-eslint/consistent-type-definitions: ['error', 'type']` + +### Use `import type` for type-only imports + +When an import is used only as a type and not at runtime, annotate it with `type`. + +```ts +import { type MatrixClient, MatrixError } from '$types/matrix-sdk'; +``` + +Rule: `@typescript-eslint/consistent-type-imports` with `inline-type-imports` style. + +### Strict null checks + +The project uses `strict: true`. Do not paper over nullability with unsafe casts. Handle the null or undefined case explicitly or use optional chaining. + +### Enums + +Use string enums for sets of related constants when they improve readability and debug output. + +## Imports + +### Ordering + +Group imports in this order, with a blank line between groups: + +1. External packages. +2. Internal path aliases. +3. Relative imports. + +```ts +import { useState } from 'react'; +import { Box, Text } from 'folds'; + +import { type MatrixClient } from '$types/matrix-sdk'; +import { useMatrixClient } from '$hooks/useMatrixClient'; + +import * as css from './RoomAvatar.css'; +``` + +### Path aliases + +Prefer the `$`-prefixed aliases over deep relative traversal for anything outside the current directory. + +## Naming conventions + +| Thing | Convention | Example | +| ---------------------- | ---------------------------------------- | ------------------------------ | +| React component | `PascalCase` function | `RoomAvatar` | +| Component props type | `[ComponentName]Props` | `RoomAvatarProps` | +| Custom hook | `use` prefix, `camelCase` | `useMatrixClient` | +| Jotai atom | `camelCase` + `Atom` suffix | `settingsAtom` | +| Jotai atom family | `camelCase` + `AtomFamily` suffix | `roomIdToOpenThreadAtomFamily` | +| Utility function | `camelCase` | `getMemberDisplayName` | +| Enum | `PascalCase` type + `PascalCase` members | `AsyncStatus.Loading` | +| CSS module file | `[ComponentName].css.ts` | `RoomAvatar.css.ts` | +| File (component) | `PascalCase.tsx` | `RoomAvatar.tsx` | +| File (hook/util/state) | `camelCase.ts` | `useMatrixClient.ts` | + +## React components + +### Named exports, not default exports + +Use named exports for components, hooks, and utilities. Default exports make refactors worse. + +### Keep components focused + +- One component per file is the default. +- Derive values from props and state instead of duplicating derived state. +- Move non-trivial logic into hooks or state helpers instead of burying it in JSX. + +### localStorage access + +Direct `localStorage` access is banned in `src/app/components/**` and `src/app/features/**`. + +Use one of these patterns instead: + +- Reactive state read by JSX: use `atomWithLocalStorage` in a state file. +- Values needed before React mounts or applied directly to DOM refs: use plain helper functions in `src/app/state/`. + +Examples: + +- [src/app/state/sentryStorage.ts](../src/app/state/sentryStorage.ts) +- [src/app/state/mediaVolume.ts](../src/app/state/mediaVolume.ts) + +## Styling + +Styles live in co-located `*.css.ts` files alongside the component. + +- Avoid inline `style={{}}` for static styling that should be a class. +- Do not import global CSS from component files. + +## Testing + +See [TESTING.md](./TESTING.md) for the full guide. + +- Put tests adjacent to the code they cover, or under `src/test/` for shared fixtures. +- Use `*.test.ts` / `*.test.tsx`. +- Use `@testing-library/react` for component tests. +- If your change touches logic with clear input/output, add or update tests. + +### Coverage thresholds + +Coverage thresholds are locked in `vitest.config.ts` and enforced by CI. They should only go up, never down. + +### Missing-tests advisory + +PRs get an advisory comment when changed logic files have no corresponding test file. That job is informational only. + +## What the linter enforces automatically + +| Rule | Enforced as | +| ----------------------------------------------------------------------- | ------------------------- | +| `@typescript-eslint/consistent-type-definitions` | error | +| `@typescript-eslint/consistent-type-imports` | error | +| `@typescript-eslint/no-unused-vars` | error | +| `@typescript-eslint/no-shadow` | error | +| `react-hooks/rules-of-hooks` | error | +| `react-hooks/exhaustive-deps` | error | +| `react/no-unstable-nested-components` | error | +| No direct `localStorage` in `components/` or `features/` | error | +| Prettier formatting | error | +| Knip dead exports and unused files | error | +| Coverage thresholds (statements/functions/lines >= 1.5%, branches >= 1) | CI error | +| Logic files without a `.test.` counterpart | CI advisory comment on PR | diff --git a/eslint.config.js b/eslint.config.js index 27f5642d9..07303ad44 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -13,6 +13,14 @@ import globals from 'globals'; const gitignorePath = path.resolve('.', '.gitignore'); const { jsFiles, tsFiles } = helpers.extensions; +const recommendedConfig = e18ePlugin.configs?.recommended; +const e18eRecommendedRules = + recommendedConfig && + !Array.isArray(recommendedConfig) && + 'rules' in recommendedConfig && + recommendedConfig.rules + ? recommendedConfig.rules + : {}; const jsConfig = defineConfig([ // ESLint recommended config @@ -70,16 +78,15 @@ const prettierConfig = defineConfig([ const e18eConfig = defineConfig([ { - name: 'e18e/scripts', - files: ['scripts/**/*.js'], + name: 'e18e/recommended', + files: ['src/**/*.{js,jsx,ts,tsx}', 'scripts/**/*.js'], + ignores: ['src/**/*.{test,spec}.{js,jsx,ts,tsx}', 'src/**/*.d.ts'], plugins: { e18e: e18ePlugin, }, rules: { - 'e18e/prefer-array-at': 'error', - 'e18e/prefer-array-some': 'error', - 'e18e/prefer-array-to-sorted': 'error', - 'e18e/prefer-spread-syntax': 'error', + ...e18eRecommendedRules, + 'e18e/prefer-static-regex': 'off', }, }, ]); @@ -163,8 +170,11 @@ const projectOverrides = defineConfig([ }, }, rules: { - // disabled for now to get eslint to pass - '@typescript-eslint/consistent-type-definitions': 'off', + '@typescript-eslint/consistent-type-definitions': ['error', 'type'], + '@typescript-eslint/consistent-type-imports': [ + 'error', + { prefer: 'type-imports', fixStyle: 'inline-type-imports' }, + ], '@typescript-eslint/no-unsafe-enum-comparison': 'off', '@typescript-eslint/only-throw-error': 'off', '@typescript-eslint/array-type': 'off', @@ -183,6 +193,34 @@ const projectOverrides = defineConfig([ 'no-undef': 'off', }, }, + { + name: 'project/no-direct-localstorage-in-ui', + files: ['src/app/components/**/*.{ts,tsx}', 'src/app/features/**/*.{ts,tsx}'], + ignores: ['src/app/components/**/*.test.{ts,tsx}', 'src/app/features/**/*.test.{ts,tsx}'], + rules: { + 'no-restricted-properties': [ + 'error', + { + object: 'localStorage', + message: + 'Direct localStorage access is not allowed in components or features. Use an atom (atomWithLocalStorage) or a storage utility from src/app/state/ instead.', + }, + { + object: 'window', + property: 'localStorage', + message: + 'Direct localStorage access is not allowed in components or features. Use an atom (atomWithLocalStorage) or a storage utility from src/app/state/ instead.', + }, + ], + }, + }, + { + name: 'project/typescript-definition-files', + files: ['**/*.d.ts'], + rules: { + '@typescript-eslint/consistent-type-definitions': 'off', + }, + }, ]); export default defineConfig([ diff --git a/src/app/components/GlobalKeyboardShortcuts.tsx b/src/app/components/GlobalKeyboardShortcuts.tsx index 44daf7fd6..f2de4fd03 100644 --- a/src/app/components/GlobalKeyboardShortcuts.tsx +++ b/src/app/components/GlobalKeyboardShortcuts.tsx @@ -62,7 +62,7 @@ export function GlobalKeyboardShortcuts() { } else { const parents = roomToParents.get(roomId); if (parents && parents.size > 0) { - const spaceId = Array.from(parents)[0]; + const spaceId = [...parents][0]; const spaceIdOrAlias = getCanonicalAliasOrRoomId(mx, spaceId); navigate(getSpaceRoomPath(spaceIdOrAlias, roomIdOrAliasToNav)); } else { @@ -80,7 +80,7 @@ export function GlobalKeyboardShortcuts() { const handleNextUnreadKeyDown = useCallback( (evt: KeyboardEvent) => { if (!isKeyHotkey('alt+n', evt)) return; - const unreadEntries = Array.from(roomToUnread.entries()) + const unreadEntries = [...roomToUnread.entries()] .filter(([id, u]) => u.total > 0 && id !== currentRoom?.roomId) .sort((a, b) => b[1].highlight - a[1].highlight || b[1].total - a[1].total); if (unreadEntries.length === 0) return; @@ -98,7 +98,7 @@ export function GlobalKeyboardShortcuts() { const isDown = isKeyHotkey('alt+shift+down', evt); const isUp = isKeyHotkey('alt+shift+up', evt); if (!isDown && !isUp) return; - const unreadEntries = Array.from(roomToUnread.entries()) + const unreadEntries = [...roomToUnread.entries()] .filter(([, u]) => u.total > 0) .sort((a, b) => b[1].highlight - a[1].highlight || b[1].total - a[1].total); if (unreadEntries.length === 0) return; diff --git a/src/app/components/LogoutDialog.tsx b/src/app/components/LogoutDialog.tsx index c1cf9d1ce..96fcd5990 100644 --- a/src/app/components/LogoutDialog.tsx +++ b/src/app/components/LogoutDialog.tsx @@ -16,7 +16,7 @@ type LogoutDialogProps = { export const LogoutDialog = forwardRef( ({ handleClose }, ref) => { const mx = useMatrixClient(); - const hasEncryptedRoom = !!mx.getRooms().find((room) => room.hasEncryptionStateEvent()); + const hasEncryptedRoom = mx.getRooms().some((room) => room.hasEncryptionStateEvent()); const crossSigningActive = useCrossSigningActive(); const verificationStatus = useDeviceVerificationStatus( mx.getCrypto(), diff --git a/src/app/components/RenderMessageContent.tsx b/src/app/components/RenderMessageContent.tsx index 5cbbed6fc..71fa0897e 100644 --- a/src/app/components/RenderMessageContent.tsx +++ b/src/app/components/RenderMessageContent.tsx @@ -53,8 +53,8 @@ type RenderMessageContentProps = { const getMediaType = (url: string) => { const cleanUrl = url.toLowerCase(); - if (cleanUrl.match(/\.(mp4|webm|ogg)$/i)) return 'video'; - if (cleanUrl.match(/\.(png|jpg|jpeg|gif|webp)$/i) || cleanUrl.match(/@(jpeg|webp|png|jpg)$/i)) + if (/\.(mp4|webm|ogg)$/i.test(cleanUrl)) return 'video'; + if (/\.(png|jpg|jpeg|gif|webp)$/i.test(cleanUrl) || /@(jpeg|webp|png|jpg)$/i.test(cleanUrl)) return 'image'; return null; }; diff --git a/src/app/components/SwipeableChatWrapper.tsx b/src/app/components/SwipeableChatWrapper.tsx index 050fa440c..0811c54be 100644 --- a/src/app/components/SwipeableChatWrapper.tsx +++ b/src/app/components/SwipeableChatWrapper.tsx @@ -5,12 +5,12 @@ import { useAtomValue } from 'jotai'; import { settingsAtom, RightSwipeAction } from '$state/settings'; import { mobileOrTablet } from '$utils/user-agent'; -interface SwipeableChatWrapperProps { +type SwipeableChatWrapperProps = { children: ReactNode; onOpenSidebar?: () => void; onOpenMembers?: () => void; onReply?: () => void; -} +}; export function SwipeableChatWrapper({ children, diff --git a/src/app/components/SwipeableOverlayWrapper.tsx b/src/app/components/SwipeableOverlayWrapper.tsx index 0c06de91c..6cc488204 100644 --- a/src/app/components/SwipeableOverlayWrapper.tsx +++ b/src/app/components/SwipeableOverlayWrapper.tsx @@ -5,11 +5,11 @@ import { useAtomValue } from 'jotai'; import { settingsAtom } from '$state/settings'; import { mobileOrTablet } from '$utils/user-agent'; -interface SwipeableOverlayWrapperProps { +type SwipeableOverlayWrapperProps = { children: ReactNode; onClose: () => void; direction: 'left' | 'right'; -} +}; export function SwipeableOverlayWrapper({ children, diff --git a/src/app/components/create-room/AdditionalCreatorInput.tsx b/src/app/components/create-room/AdditionalCreatorInput.tsx index 4ef005125..3ee2b331c 100644 --- a/src/app/components/create-room/AdditionalCreatorInput.tsx +++ b/src/app/components/create-room/AdditionalCreatorInput.tsx @@ -44,7 +44,7 @@ export const useAdditionalCreators = (defaultCreators?: string[]) => { setAdditionalCreators((creators) => { const creatorsSet = new Set(creators); creatorsSet.add(userId); - return Array.from(creatorsSet); + return [...creatorsSet]; }); }; @@ -52,7 +52,7 @@ export const useAdditionalCreators = (defaultCreators?: string[]) => { setAdditionalCreators((creators) => { const creatorsSet = new Set(creators); creatorsSet.delete(userId); - return Array.from(creatorsSet); + return [...creatorsSet]; }); }; diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index 2b6c902b6..32d332c4e 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -25,7 +25,7 @@ import { withHistory } from 'slate-history'; import { mobileOrTablet } from '$utils/user-agent'; import { BlockType } from './types'; import { RenderElement, RenderLeaf } from './Elements'; -import { type CustomElement } from './slate'; +import type { CustomElement } from './slate'; import * as css from './Editor.css'; import { toggleKeyboardShortcut } from './keyboard'; diff --git a/src/app/components/editor/Elements.tsx b/src/app/components/editor/Elements.tsx index bdf361788..8663f019b 100644 --- a/src/app/components/editor/Elements.tsx +++ b/src/app/components/editor/Elements.tsx @@ -15,12 +15,7 @@ import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { nicknamesAtom } from '$state/nicknames'; import { BlockType } from './types'; import { getBeginCommand } from './utils'; -import { - type CommandElement, - type EmoticonElement, - type LinkElement, - type MentionElement, -} from './slate'; +import type { CommandElement, EmoticonElement, LinkElement, MentionElement } from './slate'; // Put this at the start and end of an inline component to work around this Chromium bug: // https://bugs.chromium.org/p/chromium/issues/detail?id=1249405 diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx index 10c7c21d9..90441431f 100644 --- a/src/app/components/editor/Toolbar.tsx +++ b/src/app/components/editor/Toolbar.tsx @@ -25,7 +25,7 @@ import { useSetting } from '$state/hooks/settings'; import { settingsAtom } from '$state/settings'; import { stopPropagation } from '$utils/keyboard'; import { floatingToolbar } from '$styles/overrides/Composer.css'; -import { type HeadingLevel } from './slate'; +import type { HeadingLevel } from './slate'; import { BlockType, MarkType } from './types'; import * as css from './Editor.css'; import { diff --git a/src/app/components/editor/input.ts b/src/app/components/editor/input.ts index 8a919ab84..7d3d00167 100644 --- a/src/app/components/editor/input.ts +++ b/src/app/components/editor/input.ts @@ -11,20 +11,20 @@ import { } from '$plugins/matrix-to'; import { escapeMarkdownInlineSequences, escapeMarkdownBlockSequences } from '$plugins/markdown'; import { BlockType, MarkType } from './types'; -import { - type BlockQuoteElement, - type CodeBlockElement, - type CodeLineElement, - type EmoticonElement, - type HeadingElement, - type HeadingLevel, - type HorizontalRuleElement, - type InlineElement, - type MentionElement, - type OrderedListElement, - type ParagraphElement, - type SmallElement, - type UnorderedListElement, +import type { + BlockQuoteElement, + CodeBlockElement, + CodeLineElement, + EmoticonElement, + HeadingElement, + HeadingLevel, + HorizontalRuleElement, + InlineElement, + MentionElement, + OrderedListElement, + ParagraphElement, + SmallElement, + UnorderedListElement, } from './slate'; import { createEmoticonElement, createMentionElement } from './utils'; @@ -450,7 +450,7 @@ export const domToEditorInput = ( return; } - if (node.name.match(/^h[123456]$/)) { + if (/^h[123456]$/.test(node.name)) { appendLine(); children.push(parseHeadingNode(node, processText)); return; diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 2e21b4b61..1d48c40a0 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -10,7 +10,7 @@ import { import { findAndReplace } from '$utils/findAndReplace'; import { sanitizeForRegex } from '$utils/regex'; import { isUserId } from '$utils/matrix'; -import { type CustomElement } from './slate'; +import type { CustomElement } from './slate'; import { BlockType } from './types'; export type OutputOptions = { diff --git a/src/app/components/editor/utils.ts b/src/app/components/editor/utils.ts index de3928e89..29df43ade 100644 --- a/src/app/components/editor/utils.ts +++ b/src/app/components/editor/utils.ts @@ -9,13 +9,13 @@ import { Transforms, } from 'slate'; import { BlockType, MarkType } from './types'; -import { - type CommandElement, - type EmoticonElement, - type FormattedText, - type HeadingLevel, - type LinkElement, - type MentionElement, +import type { + CommandElement, + EmoticonElement, + FormattedText, + HeadingLevel, + LinkElement, + MentionElement, } from './slate'; const ALL_MARK_TYPE: MarkType[] = [ @@ -34,7 +34,7 @@ export const isMarkActive = (editor: Editor, format: MarkType) => { export const isAnyMarkActive = (editor: Editor) => { const marks = Editor.marks(editor); - return marks && !!ALL_MARK_TYPE.find((type) => marks[type] === true); + return marks && ALL_MARK_TYPE.some((type) => marks[type] === true); }; export const toggleMark = (editor: Editor, format: MarkType) => { @@ -229,10 +229,10 @@ export const moveCursor = (editor: Editor, withSpace?: boolean) => { Transforms.collapse(editor, { edge: 'end' }); }; -interface PointUntilCharOptions { +type PointUntilCharOptions = { match: (char: string) => boolean; reverse?: boolean; -} +}; export const getPointUntilChar = ( editor: Editor, cursorPoint: BasePoint, diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index ce43c387c..214ebbc49 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -417,8 +417,8 @@ export function EmojiBoard({ const searchList = useMemo(() => { let list: Array = []; - list = list.concat(imagePacks.flatMap((pack) => pack.getImages(usage))); - if (emojiTab) list = list.concat(emojis); + list = [...list, ...imagePacks.flatMap((pack) => pack.getImages(usage))]; + if (emojiTab) list = [...list, ...emojis]; return list; }, [emojiTab, usage, imagePacks]); diff --git a/src/app/components/image-pack-view/ImagePackContent.tsx b/src/app/components/image-pack-view/ImagePackContent.tsx index e89108254..41132718d 100644 --- a/src/app/components/image-pack-view/ImagePackContent.tsx +++ b/src/app/components/image-pack-view/ImagePackContent.tsx @@ -39,7 +39,7 @@ export const ImagePackContent = as<'div', ImagePackContentProps>( const [savedMeta, setSavedMeta] = useState(); const currentMeta = savedMeta ?? imagePack.meta; - const images = useMemo(() => Array.from(imagePack.images.collection.values()), [imagePack]); + const images = useMemo(() => [...imagePack.images.collection.values()], [imagePack]); const [files, setFiles] = useState([]); const [uploadedImages, setUploadedImages] = useState([]); const [imagesEditing, setImagesEditing] = useState>(new Set()); @@ -50,11 +50,9 @@ export const ImagePackContent = as<'div', ImagePackContentProps>( (shortcode: string): boolean => { const hasInPack = imagePack.images.collection.has(shortcode); if (hasInPack) return true; - const hasInUploaded = - uploadedImages.find((img) => img.shortcode === shortcode) !== undefined; + const hasInUploaded = uploadedImages.some((img) => img.shortcode === shortcode); if (hasInUploaded) return true; - const hasInSaved = - Array.from(savedImages).find(([, img]) => img.shortcode === shortcode) !== undefined; + const hasInSaved = [...savedImages].some(([, img]) => img.shortcode === shortcode); return hasInSaved; }, [imagePack, savedImages, uploadedImages] diff --git a/src/app/components/media/Video.tsx b/src/app/components/media/Video.tsx index 073b6b0d6..2d65fb2f3 100644 --- a/src/app/components/media/Video.tsx +++ b/src/app/components/media/Video.tsx @@ -1,5 +1,6 @@ import { type VideoHTMLAttributes, forwardRef, useEffect, useRef } from 'react'; import classNames from 'classnames'; +import { getMediaVolume, setMediaVolume } from '$state/mediaVolume'; import * as css from './media.css'; export const Video = forwardRef>( @@ -9,8 +10,6 @@ export const Video = forwardRef(null); useEffect(() => { - const stored = localStorage.getItem(MEDIA_VOLUME_KEY); - if (innerRef.current && stored !== null) { - const parsed = parseFloat(stored); - if (!Number.isNaN(parsed)) innerRef.current.volume = parsed; - } + const volume = getMediaVolume(); + if (innerRef.current && volume !== undefined) innerRef.current.volume = volume; }, []); return ( @@ -30,7 +26,7 @@ export function PersistedVolumeVideo({ {...props} ref={innerRef} onVolumeChange={(e) => { - localStorage.setItem(MEDIA_VOLUME_KEY, String((e.target as HTMLVideoElement).volume)); + setMediaVolume((e.target as HTMLVideoElement).volume); onVolumeChange?.(e); }} /> diff --git a/src/app/components/message/content/AudioContent.tsx b/src/app/components/message/content/AudioContent.tsx index 34fc1d3f3..871918fd9 100644 --- a/src/app/components/message/content/AudioContent.tsx +++ b/src/app/components/message/content/AudioContent.tsx @@ -18,7 +18,7 @@ import { useThrottle } from '$hooks/useThrottle'; import { secondsToMinutesAndSeconds } from '$utils/common'; import { decryptFile, downloadEncryptedMedia, downloadMedia, mxcUrlToHttp } from '$utils/matrix'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; -import { MEDIA_VOLUME_KEY } from '$components/media'; +import { getMediaVolume, setMediaVolume } from '$state/mediaVolume'; const PLAY_TIME_THROTTLE_OPS = { wait: 500, @@ -62,11 +62,8 @@ export function AudioContent({ const audioRef = useRef(null); useEffect(() => { - const stored = localStorage.getItem(MEDIA_VOLUME_KEY); - if (audioRef.current && stored !== null) { - const parsed = parseFloat(stored); - if (!Number.isNaN(parsed)) audioRef.current.volume = parsed; - } + const volume = getMediaVolume(); + if (audioRef.current && volume !== undefined) audioRef.current.volume = volume; }, []); const [currentTime, setCurrentTime] = useState(0); @@ -225,7 +222,7 @@ export function AudioContent({ autoPlay ref={audioRef} onVolumeChange={(e) => { - localStorage.setItem(MEDIA_VOLUME_KEY, String((e.target as HTMLAudioElement).volume)); + setMediaVolume((e.target as HTMLAudioElement).volume); }} > {srcState.status === AsyncStatus.Success && } diff --git a/src/app/components/notification-banner/NotificationBanner.tsx b/src/app/components/notification-banner/NotificationBanner.tsx index 38b163863..553080642 100644 --- a/src/app/components/notification-banner/NotificationBanner.tsx +++ b/src/app/components/notification-banner/NotificationBanner.tsx @@ -65,7 +65,7 @@ function BannerItem({ notification, onDismiss }: BannerItemProps) { if (dismissedRef.current) return; dismissedRef.current = true; setDismissing(true); - dismissAnimTimerRef.current = setTimeout(() => onDismiss(notification.id), 200); + dismissAnimTimerRef.current = setTimeout(onDismiss, 200, notification.id); }, [notification.id, onDismiss]); // Auto-dismiss timer — only runs when not paused. diff --git a/src/app/components/telemetry-consent/TelemetryConsentBanner.tsx b/src/app/components/telemetry-consent/TelemetryConsentBanner.tsx index 5c1e90a08..6335cf7af 100644 --- a/src/app/components/telemetry-consent/TelemetryConsentBanner.tsx +++ b/src/app/components/telemetry-consent/TelemetryConsentBanner.tsx @@ -1,14 +1,11 @@ import { useEffect, useRef, useState } from 'react'; import { Box, Button, Icon, Icons, Text } from 'folds'; +import { isSentryDecided, setSentryEnabled } from '$state/sentryStorage'; import * as css from './TelemetryConsentBanner.css'; -const SENTRY_KEY = 'sable_sentry_enabled'; - export function TelemetryConsentBanner() { const isSentryConfigured = Boolean(import.meta.env.VITE_SENTRY_DSN); - const [visible, setVisible] = useState( - isSentryConfigured && localStorage.getItem(SENTRY_KEY) === null - ); + const [visible, setVisible] = useState(isSentryConfigured && !isSentryDecided()); const [dismissing, setDismissing] = useState(false); const dismissTimerRef = useRef | null>(null); @@ -22,14 +19,14 @@ export function TelemetryConsentBanner() { if (!visible) return null; const handleEnable = () => { - localStorage.setItem(SENTRY_KEY, 'true'); + setSentryEnabled(true); window.location.reload(); }; const handleDecline = () => { - localStorage.setItem(SENTRY_KEY, 'false'); + setSentryEnabled(false); setDismissing(true); - dismissTimerRef.current = setTimeout(() => setVisible(false), 220); + dismissTimerRef.current = setTimeout(setVisible, 220, false); }; return ( diff --git a/src/app/components/time-date/DatePicker.tsx b/src/app/components/time-date/DatePicker.tsx index 078d91d8e..1d92ccff7 100644 --- a/src/app/components/time-date/DatePicker.tsx +++ b/src/app/components/time-date/DatePicker.tsx @@ -60,67 +60,64 @@ export const DatePicker = forwardRef( - {Array.from(new Array(daysInMonth(selectedMonth, selectedYear)).keys()) - .map((i) => i + 1) - .map((day) => ( - handleDay(day)} - disabled={ - (selectedYear === minYear && selectedMonth === minMonth && day < minDay) || - (selectedYear === maxYear && selectedMonth === maxMonth && day > maxDay) - } - > - {day} - - ))} + {Array.from( + new Array(daysInMonth(selectedMonth, selectedYear)).keys(), + (i) => i + 1 + ).map((day) => ( + handleDay(day)} + disabled={ + (selectedYear === minYear && selectedMonth === minMonth && day < minDay) || + (selectedYear === maxYear && selectedMonth === maxMonth && day > maxDay) + } + > + {day} + + ))} - {Array.from(new Array(12).keys()) - .map((i) => i + 1) - .map((month) => ( - handleMonth(month)} - disabled={ - (selectedYear === minYear && month < minMonth) || - (selectedYear === maxYear && month > maxMonth) - } - > - - {dayjs() - .month(month - 1) - .format('MMM')} - - - ))} + {Array.from(new Array(12).keys(), (i) => i + 1).map((month) => ( + handleMonth(month)} + disabled={ + (selectedYear === minYear && month < minMonth) || + (selectedYear === maxYear && month > maxMonth) + } + > + + {dayjs() + .month(month - 1) + .format('MMM')} + + + ))} - {Array.from(new Array(yearsRange).keys()) - .map((i) => minYear + i) - .map((year) => ( - handleYear(year)} - > - {year} - - ))} + {Array.from(new Array(yearsRange).keys(), (i) => minYear + i).map((year) => ( + handleYear(year)} + > + {year} + + ))} diff --git a/src/app/components/time-date/TimePicker.tsx b/src/app/components/time-date/TimePicker.tsx index c16ad7caa..039d3d5a7 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(new Array(24).keys(), (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(new Array(12).keys(), (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(new Array(60).keys(), (minute) => ( { const data = await fetch(url).then((resp) => resp.json()); @@ -158,18 +158,21 @@ type YoutubeLink = { function parseYoutubeLink(url: string): YoutubeLink | null { const urlsplit = url.split('/'); - const path = urlsplit[urlsplit.length - 1]; + const path = urlsplit.at(-1); + + if (!path) return null; let videoId: string | undefined; let params: string[]; if (url.includes('youtu.be')) { - const split = path.split('?'); - [videoId] = split; - params = split[1].split('&'); + const [shortVideoId, query = ''] = path.split('?'); + videoId = shortVideoId; + params = query ? query.split('&') : []; } else { - params = path.split('?')[1].split('&'); - videoId = params.find((s) => s.startsWith('v='), params)?.split('v=')[1]; + const [, query = ''] = path.split('?'); + params = query ? query.split('&') : []; + videoId = params.find((s) => s.startsWith('v='))?.split('v=')[1]; } if (!videoId) return null; diff --git a/src/app/features/add-existing/AddExisting.tsx b/src/app/features/add-existing/AddExisting.tsx index fdee02b0c..77fc73cc3 100644 --- a/src/app/features/add-existing/AddExisting.tsx +++ b/src/app/features/add-existing/AddExisting.tsx @@ -108,7 +108,7 @@ export function AddExistingModal({ parentId, space, requestClose }: AddExistingM return true; } - return Array.from(parentIds).some((id) => isAncestor(sourceId, id, visited)); + return [...parentIds].some((id) => isAncestor(sourceId, id, visited)); }, [roomIdToParents] ); diff --git a/src/app/features/call-status/MemberSpeaking.tsx b/src/app/features/call-status/MemberSpeaking.tsx index 3c7206e5b..b5fc30a2c 100644 --- a/src/app/features/call-status/MemberSpeaking.tsx +++ b/src/app/features/call-status/MemberSpeaking.tsx @@ -8,7 +8,8 @@ type MemberSpeakingProps = { speakers: Set; }; export function MemberSpeaking({ room, speakers }: MemberSpeakingProps) { - const speakingNames = Array.from(speakers).map( + const speakingNames = Array.from( + speakers, (userId) => getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId ); return ( diff --git a/src/app/features/call/CallMemberCard.tsx b/src/app/features/call/CallMemberCard.tsx index 0c4ca7601..698cc998a 100644 --- a/src/app/features/call/CallMemberCard.tsx +++ b/src/app/features/call/CallMemberCard.tsx @@ -15,11 +15,11 @@ import { UserAvatar } from '../../components/user-avatar'; import { getMouseEventCords } from '../../utils/dom'; import * as css from './styles.css'; -interface MemberWithMembershipData { +type MemberWithMembershipData = { membershipData?: SessionMembershipData & { 'm.call.intent': 'video' | 'audio'; }; -} +}; type CallMemberCardProps = { member: CallMembership; diff --git a/src/app/features/call/CallView.tsx b/src/app/features/call/CallView.tsx index e79a7f6ac..9e802b961 100644 --- a/src/app/features/call/CallView.tsx +++ b/src/app/features/call/CallView.tsx @@ -147,9 +147,9 @@ function CallJoined({ joined, containerRef }: CallJoinedProps) { ); } -interface CallViewProps { +type CallViewProps = { resizable?: boolean; -} +}; export function CallView({ resizable }: CallViewProps) { const room = useRoom(); diff --git a/src/app/features/common-settings/developer-tools/DevelopTools.tsx b/src/app/features/common-settings/developer-tools/DevelopTools.tsx index 705ab1983..8f3d82cbe 100644 --- a/src/app/features/common-settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/common-settings/developer-tools/DevelopTools.tsx @@ -78,15 +78,15 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) { const userId = mx.getUserId(); const clientSyncState = mx.getSyncState(); const liveEvents = room.getLiveTimeline().getEvents(); - const latestTimelineEvent = liveEvents[liveEvents.length - 1]; + const latestTimelineEvent = liveEvents.at(-1); const latestTimelineEventId = latestTimelineEvent?.getId() ?? null; - const latestMessageEvent = [...liveEvents].reverse().find((event) => { + const latestMessageEvent = liveEvents.toReversed().find((event) => { const type = event.getType(); return type === 'm.room.message' || type === 'm.room.encrypted' || type === 'm.sticker'; }); const latestMessageEventId = latestMessageEvent?.getId() ?? null; - const latestNotificationEvent = [...liveEvents] - .reverse() + const latestNotificationEvent = liveEvents + .toReversed() .find((event) => isNotificationEvent(event)); const latestNotificationEventId = latestNotificationEvent?.getId() ?? null; const fullyReadEventId = @@ -475,89 +475,85 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) { - {Array.from(roomState.keys()) - .sort() - .map((eventType) => { - const expanded = eventType === expandStateType; - const stateKeyToEvents = roomState.get(eventType); - if (!stateKeyToEvents) return null; + {[...roomState.keys()].sort().map((eventType) => { + const expanded = eventType === expandStateType; + const stateKeyToEvents = roomState.get(eventType); + if (!stateKeyToEvents) return null; - return ( - - - setExpandStateType(expanded ? undefined : eventType) - } - variant="Surface" - fill="None" - size="300" - radii="0" - before={ - - } - after={{stateKeyToEvents.size}} + return ( + + + setExpandStateType(expanded ? undefined : eventType) + } + variant="Surface" + fill="None" + size="300" + radii="0" + before={ + + } + after={{stateKeyToEvents.size}} + > + + + {eventType} + + + + {expanded && ( +
- - - {eventType} - - - - {expanded && ( -
+ setComposeEvent({ type: eventType, stateKey: '' }) + } + variant="Surface" + fill="None" + size="300" + radii="0" + before={} > + + + Add New + + + + {[...stateKeyToEvents.keys()].sort().map((stateKey) => ( - setComposeEvent({ type: eventType, stateKey: '' }) - } + onClick={() => { + setOpenStateEvent({ + type: eventType, + stateKey, + }); + }} + key={stateKey} variant="Surface" fill="None" size="300" radii="0" - before={} + after={} > - Add New + {stateKey ? `"${stateKey}"` : 'Default'} - {Array.from(stateKeyToEvents.keys()) - .sort() - .map((stateKey) => ( - { - setOpenStateEvent({ - type: eventType, - stateKey, - }); - }} - key={stateKey} - variant="Surface" - fill="None" - size="300" - radii="0" - after={} - > - - - {stateKey ? `"${stateKey}"` : 'Default'} - - - - ))} -
- )} - - ); - })} + ))} +
+ )} +
+ ); + })}
)} @@ -612,25 +608,23 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) { - {Array.from(accountData.keys()) - .sort() - .map((type) => ( - } - onClick={() => setAccountDataType(type)} - > - - - {type} - - - - ))} + {[...accountData.keys()].sort().map((type) => ( + } + onClick={() => setAccountDataType(type)} + > + + + {type} + + + + ))} )} diff --git a/src/app/features/common-settings/general/RoomUpgrade.tsx b/src/app/features/common-settings/general/RoomUpgrade.tsx index ac738ff77..56f0e795f 100644 --- a/src/app/features/common-settings/general/RoomUpgrade.tsx +++ b/src/app/features/common-settings/general/RoomUpgrade.tsx @@ -55,7 +55,7 @@ function RoomUpgradeDialog({ requestClose }: { requestClose: () => void }) { const allowAdditionalCreators = creatorsSupported(selectedRoomVersion); const { additionalCreators, addAdditionalCreator, removeAdditionalCreator } = - useAdditionalCreators(Array.from(creators)); + useAdditionalCreators([...creators]); const [upgradeState, upgrade] = useAsyncCallback( useCallback( diff --git a/src/app/features/common-settings/members/Members.tsx b/src/app/features/common-settings/members/Members.tsx index 6a7abc10f..57e3ca02f 100644 --- a/src/app/features/common-settings/members/Members.tsx +++ b/src/app/features/common-settings/members/Members.tsx @@ -98,10 +98,7 @@ export function Members({ requestClose }: MembersProps) { const sortedMembers = useMemo( () => - Array.from(members) - .filter(membershipFilter.filterFn) - .sort(memberSort.sortFn) - .sort(memberPowerSort), + [...members].filter(membershipFilter.filterFn).sort(memberSort.sortFn).sort(memberPowerSort), [members, membershipFilter, memberSort, memberPowerSort] ); diff --git a/src/app/features/common-settings/permissions/PowersEditor.tsx b/src/app/features/common-settings/permissions/PowersEditor.tsx index 06cfd8337..05d18ecec 100644 --- a/src/app/features/common-settings/permissions/PowersEditor.tsx +++ b/src/app/features/common-settings/permissions/PowersEditor.tsx @@ -320,7 +320,7 @@ export function PowersEditor({ powerLevels, requestClose }: Readonly { const up = getUsedPowers(powerLevels); - return [up, Math.max(...Array.from(up))]; + return [up, Math.max(...[...up])]; }, [powerLevels]); const powerLevelTags = usePowerLevelTags(room, powerLevels); diff --git a/src/app/features/lobby/Lobby.tsx b/src/app/features/lobby/Lobby.tsx index 7c9213bad..c3032583d 100644 --- a/src/app/features/lobby/Lobby.tsx +++ b/src/app/features/lobby/Lobby.tsx @@ -271,7 +271,7 @@ export function Lobby() { // As a subspace can be in multiple spaces, // only return true if all parent spaces are closed. - const allClosed = !Array.from(parentParentIds).some( + const allClosed = ![...parentParentIds].some( (id) => !getInClosedCategories(spaceId, id, parentId, visited) ); visited.delete(categoryId); @@ -295,7 +295,7 @@ export function Lobby() { return false; } - return !Array.from(parentIds).some((id) => !getInClosedCategories(spaceId, id, roomId)); + return ![...parentIds].some((id) => !getInClosedCategories(spaceId, id, roomId)); }; const [subspaceHierarchyLimit] = useSetting(settingsAtom, 'subspaceHierarchyLimit'); @@ -439,9 +439,9 @@ export function Lobby() { } } - const itemSpaces = Array.from( - hierarchy?.find((i) => i.space.roomId === containerParentId)?.rooms ?? [] - ); + const itemSpaces = [ + ...(hierarchy?.find((i) => i.space.roomId === containerParentId)?.rooms ?? []), + ]; const beforeItem: HierarchyItem | undefined = 'space' in containerItem ? undefined : containerItem; diff --git a/src/app/features/lobby/SpaceHierarchyItem.tsx b/src/app/features/lobby/SpaceHierarchyItem.tsx index 917f25de8..9158583ed 100644 --- a/src/app/features/lobby/SpaceHierarchyItem.tsx +++ b/src/app/features/lobby/SpaceHierarchyItem.tsx @@ -95,7 +95,7 @@ export const SpaceHierarchyItem = forwardRef { - onSpacesFound(Array.from(subspaces.values())); + onSpacesFound([...subspaces.values()]); }, [subspaces, onSpacesFound]); let childItems: HierarchyItemRoom[] | undefined = roomItems?.filter( diff --git a/src/app/features/message-search/MessageSearch.tsx b/src/app/features/message-search/MessageSearch.tsx index 443d6a20c..ec03c3dab 100644 --- a/src/app/features/message-search/MessageSearch.tsx +++ b/src/app/features/message-search/MessageSearch.tsx @@ -113,7 +113,7 @@ export function MessageSearch({ const groups = useMemo(() => data?.pages.flatMap((result) => result.groups) ?? [], [data]); const highlights = useMemo(() => { const mixed = data?.pages.flatMap((result) => result.highlights); - return Array.from(new Set(mixed)); + return [...new Set(mixed)]; }, [data]); const virtualizer = useVirtualizer({ @@ -253,7 +253,7 @@ export function MessageSearch({ {((msgSearchParams.term && status === 'pending') || (groups.length > 0 && vItems.length === 0)) && ( - {[...new Array(8).keys()].map((key) => ( + {Array.from(new Array(8).keys(), (key) => ( ))} diff --git a/src/app/features/message-search/SearchFilters.tsx b/src/app/features/message-search/SearchFilters.tsx index 57a8e31af..f955bb921 100644 --- a/src/app/features/message-search/SearchFilters.tsx +++ b/src/app/features/message-search/SearchFilters.tsx @@ -142,7 +142,7 @@ function SelectRoomButton({ roomList, selectedRooms, onChange }: SelectRoomButto getRoomNameStr, SEARCH_OPTS ); - const rooms = Array.from(searchResult?.items ?? roomList).sort(factoryRoomIdByAtoZ(mx)); + const rooms = (searchResult?.items ?? roomList).toSorted(factoryRoomIdByAtoZ(mx)); const virtualizer = useVirtualizer({ count: rooms.length, diff --git a/src/app/features/message-search/useMessageSearch.ts b/src/app/features/message-search/useMessageSearch.ts index a0349531e..b860eeea3 100644 --- a/src/app/features/message-search/useMessageSearch.ts +++ b/src/app/features/message-search/useMessageSearch.ts @@ -37,7 +37,7 @@ const groupSearchResult = (results: ISearchResult[]): ResultGroup[] => { context: item.context, }; - const lastAddedGroup: ResultGroup | undefined = groups[groups.length - 1]; + const lastAddedGroup: ResultGroup | undefined = groups.at(-1); if (lastAddedGroup && roomId === lastAddedGroup.roomId) { lastAddedGroup.items.push(resultItem); return; diff --git a/src/app/features/room-settings/abbreviations/RoomAbbreviations.tsx b/src/app/features/room-settings/abbreviations/RoomAbbreviations.tsx index 333c06b36..094a870fc 100644 --- a/src/app/features/room-settings/abbreviations/RoomAbbreviations.tsx +++ b/src/app/features/room-settings/abbreviations/RoomAbbreviations.tsx @@ -70,7 +70,7 @@ export function RoomAbbreviations({ requestClose, isSpace }: AbbreviationsProps) type SpaceEntryGroup = { spaceId: string; spaceName: string; entries: AbbreviationEntry[] }; const ancestorGroups = useMemo( (): SpaceEntryGroup[] => - Array.from(getAllParents(roomToParents, room.roomId)).reduce( + [...getAllParents(roomToParents, room.roomId)].reduce( (groups, parentId) => { const parentRoom = mx.getRoom(parentId); if (!parentRoom) return groups; diff --git a/src/app/features/room/RoomCallButton.tsx b/src/app/features/room/RoomCallButton.tsx index 11becd090..c12c9a0a5 100644 --- a/src/app/features/room/RoomCallButton.tsx +++ b/src/app/features/room/RoomCallButton.tsx @@ -6,9 +6,9 @@ import { callEmbedAtom } from '$state/callEmbed'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useCallPreferences } from '$state/hooks/callPreferences'; -interface RoomCallButtonProps { +type RoomCallButtonProps = { room: Room; -} +}; export function RoomCallButton({ room }: RoomCallButtonProps) { const startCall = useCallStart(); diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx index 981b9c270..8c802f692 100644 --- a/src/app/features/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -173,7 +173,8 @@ const getLatestThreadEventId = (room: Room, threadRootId: string): string => { (ev) => ev.getId() !== threadRootId && !reactionOrEditEvent(ev) ); if (filtered.length > 0) { - return filtered[filtered.length - 1].getId() ?? threadRootId; + const latestThreadEvent = filtered.at(-1); + return latestThreadEvent?.getId() ?? threadRootId; } // Fall back to the live timeline if the Thread object hasn't been registered yet const liveEvents = room @@ -185,7 +186,8 @@ const getLatestThreadEventId = (room: Room, threadRootId: string): string => { ev.threadRootId === threadRootId && ev.getId() !== threadRootId && !reactionOrEditEvent(ev) ); if (liveEvents.length > 0) { - return liveEvents[liveEvents.length - 1].getId() ?? threadRootId; + const latestLiveEvent = liveEvents.at(-1); + return latestLiveEvent?.getId() ?? threadRootId; } return threadRootId; }; @@ -230,18 +232,18 @@ const getReplyContent = (replyDraft: IReplyDraft | undefined, room?: Room): IEve const log = createLogger('RoomInput'); const debugLog = createDebugLogger('RoomInput'); -interface ReplyEventContent { +type ReplyEventContent = { 'm.relates_to'?: IEventRelation; -} +}; -interface RoomInputProps { +type RoomInputProps = { editor: Editor; fileDropContainerRef: RefObject; roomId: string; room: Room; threadRootId?: string; onEditLastMessage?: () => void; -} +}; export const RoomInput = forwardRef( ({ editor, fileDropContainerRef, roomId, room, threadRootId, onEditLastMessage }, ref) => { // When in thread mode, isolate drafts by thread root ID so thread replies @@ -756,7 +758,7 @@ export const RoomInput = forwardRef( mentionData.users.add(replyDraft.userId); } - content['m.mentions'] = getMentionContent(Array.from(mentionData.users), mentionData.room); + content['m.mentions'] = getMentionContent([...mentionData.users], mentionData.room); if (replyDraft || !customHtmlEqualsPlainText(formattedBody, body)) { content.format = 'org.matrix.custom.html'; @@ -1112,20 +1114,18 @@ export const RoomInput = forwardRef( {uploadBoard && ( - {Array.from(selectedFiles) - .reverse() - .map((fileItem, index) => ( - - ))} + {selectedFiles.toReversed().map((fileItem, index) => ( + + ))} )} diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index 6fc9fc08b..cd9cbd996 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -679,8 +679,8 @@ export function RoomTimeline({ const ref = onEditLastMessageRef; ref.current = () => { const myUserId = mx.getUserId(); - const found = [...processedEventsRef.current] - .reverse() + const found = processedEventsRef.current + .toReversed() .find( (e) => e.mEvent.getSender() === myUserId && diff --git a/src/app/features/room/RoomViewHeader.tsx b/src/app/features/room/RoomViewHeader.tsx index fd08cde69..3818c9946 100644 --- a/src/app/features/room/RoomViewHeader.tsx +++ b/src/app/features/room/RoomViewHeader.tsx @@ -96,20 +96,20 @@ import { RoomCallButton } from './RoomCallButton'; const log = createLogger('RoomViewHeader'); async function getPinsHash(pinnedIds: string[]): Promise { - const sorted = [...pinnedIds].sort().join(','); + const sorted = pinnedIds.toSorted().join(','); const encoder = new TextEncoder(); const data = encoder.encode(sorted); const hashBuffer = await crypto.subtle.digest('SHA-256', data); - const hashArray = Array.from(new Uint8Array(hashBuffer)); + const hashArray = [...new Uint8Array(hashBuffer)]; const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); return hashHex.slice(0, 10); } -export interface PinReadMarker { +export type PinReadMarker = { hash: string; count: number; last_seen_id: string; -} +}; type RoomMenuProps = { room: Room; diff --git a/src/app/features/room/ThreadDrawer.tsx b/src/app/features/room/ThreadDrawer.tsx index 3676240c9..852e673ed 100644 --- a/src/app/features/room/ThreadDrawer.tsx +++ b/src/app/features/room/ThreadDrawer.tsx @@ -541,7 +541,7 @@ export function ThreadDrawer({ room, threadRootId, onClose, overlay }: ThreadDra const events = thread.events || []; if (events.length === 0) return; - const lastEvent = events[events.length - 1]; + const lastEvent = events.at(-1); if (!lastEvent || lastEvent.isSending()) return; const userId = mx.getUserId(); @@ -703,7 +703,7 @@ export function ThreadDrawer({ room, threadRootId, onClose, overlay }: ThreadDra const isInReplies = replyEventsRef.current.some((e) => e.getId() === targetId); if (!isRoot && !isInReplies) return; setJumpToEventId(targetId); - setTimeout(() => setJumpToEventId(undefined), 2500); + setTimeout(setJumpToEventId, 2500, undefined); const el = drawerRef.current; if (el) { const target = el.querySelector(`[data-message-id="${targetId}"]`); @@ -746,9 +746,7 @@ export function ThreadDrawer({ room, threadRootId, onClose, overlay }: ThreadDra const threadParticipantIds = new Set( [rootEvent, ...replyEvents].map((ev) => ev?.getSender()).filter(Boolean) as string[] ); - const latestThreadEventId = ( - replyEvents.length > 0 ? replyEvents[replyEvents.length - 1] : rootEvent - )?.getId(); + const latestThreadEventId = (replyEvents.length > 0 ? replyEvents.at(-1) : rootEvent)?.getId(); return ( { const eventId = mEvent.getId(); const pinContent: RoomPinnedEventsEventContent = { - pinned: Array.from(pinnedEvents).filter((id) => id !== eventId), + pinned: [...pinnedEvents].filter((id) => id !== eventId), }; if (!isPinned && eventId) { pinContent.pinned.push(eventId); diff --git a/src/app/features/room/message/MessageEditor.tsx b/src/app/features/room/message/MessageEditor.tsx index b5960dcca..c84251c13 100644 --- a/src/app/features/room/message/MessageEditor.tsx +++ b/src/app/features/room/message/MessageEditor.tsx @@ -225,7 +225,7 @@ export const MessageEditor = as<'div', MessageEditorProps>( mentionData.users.add(prevMentionId); }); - const mMentions = getMentionContent(Array.from(mentionData.users), mentionData.room); + const mMentions = getMentionContent([...mentionData.users], mentionData.room); newContent['m.mentions'] = mMentions; contentBody['m.mentions'] = mMentions; diff --git a/src/app/features/room/message/Reactions.tsx b/src/app/features/room/message/Reactions.tsx index a5cacf2dc..d0c03c695 100644 --- a/src/app/features/room/message/Reactions.tsx +++ b/src/app/features/room/message/Reactions.tsx @@ -71,7 +71,7 @@ export const Reactions = as<'div', ReactionsProps>( ref={ref} > {reactions.map(([key, events]) => { - const rEvents = Array.from(events); + const rEvents = [...events]; if (rEvents.length === 0 || typeof key !== 'string') return null; const myREvent = myUserId ? rEvents.find(factoryEventSentBy(myUserId)) : undefined; const isPressed = !!myREvent?.getRelation(); diff --git a/src/app/features/room/reaction-viewer/ReactionViewer.tsx b/src/app/features/room/reaction-viewer/ReactionViewer.tsx index fc0573499..059ea39a5 100644 --- a/src/app/features/room/reaction-viewer/ReactionViewer.tsx +++ b/src/app/features/room/reaction-viewer/ReactionViewer.tsx @@ -62,7 +62,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( const getReactionsForKey = (key: string): MatrixEvent[] => { const reactSet = reactions.find(([k]) => k === key)?.[1]; if (!reactSet) return []; - return Array.from(reactSet); + return [...reactSet]; }; const selectedReactions = getReactionsForKey(selectedKey); diff --git a/src/app/features/room/room-pin-menu/RoomPinMenu.tsx b/src/app/features/room/room-pin-menu/RoomPinMenu.tsx index 705e8e850..be3bb04a8 100644 --- a/src/app/features/room/room-pin-menu/RoomPinMenu.tsx +++ b/src/app/features/room/room-pin-menu/RoomPinMenu.tsx @@ -310,7 +310,7 @@ export const RoomPinMenu = forwardRef( ); const pinnedEvents = useRoomPinnedEvents(room); - const sortedPinnedEvent = useMemo(() => Array.from(pinnedEvents).reverse(), [pinnedEvents]); + const sortedPinnedEvent = useMemo(() => pinnedEvents.toReversed(), [pinnedEvents]); const useAuthentication = useMediaAuthentication(); const [mediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); const [urlPreview] = useSetting(settingsAtom, 'urlPreview'); diff --git a/src/app/features/search/Search.tsx b/src/app/features/search/Search.tsx index 4c29a68df..7b588f99b 100644 --- a/src/app/features/search/Search.tsx +++ b/src/app/features/search/Search.tsx @@ -87,10 +87,10 @@ const useTopActiveRooms = ( return spaces; } if (searchRoomType === SearchRoomType.Directs) { - return [...directs].sort(factoryRoomIdByActivity(mx)).slice(0, 20); + return directs.toSorted(factoryRoomIdByActivity(mx)).slice(0, 20); } if (searchRoomType === SearchRoomType.Rooms) { - return [...rooms].sort(factoryRoomIdByActivity(mx)).slice(0, 20); + return rooms.toSorted(factoryRoomIdByActivity(mx)).slice(0, 20); } return [...rooms, ...directs].sort(factoryRoomIdByActivity(mx)).slice(0, 20); }, [mx, rooms, directs, spaces, searchRoomType]); @@ -178,7 +178,7 @@ export function Search({ requestClose }: SearchProps) { const items = result ? result.items : topActiveRooms; if (!selectedSpaceId) return items; - return [...items].sort((a, b) => { + return items.toSorted((a, b) => { const aInSpace = getAllParents(roomToParents, a)?.has(selectedSpaceId) ? 1 : 0; const bInSpace = getAllParents(roomToParents, b)?.has(selectedSpaceId) ? 1 : 0; return bInSpace - aInSpace; @@ -328,7 +328,7 @@ export function Search({ requestClose }: SearchProps) { const exactParents = roomToParents.get(roomId); const perfectParent = - exactParents && guessPerfectParent(mx, roomId, Array.from(exactParents)); + exactParents && guessPerfectParent(mx, roomId, [...exactParents]); const unread = roomToUnread.get(roomId); diff --git a/src/app/features/settings/account/TimezoneEditor.tsx b/src/app/features/settings/account/TimezoneEditor.tsx index 0b3e12d1c..4832268ca 100644 --- a/src/app/features/settings/account/TimezoneEditor.tsx +++ b/src/app/features/settings/account/TimezoneEditor.tsx @@ -2,9 +2,9 @@ import { useMemo, useState, useEffect, type ChangeEvent } from 'react'; import { Box, IconButton, Button, Icon, Icons, Input, Text } from 'folds'; import { SettingTile } from '$components/setting-tile'; -interface IntlWithSupportedValues { +type IntlWithSupportedValues = { supportedValuesOf(key: 'timeZone' | string): string[]; -} +}; type TimezoneEditorProps = { current?: string; diff --git a/src/app/features/settings/developer-tools/AccountData.tsx b/src/app/features/settings/developer-tools/AccountData.tsx index 6cd68e9bc..2a527db4e 100644 --- a/src/app/features/settings/developer-tools/AccountData.tsx +++ b/src/app/features/settings/developer-tools/AccountData.tsx @@ -16,14 +16,14 @@ export function AccountData({ expand, onExpandToggle, onSelect }: AccountDataPro const mx = useMatrixClient(); const [accountDataTypes, setAccountDataKeys] = useState(() => // TODO: tighten this once account data event typing is standardized. - Array.from(mx.store.accountData.keys()) + [...mx.store.accountData.keys()] ); useAccountDataCallback( mx, useCallback(() => { // TODO: tighten this once account data event typing is standardized. - setAccountDataKeys(Array.from(mx.store.accountData.keys())); + setAccountDataKeys([...mx.store.accountData.keys()]); }, [mx]) ); diff --git a/src/app/features/settings/developer-tools/SentrySettings.tsx b/src/app/features/settings/developer-tools/SentrySettings.tsx index 3c6ef4874..3f4be813f 100644 --- a/src/app/features/settings/developer-tools/SentrySettings.tsx +++ b/src/app/features/settings/developer-tools/SentrySettings.tsx @@ -3,6 +3,7 @@ import { Box, Text, Switch, Button } from 'folds'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; import { SequenceCardStyle } from '$features/settings/styles.css'; +import { getSentryEnabled } from '$state/sentryStorage'; import { getDebugLogger, type LogCategory } from '$utils/debugLogger'; const ALL_CATEGORIES: LogCategory[] = [ @@ -50,7 +51,7 @@ export function SentrySettings() { }; const isSentryConfigured = Boolean(import.meta.env.VITE_SENTRY_DSN); - const sentryEnabled = localStorage.getItem('sable_sentry_enabled') === 'true'; + const sentryEnabled = getSentryEnabled(); const environment = import.meta.env.VITE_SENTRY_ENVIRONMENT || import.meta.env.MODE; const isProd = environment === 'production'; const traceSampleRate = isProd ? '10%' : '100%'; diff --git a/src/app/features/settings/developer-tools/SyncDiagnostics.tsx b/src/app/features/settings/developer-tools/SyncDiagnostics.tsx index f9b062b71..7e9f302f9 100644 --- a/src/app/features/settings/developer-tools/SyncDiagnostics.tsx +++ b/src/app/features/settings/developer-tools/SyncDiagnostics.tsx @@ -77,8 +77,10 @@ const getUnreadDriftRooms = (mx: ReturnType): UnreadDrif if (sdkTotal <= 0 && sdkHighlight <= 0) return driftRooms; if (reconciledUnread.total <= 0 && reconciledUnread.highlight <= 0) return driftRooms; - const latestNotificationEvent = [...room.getLiveTimeline().getEvents()] - .reverse() + const latestNotificationEvent = room + .getLiveTimeline() + .getEvents() + .toReversed() .find((event) => !event.isSending() && isNotificationEvent(event)); const latestNotificationEventId = latestNotificationEvent?.getId() ?? null; if (!latestNotificationEventId) return driftRooms; diff --git a/src/app/features/settings/devices/OtherDevices.tsx b/src/app/features/settings/devices/OtherDevices.tsx index 8687f1165..c37e0fce0 100644 --- a/src/app/features/settings/devices/OtherDevices.tsx +++ b/src/app/features/settings/devices/OtherDevices.tsx @@ -76,7 +76,7 @@ export function OtherDevices({ devices, refreshDeviceList, showVerification }: O const deleteDevices = useAsync( useCallback( async (authDict?: AuthDict) => { - await mx.deleteMultipleDevices(Array.from(deleted), authDict); + await mx.deleteMultipleDevices([...deleted], authDict); }, [mx, deleted] ), diff --git a/src/app/features/settings/emojis-stickers/GlobalPacks.tsx b/src/app/features/settings/emojis-stickers/GlobalPacks.tsx index 799e709f6..4ff83323a 100644 --- a/src/app/features/settings/emojis-stickers/GlobalPacks.tsx +++ b/src/app/features/settings/emojis-stickers/GlobalPacks.tsx @@ -81,9 +81,9 @@ function GlobalPackSelector({ const addSelected = (adds: PackAddress[]) => { setSelected((addresses) => { - const newAddresses = Array.from(addresses); + const newAddresses = [...addresses]; adds.forEach((address) => { - if (newAddresses.find((addr) => packAddressEqual(addr, address))) { + if (newAddresses.some((addr) => packAddressEqual(addr, address))) { return; } newAddresses.push(address); @@ -95,7 +95,7 @@ function GlobalPackSelector({ const removeSelected = (adds: PackAddress[]) => { setSelected((addresses) => { const newAddresses = addresses.filter( - (addr) => !adds.find((address) => packAddressEqual(addr, address)) + (addr) => !adds.some((address) => packAddressEqual(addr, address)) ); return newAddresses; }); @@ -134,7 +134,7 @@ function GlobalPackSelector({ paddingRight: config.space.S100, }} > - {Array.from(roomToPacks.entries()).map(([roomId, roomPacks]) => { + {Array.from(roomToPacks.entries(), ([roomId, roomPacks]) => { const room = mx.getRoom(roomId); if (!room) return null; const roomPackAddresses = roomPacks @@ -174,7 +174,7 @@ function GlobalPackSelector({ const { address } = pack; if (!address) return null; - const added = !!selected.find((addr) => packAddressEqual(addr, address)); + const added = selected.some((addr) => packAddressEqual(addr, address)); return ( roomsImagePack.filter( - (pack) => !globalPacks.find((p) => packAddressEqual(pack.address, p.address)) + (pack) => !globalPacks.some((p) => packAddressEqual(pack.address, p.address)) ), [roomsImagePack, globalPacks] ); @@ -280,7 +280,7 @@ export function GlobalPacks({ onViewPack }: GlobalPacksProps) { const unselectedGlobalPacks = useMemo( () => nonGlobalPacks.filter( - (pack) => !selectedPacks.find((addr) => packAddressEqual(pack.address, addr)) + (pack) => !selectedPacks.some((addr) => packAddressEqual(pack.address, addr)) ), [selectedPacks, nonGlobalPacks] ); @@ -347,7 +347,7 @@ export function GlobalPacks({ onViewPack }: GlobalPacksProps) { const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication) : undefined; const { address } = pack; if (!address) return null; - const removed = !!removedPacks.find((addr) => packAddressEqual(addr, address)); + const removed = removedPacks.some((addr) => packAddressEqual(addr, address)); return ( {globalPacks.map(renderPack)} {nonGlobalPacks - .filter((pack) => !!selectedPacks.find((addr) => packAddressEqual(pack.address, addr))) + .filter((pack) => selectedPacks.some((addr) => packAddressEqual(pack.address, addr))) .map(renderPack)} {hasChanges && ( diff --git a/src/app/features/settings/general/General.tsx b/src/app/features/settings/general/General.tsx index 1d4bcd1e5..15467bedb 100644 --- a/src/app/features/settings/general/General.tsx +++ b/src/app/features/settings/general/General.tsx @@ -48,6 +48,12 @@ import { useMessageSpacingItems } from '$hooks/useMessageSpacing'; import { useDateFormatItems } from '$hooks/useDateFormat'; import { SequenceCardStyle } from '$features/settings/styles.css'; import { sessionsAtom, activeSessionIdAtom } from '$state/sessions'; +import { + getSentryEnabled, + getSentryReplayEnabled, + setSentryEnabled as persistSentryEnabled, + setSentryReplayEnabled, +} from '$state/sentryStorage'; import { useClientConfig } from '$hooks/useClientConfig'; import { resolveSlidingEnabled } from '$client/initMatrix'; import { isKeyHotkey } from 'is-hotkey'; @@ -1239,33 +1245,21 @@ function SettingsSyncSection() { } function DiagnosticsAndPrivacy() { - const [sentryEnabled, setSentryEnabled] = useState( - localStorage.getItem('sable_sentry_enabled') === 'true' - ); - const [sessionReplayEnabled, setSessionReplayEnabled] = useState( - localStorage.getItem('sable_sentry_replay_enabled') === 'true' - ); + const [sentryEnabled, setSentryEnabled] = useState(getSentryEnabled()); + const [sessionReplayEnabled, setSessionReplayEnabled] = useState(getSentryReplayEnabled()); const [needsRefresh, setNeedsRefresh] = useState(false); const isSentryConfigured = Boolean(import.meta.env.VITE_SENTRY_DSN); const handleSentryToggle = (enabled: boolean) => { setSentryEnabled(enabled); - if (enabled) { - localStorage.setItem('sable_sentry_enabled', 'true'); - } else { - localStorage.setItem('sable_sentry_enabled', 'false'); - } + persistSentryEnabled(enabled); setNeedsRefresh(true); }; const handleReplayToggle = (enabled: boolean) => { setSessionReplayEnabled(enabled); - if (enabled) { - localStorage.setItem('sable_sentry_replay_enabled', 'true'); - } else { - localStorage.removeItem('sable_sentry_replay_enabled'); - } + setSentryReplayEnabled(enabled); setNeedsRefresh(true); }; diff --git a/src/app/features/settings/keyboard-shortcuts/KeyboardShortcuts.tsx b/src/app/features/settings/keyboard-shortcuts/KeyboardShortcuts.tsx index 0ce94a9c3..99831fa03 100644 --- a/src/app/features/settings/keyboard-shortcuts/KeyboardShortcuts.tsx +++ b/src/app/features/settings/keyboard-shortcuts/KeyboardShortcuts.tsx @@ -19,7 +19,7 @@ type ShortcutCategory = { function formatKey(key: string): string { const isMac = - typeof navigator !== 'undefined' && navigator.platform.toUpperCase().indexOf('MAC') >= 0; + typeof navigator !== 'undefined' && navigator.platform.toUpperCase().includes('MAC'); return key .replace(/\bmod\b/g, isMac ? '⌘' : 'Ctrl') .replace(/\balt\b/gi, isMac ? '⌥' : 'Alt') diff --git a/src/app/features/widgets/IntegrationManager.tsx b/src/app/features/widgets/IntegrationManager.tsx index 09ab8bcae..133b87c66 100644 --- a/src/app/features/widgets/IntegrationManager.tsx +++ b/src/app/features/widgets/IntegrationManager.tsx @@ -17,11 +17,11 @@ import { type Room } from '$types/matrix-sdk'; import { useIntegrationManager, buildIntegrationManagerUrl } from '$hooks/useIntegrationManager'; import * as css from './IntegrationManager.css'; -interface IntegrationManagerProps { +type IntegrationManagerProps = { room: Room; open: boolean; onClose: () => void; -} +}; export function IntegrationManager({ room, open, onClose }: IntegrationManagerProps) { const { managers, scalarToken, loading, error } = useIntegrationManager(); diff --git a/src/app/features/widgets/WidgetIframe.tsx b/src/app/features/widgets/WidgetIframe.tsx index bf63cde61..a7d1eb981 100644 --- a/src/app/features/widgets/WidgetIframe.tsx +++ b/src/app/features/widgets/WidgetIframe.tsx @@ -20,12 +20,12 @@ import { GenericWidgetDriver, type CapabilityApprovalCallback } from './GenericW const log = createLogger('WidgetIframe'); -interface WidgetIframeProps { +type WidgetIframeProps = { widget: IWidget; roomId: string; mx: MatrixClient; onCapabilityRequest?: CapabilityApprovalCallback; -} +}; export function WidgetIframe({ widget, roomId, mx, onCapabilityRequest }: WidgetIframeProps) { const iframeRef = useRef(null); @@ -84,7 +84,7 @@ export function WidgetIframe({ widget, roomId, mx, onCapabilityRequest }: Widget return; } const stateEvents = state.events?.get(type); - Array.from(stateEvents?.values() ?? []).forEach((eventObject: MatrixEvent) => { + [...(stateEvents?.values() ?? [])].forEach((eventObject: MatrixEvent) => { events.push(eventObject.event); }); messaging.transport.reply(ev.detail, { events }); @@ -93,7 +93,7 @@ export function WidgetIframe({ widget, roomId, mx, onCapabilityRequest }: Widget const readUpToMap: Record = {}; mx.getRooms().forEach((room) => { const roomEvents = room.getLiveTimeline()?.getEvents() || []; - const last = roomEvents[roomEvents.length - 1]; + const last = roomEvents.at(-1); if (last) { const id = last.getId(); if (id) readUpToMap[room.roomId] = id; diff --git a/src/app/hooks/timeline/useProcessedTimeline.ts b/src/app/hooks/timeline/useProcessedTimeline.ts index 861736f5d..479a62a53 100644 --- a/src/app/hooks/timeline/useProcessedTimeline.ts +++ b/src/app/hooks/timeline/useProcessedTimeline.ts @@ -8,7 +8,7 @@ import { import { reactionOrEditEvent, isMembershipChanged } from '$utils/room'; import { inSameDay, minuteDifference } from '$utils/time'; -export interface UseProcessedTimelineOptions { +export type UseProcessedTimelineOptions = { items: number[]; linkedTimelines: EventTimeline[]; ignoredUsersSet: Set; @@ -20,9 +20,9 @@ export interface UseProcessedTimelineOptions { hideNickAvatarEvents: boolean; isReadOnly: boolean; hideMemberInReadOnly: boolean; -} +}; -export interface ProcessedEvent { +export type ProcessedEvent = { id: string; itemIndex: number; mEvent: MatrixEvent; @@ -31,7 +31,7 @@ export interface ProcessedEvent { collapsed: boolean; willRenderNewDivider: boolean; willRenderDayDivider: boolean; -} +}; const MESSAGE_EVENT_TYPES = [ 'm.room.message', diff --git a/src/app/hooks/timeline/useTimelineActions.ts b/src/app/hooks/timeline/useTimelineActions.ts index a3782eea0..434546ac7 100644 --- a/src/app/hooks/timeline/useTimelineActions.ts +++ b/src/app/hooks/timeline/useTimelineActions.ts @@ -13,7 +13,7 @@ import { getMxIdLocalPart, toggleReaction } from '$utils/matrix'; import { getMemberDisplayName, getEditedEvent } from '$utils/room'; import { createMentionElement, isEmptyEditor, moveCursor } from '$components/editor'; -export interface UseTimelineActionsOptions { +export type UseTimelineActionsOptions = { room: Room; mx: MatrixClient; editor: Editor; @@ -36,7 +36,7 @@ export interface UseTimelineActionsOptions { setEditId: (editId: string | undefined) => void; onEditorReset?: () => void; handleOpenEvent: (eventId: string) => void; -} +}; export function useTimelineActions({ room, diff --git a/src/app/hooks/timeline/useTimelineEventRenderer.tsx b/src/app/hooks/timeline/useTimelineEventRenderer.tsx index d7d94e49d..60bf9bd63 100644 --- a/src/app/hooks/timeline/useTimelineEventRenderer.tsx +++ b/src/app/hooks/timeline/useTimelineEventRenderer.tsx @@ -204,7 +204,7 @@ function ThreadReplyChip({ ); } -export interface TimelineEventRendererOptions { +export type TimelineEventRendererOptions = { room: Room; mx: MatrixClient; pushProcessor: PushProcessor; @@ -256,7 +256,7 @@ export interface TimelineEventRendererOptions { getMemberPowerTag: ReturnType; parseMemberEvent: ReturnType; }; -} +}; export function useTimelineEventRenderer({ room, diff --git a/src/app/hooks/timeline/useTimelineSync.ts b/src/app/hooks/timeline/useTimelineSync.ts index 62c525f13..b567aaef9 100644 --- a/src/app/hooks/timeline/useTimelineSync.ts +++ b/src/app/hooks/timeline/useTimelineSync.ts @@ -326,7 +326,7 @@ const useThreadUpdate = (room: Room, onUpdate: () => void) => { }, [room]); }; -export interface UseTimelineSyncOptions { +export type UseTimelineSyncOptions = { room: Room; mx: MatrixClient; eventId?: string; @@ -337,7 +337,7 @@ export interface UseTimelineSyncOptions { setUnreadInfo: Dispatch>>; hideReadsRef: React.MutableRefObject; readUptoEventIdRef: React.MutableRefObject; -} +}; export function useTimelineSync({ room, diff --git a/src/app/hooks/useAsyncSearch.ts b/src/app/hooks/useAsyncSearch.ts index 5ab436d09..36e74d550 100644 --- a/src/app/hooks/useAsyncSearch.ts +++ b/src/app/hooks/useAsyncSearch.ts @@ -52,7 +52,7 @@ export const orderSearchItems = ( getItemStr: SearchItemStrGetter, options?: UseAsyncSearchOptions ): TSearchItem[] => { - const orderedItems: TSearchItem[] = Array.from(items); + const orderedItems: TSearchItem[] = [...items]; // we will consider "_" as word boundary char. // because in more use-cases it is used. (like: emojishortcode) diff --git a/src/app/hooks/useCallSignaling.ts b/src/app/hooks/useCallSignaling.ts index 16620acb9..66577565a 100644 --- a/src/app/hooks/useCallSignaling.ts +++ b/src/app/hooks/useCallSignaling.ts @@ -14,10 +14,10 @@ const debugLog = createDebugLogger('CallSignaling'); type CallPhase = 'IDLE' | 'RINGING_OUT' | 'RINGING_IN' | 'ACTIVE' | 'ENDED'; -interface SignalState { +type SignalState = { incoming: string | null; outgoing: string | null; -} +}; export function useCallSignaling() { const mx = useMatrixClient(); @@ -100,7 +100,7 @@ export function useCallSignaling() { const myUserId = mx.getUserId(); const now = Date.now(); - const signal = Array.from(mDirects).reduce( + const signal = [...mDirects].reduce( (acc, roomId) => { if (acc.incoming || mutedRoomIdRef.current === roomId) return acc; diff --git a/src/app/hooks/useCommands.ts b/src/app/hooks/useCommands.ts index 91c610ca3..de621a476 100644 --- a/src/app/hooks/useCommands.ts +++ b/src/app/hooks/useCommands.ts @@ -164,10 +164,7 @@ const hslToHex = (h: number, s: number, l: number): string => { const getAllTextNodes = (root: Node): Node[] => root.nodeType === Node.TEXT_NODE ? [root] - : Array.from(root.childNodes).reduce( - (acc, child) => acc.concat(getAllTextNodes(child)), - [] - ); + : [...root.childNodes].reduce((acc, child) => [...acc, ...getAllTextNodes(child)], []); export const rainbowify = (htmlInput: string): string => { const div = document.createElement('div'); @@ -175,7 +172,7 @@ export const rainbowify = (htmlInput: string): string => { const textNodes = getAllTextNodes(div); const totalTextLen = textNodes.reduce((acc, node) => { const text = node.textContent || ''; - const cleanLen = Array.from(text).filter((c) => c.trim().length > 0).length; + const cleanLen = [...text].filter((c) => c.trim().length > 0).length; return acc + cleanLen; }, 0); @@ -183,7 +180,7 @@ export const rainbowify = (htmlInput: string): string => { const text = node.textContent || ''; if (!text.trim()) return currentGlobalIdx; - const chars = Array.from(text); + const chars = [...text]; const { html: newHtml, count: charsProcessed } = chars.reduce( (acc, char) => { @@ -447,7 +444,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { const rawIds = splitWithSpace(payload); const userIds = rawIds.filter((id) => isUserId(id)); if (userIds.length > 0) { - let ignoredUsers = mx.getIgnoredUsers().concat(userIds); + let ignoredUsers = [...mx.getIgnoredUsers(), ...userIds]; ignoredUsers = [...new Set(ignoredUsers)]; await mx.setIgnoredUsers(ignoredUsers); } @@ -614,7 +611,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { if (newAvatar.length === 0) { // no avatar, reset to global newAvatar = profile.avatarUrl; - } else if (!newAvatar.match(/^mxc:\/\/\S+$/)) { + } else if (!/^mxc:\/\/\S+$/.test(newAvatar)) { // bad mxc return; } diff --git a/src/app/hooks/useComposingCheck.ts b/src/app/hooks/useComposingCheck.ts index 9208fcf33..a9f508c9d 100644 --- a/src/app/hooks/useComposingCheck.ts +++ b/src/app/hooks/useComposingCheck.ts @@ -2,9 +2,9 @@ import { useCallback, useEffect } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; import { lastCompositionEndAtom } from '$state/lastCompositionEnd'; -interface TimeStamped { +type TimeStamped = { readonly timeStamp: number; -} +}; export function useCompositionEndTracking(): void { const setLastCompositionEnd = useSetAtom(lastCompositionEndAtom); @@ -24,13 +24,13 @@ export function useCompositionEndTracking(): void { }); } -interface IsComposingLike { +type IsComposingLike = { readonly timeStamp: number; readonly keyCode: number; readonly nativeEvent: { readonly isComposing?: boolean; }; -} +}; export function useComposingCheck({ compositionEndThreshold = 500, diff --git a/src/app/hooks/useDebounce.ts b/src/app/hooks/useDebounce.ts index 5f33976a3..d3ebc7b3d 100644 --- a/src/app/hooks/useDebounce.ts +++ b/src/app/hooks/useDebounce.ts @@ -1,9 +1,9 @@ import { useCallback, useRef } from 'react'; -export interface DebounceOptions { +export type DebounceOptions = { wait?: number; immediate?: boolean; -} +}; export type DebounceCallback = (...args: T) => void; export function useDebounce( diff --git a/src/app/hooks/useImageGestures.ts b/src/app/hooks/useImageGestures.ts index 203d35784..90d539628 100644 --- a/src/app/hooks/useImageGestures.ts +++ b/src/app/hooks/useImageGestures.ts @@ -30,7 +30,7 @@ export const useImageGestures = (active: boolean, step = 0.2, min = 0.1, max = 5 setCursor('grabbing'); if (activePointers.current.size === 2) { - const points = Array.from(activePointers.current.values()); + const points = [...activePointers.current.values()]; initialDist.current = Math.hypot(points[0].x - points[1].x, points[0].y - points[1].y); } }; @@ -42,7 +42,7 @@ export const useImageGestures = (active: boolean, step = 0.2, min = 0.1, max = 5 activePointers.current.set(e.pointerId, { x: e.clientX, y: e.clientY }); if (activePointers.current.size === 2) { - const points = Array.from(activePointers.current.values()); + const points = [...activePointers.current.values()]; const currentDist = Math.hypot(points[0].x - points[1].x, points[0].y - points[1].y); const delta = currentDist / initialDist.current; diff --git a/src/app/hooks/useImagePackRooms.ts b/src/app/hooks/useImagePackRooms.ts index 6e22886e3..d9622db45 100644 --- a/src/app/hooks/useImagePackRooms.ts +++ b/src/app/hooks/useImagePackRooms.ts @@ -10,7 +10,7 @@ export const useImagePackRooms = ( const mx = useMatrixClient(); const imagePackRooms: Room[] = useMemo(() => { - const allParentSpaces = [roomId].concat(Array.from(getAllParents(roomToParents, roomId))); + const allParentSpaces = [...[roomId], ...[...getAllParents(roomToParents, roomId)]]; return allParentSpaces.reduce((list, rId) => { const r = mx.getRoom(rId); if (r) list.push(r); diff --git a/src/app/hooks/useImagePacks.ts b/src/app/hooks/useImagePacks.ts index 47c6cbedd..b318034a3 100644 --- a/src/app/hooks/useImagePacks.ts +++ b/src/app/hooks/useImagePacks.ts @@ -24,8 +24,8 @@ import { useStateEventCallback } from './useStateEventCallback'; const imagePackEqual = (a: ImagePack | undefined, b: ImagePack | undefined): boolean => { if (!a && !b) return true; if (!a || !b) return false; - const aImages = Array.from(a.images.collection.entries()); - const bImages = Array.from(b.images.collection.entries()); + const aImages = [...a.images.collection.entries()]; + const bImages = [...b.images.collection.entries()]; if (aImages.length !== bImages.length) return false; const sameImages = aImages.every(([shortcode, image], index) => { const [otherShortcode, otherImage] = bImages[index]; @@ -136,7 +136,7 @@ export const useGlobalImagePacks = (): ImagePack[] => { const stateKey = mEvent.getStateKey(); if (eventType === StateEvent.PoniesRoomEmotes && roomId && typeof stateKey === 'string') { setGlobalPacks((prev) => { - const global = !!prev.find( + const global = prev.some( (pack) => pack.address && pack.address.roomId === roomId && pack.address.stateKey === stateKey ); @@ -287,7 +287,7 @@ export const useRoomsImagePacks = (rooms: Room[]) => { useCallback( (mEvent) => { if ( - rooms.find((room) => room.roomId === mEvent.getRoomId()) && + rooms.some((room) => room.roomId === mEvent.getRoomId()) && mEvent.getType() === StateEvent.PoniesRoomEmotes ) { setRoomPacks((prev) => { @@ -312,10 +312,11 @@ export const useRelevantImagePacks = (usage: ImageUsage, rooms: Room[]): ImagePa const packs = userPack ? [userPack] : []; const globalPackIds = new Set(globalPacks.map((pack) => pack.id)); - const relPacks = packs.concat( - globalPacks, - roomsPacks.filter((pack) => !globalPackIds.has(pack.id)) - ); + const relPacks = [ + ...packs, + ...globalPacks, + ...roomsPacks.filter((pack) => !globalPackIds.has(pack.id)), + ]; return relPacks.filter((pack) => pack.getImages(usage).length > 0); }, [userPack, globalPacks, roomsPacks, usage]); diff --git a/src/app/hooks/useIntegrationManager.ts b/src/app/hooks/useIntegrationManager.ts index c84d98d97..76a978288 100644 --- a/src/app/hooks/useIntegrationManager.ts +++ b/src/app/hooks/useIntegrationManager.ts @@ -2,10 +2,10 @@ import { useCallback, useEffect, useState } from 'react'; import { type MatrixClient } from '$types/matrix-sdk'; import { useMatrixClient } from './useMatrixClient'; -export interface IntegrationManager { +export type IntegrationManager = { apiUrl: string; uiUrl: string; -} +}; const DEFAULT_MANAGERS: IntegrationManager[] = [ { diff --git a/src/app/hooks/useMediaConfig.ts b/src/app/hooks/useMediaConfig.ts index 929ebd004..d633cd6b7 100644 --- a/src/app/hooks/useMediaConfig.ts +++ b/src/app/hooks/useMediaConfig.ts @@ -1,9 +1,9 @@ import { createContext, useContext } from 'react'; -export interface MediaConfig { +export type MediaConfig = { [key: string]: unknown; 'm.upload.size'?: number; -} +}; const MediaConfigContext = createContext(null); diff --git a/src/app/hooks/usePerMessageProfile.ts b/src/app/hooks/usePerMessageProfile.ts index dced8f01e..b3b996acc 100644 --- a/src/app/hooks/usePerMessageProfile.ts +++ b/src/app/hooks/usePerMessageProfile.ts @@ -198,7 +198,7 @@ async function getRoomsUsingProfile(mx: MatrixClient, profileId: string): Promis const content: PerMessageProfileRoomAssociationWrapper | undefined = accountData?.getContent(); const associations = getAssociationsMap(content); const roomsUsingProfile: string[] = []; - Array.from(associations.entries()).forEach(([roomId, assoc]) => { + [...associations.entries()].forEach(([roomId, assoc]) => { if (assoc?.profileId === profileId) roomsUsingProfile.push(roomId); }); return roomsUsingProfile; diff --git a/src/app/hooks/usePowerLevelTags.ts b/src/app/hooks/usePowerLevelTags.ts index 6b5407cdd..05cff7f6d 100644 --- a/src/app/hooks/usePowerLevelTags.ts +++ b/src/app/hooks/usePowerLevelTags.ts @@ -95,7 +95,7 @@ export const usePowerLevelTags = (room: Room, powerLevels: IPowerLevels): PowerL const powerToTags: PowerLevelTags = { ...content }; const powers = getUsedPowers(powerLevels); - Array.from(powers).forEach((power) => { + [...powers].forEach((power) => { if (powerToTags[power]?.name === undefined) { powerToTags[power] = DEFAULT_TAGS[power] ?? generateFallbackTag(DEFAULT_TAGS, power); } diff --git a/src/app/hooks/usePowerLevels.ts b/src/app/hooks/usePowerLevels.ts index 2332f3354..a99f2d5b6 100644 --- a/src/app/hooks/usePowerLevels.ts +++ b/src/app/hooks/usePowerLevels.ts @@ -109,7 +109,7 @@ export const useRoomsPowerLevels = (rooms: Room[]): Map => roomId && event.getType() === StateEvent.RoomPowerLevels && event.getStateKey() === '' && - rooms.find((r) => r.roomId === roomId) + rooms.some((r) => r.roomId === roomId) ) { setRoomToPowerLevels(getRoomsPowerLevels()); } diff --git a/src/app/hooks/useRoomAbbreviations.ts b/src/app/hooks/useRoomAbbreviations.ts index 91a2b35a7..34a93d27c 100644 --- a/src/app/hooks/useRoomAbbreviations.ts +++ b/src/app/hooks/useRoomAbbreviations.ts @@ -54,7 +54,7 @@ export const useMergedAbbreviations = (room: Room): Map => { ); return useMemo(() => { - const allParentIds = Array.from(getAllParents(roomToParents, room.roomId)); + const allParentIds = [...getAllParents(roomToParents, room.roomId)]; const ancestorEntries = allParentIds.flatMap((parentId) => { const parentRoom = mx.getRoom(parentId); if (!parentRoom) return []; diff --git a/src/app/hooks/useRoomAccountData.ts b/src/app/hooks/useRoomAccountData.ts index 5fd4ff520..fe66645d3 100644 --- a/src/app/hooks/useRoomAccountData.ts +++ b/src/app/hooks/useRoomAccountData.ts @@ -5,7 +5,7 @@ export const useRoomAccountData = (room: Room): Map => { const getAccountData = useCallback((): Map => { const accountData = new Map(); - Array.from(room.accountData.entries()).forEach(([type, mEvent]) => { + [...room.accountData.entries()].forEach(([type, mEvent]) => { const content = mEvent.getContent(); accountData.set(type, content); }); diff --git a/src/app/hooks/useRoomWidgets.ts b/src/app/hooks/useRoomWidgets.ts index 3c1a43444..e2cbde94f 100644 --- a/src/app/hooks/useRoomWidgets.ts +++ b/src/app/hooks/useRoomWidgets.ts @@ -6,10 +6,10 @@ import { getStateEvents } from '$utils/room'; import { useStateEventCallback } from './useStateEventCallback'; import { useForceUpdate } from './useForceUpdate'; -export interface RoomWidget extends IWidget { +export type RoomWidget = { eventId?: string; sender?: string; -} +} & IWidget; export const resolveWidgetUrl = ( url: string, diff --git a/src/app/hooks/useSidebarItems.ts b/src/app/hooks/useSidebarItems.ts index b3fa793a4..49a0e673c 100644 --- a/src/app/hooks/useSidebarItems.ts +++ b/src/app/hooks/useSidebarItems.ts @@ -48,13 +48,13 @@ export const parseSidebar = ( typeof item === 'object' && typeof item.id === 'string' && Array.isArray(item.content) && - !items.find((i) => (typeof i === 'string' ? false : i.id === item.id)) + !items.some((i) => (typeof i === 'string' ? false : i.id === item.id)) ) { const safeContent = item.content.filter(safeToAdd); safeContent.forEach((i) => orphans.delete(i)); items.push({ ...item, - content: Array.from(new Set(safeContent)), + content: [...new Set(safeContent)], }); } }); diff --git a/src/app/hooks/useThrottle.ts b/src/app/hooks/useThrottle.ts index 12b249f29..3d2875fd4 100644 --- a/src/app/hooks/useThrottle.ts +++ b/src/app/hooks/useThrottle.ts @@ -1,9 +1,9 @@ import { useCallback, useRef } from 'react'; -export interface ThrottleOptions { +export type ThrottleOptions = { wait?: number; immediate?: boolean; -} +}; export type ThrottleCallback = (...args: T) => void; diff --git a/src/app/pages/client/BackgroundNotifications.tsx b/src/app/pages/client/BackgroundNotifications.tsx index 44af1ed91..8b5c60688 100644 --- a/src/app/pages/client/BackgroundNotifications.tsx +++ b/src/app/pages/client/BackgroundNotifications.tsx @@ -144,7 +144,7 @@ export function BackgroundNotifications() { const inactiveSessionsRef = useRef(inactiveSessions); inactiveSessionsRef.current = inactiveSessions; - interface NotifyOptions { + type NotifyOptions = { /** Title shown in the notification banner. */ title: string; /** Body text. */ @@ -162,7 +162,7 @@ export function BackgroundNotifications() { /** Optional callback invoked when the user clicks the notification (window.Notification * fallback path only; the SW path routes via its own notificationclick handler). */ onClick?: () => void; - } + }; useEffect(() => { if (!shouldRunBackgroundNotifications) { diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx index daade38e9..3cd91d205 100644 --- a/src/app/pages/client/ClientRoot.tsx +++ b/src/app/pages/client/ClientRoot.tsx @@ -330,8 +330,7 @@ export function ClientRoot({ children }: ClientRootProps) { 'SHA-256', new TextEncoder().encode(matrixUserId) ); - const hashHex = Array.from(new Uint8Array(hashBuffer)) - .map((b) => b.toString(16).padStart(2, '0')) + const hashHex = Array.from(new Uint8Array(hashBuffer), (b) => b.toString(16).padStart(2, '0')) .join('') .slice(0, 16); // Include the homeserver domain as a custom attribute — it is not PII (it is the diff --git a/src/app/pages/client/direct/Direct.tsx b/src/app/pages/client/direct/Direct.tsx index 67c1cdb71..83da5056d 100644 --- a/src/app/pages/client/direct/Direct.tsx +++ b/src/app/pages/client/direct/Direct.tsx @@ -212,7 +212,7 @@ export function Direct() { }, [mx, directs]); const sortedDirects = useMemo(() => { - const items = Array.from(directs).sort(factoryRoomIdByActivity(mx)); + const items = directs.toSorted(factoryRoomIdByActivity(mx)); const hasUnread = (roomId: string) => { const unread = roomToUnread.get(roomId); return !!unread && (unread.total > 0 || unread.highlight > 0); diff --git a/src/app/pages/client/explore/Server.tsx b/src/app/pages/client/explore/Server.tsx index 403d15ff5..1b0c44400 100644 --- a/src/app/pages/client/explore/Server.tsx +++ b/src/app/pages/client/explore/Server.tsx @@ -574,7 +574,7 @@ export function PublicRooms() { {isLoading && ( - {[...new Array(currentLimit).keys()].map((item) => ( + {Array.from(new Array(currentLimit).keys(), (item) => ( ))} diff --git a/src/app/pages/client/home/Home.tsx b/src/app/pages/client/home/Home.tsx index 8a114f07d..031bb28f1 100644 --- a/src/app/pages/client/home/Home.tsx +++ b/src/app/pages/client/home/Home.tsx @@ -207,7 +207,7 @@ export function Home() { const [closedCategories, setClosedCategories] = useAtom(useClosedNavCategoriesAtom()); const sortedRooms = useMemo(() => { - const items = Array.from(rooms).sort( + const items = rooms.toSorted( closedCategories.has(DEFAULT_CATEGORY_ID) ? factoryRoomIdByActivity(mx) : factoryRoomIdByAtoZ(mx) diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx index 831a50238..a895a99ed 100644 --- a/src/app/pages/client/inbox/Invites.tsx +++ b/src/app/pages/client/inbox/Invites.tsx @@ -578,7 +578,7 @@ function SpamInvites({ ); const ignoredUsers = useIgnoredUsers(); - const unignoredUsers = Array.from(new Set(invites.map((invite) => invite.senderId))).filter( + const unignoredUsers = [...new Set(invites.map((invite) => invite.senderId))].filter( (user) => !ignoredUsers.includes(user) ); const [blockAllStatus, blockAll] = useAsyncCallback( diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index 87613dec1..8e4756867 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -173,7 +173,7 @@ const useNotificationTimeline = ( if (currentTimeline.nextToken === from) { return { nextToken: data.next_token, - groups: from ? currentTimeline.groups.concat(groups) : groups, + groups: from ? [...currentTimeline.groups, ...groups] : groups, }; } return currentTimeline; @@ -762,7 +762,7 @@ export function Notifications() { {timelineState.status === AsyncStatus.Loading && ( - {[...new Array(8).keys()].map((key) => ( + {Array.from(new Array(8).keys(), (key) => ( ) { if (typeof containerItem === 'string') { const folder: ISidebarFolder = { id: randomStr(), - content: [containerItem].concat(child), + content: [...[containerItem], ...child], }; newItems.push(folder); return; } newItems.push({ ...containerItem.folder, - content: containerItem.folder.content.concat(child), + content: [...containerItem.folder.content, ...child], }); return; } diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx index 6d710f8b5..82ac8d739 100644 --- a/src/app/pages/client/space/Space.tsx +++ b/src/app/pages/client/space/Space.tsx @@ -466,7 +466,7 @@ export function Space() { // As a subspace can be in multiple spaces, // only return true if all parent spaces are closed. - const allClosed = !Array.from(parentParentIds).some( + const allClosed = ![...parentParentIds].some( (id) => !getInClosedCategories(spaceId, id, parentId, visited) ); visited.delete(categoryId); @@ -498,7 +498,7 @@ export function Space() { return false; } - return Array.from(childIds).some((id) => getContainsShowRoom(id, visited)); + return [...childIds].some((id) => getContainsShowRoom(id, visited)); }, [roomToUnread, selectedRoomId, roomToChildren] ); @@ -522,9 +522,7 @@ export function Space() { return false; } - const allCollapsed = !Array.from(parentIds).some( - (id) => !getInClosedCategories(spaceId, id, roomId) - ); + const allCollapsed = ![...parentIds].some((id) => !getInClosedCategories(spaceId, id, roomId)); ancestorsCollapsedCache.current.set(categoryId, allCollapsed); return allCollapsed; }; @@ -585,7 +583,10 @@ export function Space() { connectorStack = [{ aX: Math.round(renderDepth * PADDING_LEFT_DEPTH_OFFSET), aY: 0 }]; } - const lastConnector = connectorStack[connectorStack.length - 1]; + const lastConnector = connectorStack.at(-1) ?? { + aX: Math.round(renderDepth * PADDING_LEFT_DEPTH_OFFSET), + aY: 0, + }; // aX: numeric x where the vertical connector starts // aY: end of parent (already numeric) diff --git a/src/app/plugins/bad-words.ts b/src/app/plugins/bad-words.ts index 74fcaddb7..65c13ec02 100644 --- a/src/app/plugins/bad-words.ts +++ b/src/app/plugins/bad-words.ts @@ -3,9 +3,10 @@ import { sanitizeForRegex } from '$utils/regex'; const additionalBadWords: string[] = ['torture', 't0rture']; -const fullBadWordList = additionalBadWords.concat( - badWords.array.filter((word) => !additionalBadWords.includes(word)) -); +const fullBadWordList = [ + ...additionalBadWords, + ...badWords.array.filter((word) => !additionalBadWords.includes(word)), +]; export const BAD_WORDS_REGEX = new RegExp( `(\\b|_)(${fullBadWordList.map((word) => sanitizeForRegex(word)).join('|')})(\\b|_)`, diff --git a/src/app/plugins/call/CallEmbed.ts b/src/app/plugins/call/CallEmbed.ts index f746e5969..124abc8d2 100644 --- a/src/app/plugins/call/CallEmbed.ts +++ b/src/app/plugins/call/CallEmbed.ts @@ -234,7 +234,7 @@ export class CallEmbed { this.mx.getRooms().forEach((room) => { // Timelines are most recent last const events = room.getLiveTimeline()?.getEvents() || []; - const roomEvent = events[events.length - 1]; + const roomEvent = events.at(-1); if (!roomEvent) return; // force later code to think the room is fresh this.readUpToMap[room.roomId] = roomEvent.getId()!; }); @@ -360,7 +360,7 @@ export class CallEmbed { // Timelines are most recent last, so reverse the order and limit ourselves to 100 events // to avoid overusing the CPU. const timeline = room.getLiveTimeline(); - const events = [...timeline.getEvents()].reverse().slice(0, 100); + const events = timeline.getEvents().toReversed().slice(0, 100); function isRelevantTimelineEvent(timelineEvent: MatrixEvent): boolean { return timelineEvent.getId() === upToEventId || timelineEvent.getId() === ev.getId(); } diff --git a/src/app/plugins/call/CallWidgetDriver.ts b/src/app/plugins/call/CallWidgetDriver.ts index a53a7dca6..a75818fce 100644 --- a/src/app/plugins/call/CallWidgetDriver.ts +++ b/src/app/plugins/call/CallWidgetDriver.ts @@ -53,7 +53,7 @@ export class CallWidgetDriver extends WidgetDriver { } public async validateCapabilities(requested: Set): Promise> { - const allow = Array.from(requested).filter((cap) => this.allowedCapabilities.has(cap)); + const allow = [...requested].filter((cap) => this.allowedCapabilities.has(cap)); return new Set(allow); } diff --git a/src/app/plugins/custom-emoji/ImagePack.ts b/src/app/plugins/custom-emoji/ImagePack.ts index 127b558ba..58e5227c1 100644 --- a/src/app/plugins/custom-emoji/ImagePack.ts +++ b/src/app/plugins/custom-emoji/ImagePack.ts @@ -53,7 +53,7 @@ export class ImagePack { return this.stickerMemo; } - const images = Array.from(this.images.collection.values()).filter((image) => { + const images = [...this.images.collection.values()].filter((image) => { const usg = image.usage ?? this.meta.usage; return usg.includes(usage); }); diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index c1ac6c395..051e0d95e 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -498,7 +498,7 @@ export const getReactCustomHtmlParser = ( return undefined; } - const content = children.find((child) => !(child instanceof DOMText)) + const content = children.some((child) => !(child instanceof DOMText)) ? undefined : children.map((c) => (c instanceof DOMText ? c.data : '')).join(); diff --git a/src/app/plugins/text-area/Operations.ts b/src/app/plugins/text-area/Operations.ts index a465ece52..2630eefdf 100644 --- a/src/app/plugins/text-area/Operations.ts +++ b/src/app/plugins/text-area/Operations.ts @@ -1,7 +1,7 @@ import { type Cursor } from './Cursor'; -export interface Operations { +export type Operations = { select(cursor: Cursor): void; deselect(cursor: Cursor): void; insert(cursor: Cursor, text: string): Cursor; -} +}; diff --git a/src/app/plugins/text-area/TextUtils.ts b/src/app/plugins/text-area/TextUtils.ts index 43d05837f..b599a01f3 100644 --- a/src/app/plugins/text-area/TextUtils.ts +++ b/src/app/plugins/text-area/TextUtils.ts @@ -1,5 +1,5 @@ export class TextUtils { static multiline(str: string) { - return str.indexOf('\n') !== -1; + return str.includes('\n'); } } diff --git a/src/app/plugins/utils.ts b/src/app/plugins/utils.ts index c227a7e02..00f4609c6 100644 --- a/src/app/plugins/utils.ts +++ b/src/app/plugins/utils.ts @@ -13,7 +13,7 @@ export const getEmoticonSearchStr: SearchItemStrGetter const names = [shortcode, item.label]; if (Array.isArray(item.shortcodes)) { - return names.concat(item.shortcodes); + return [...names, ...item.shortcodes]; } return names; }; diff --git a/src/app/plugins/via-servers.ts b/src/app/plugins/via-servers.ts index 8e7c44c3b..404c0cdf2 100644 --- a/src/app/plugins/via-servers.ts +++ b/src/app/plugins/via-servers.ts @@ -69,5 +69,5 @@ export const getViaServers = (room: Room): string[] => { if (mostPop3.includes(via[0])) { mostPop3.splice(mostPop3.indexOf(via[0]), 1); } - return via.concat(mostPop3.slice(0, 2)); + return [...via, ...mostPop3.slice(0, 2)]; }; diff --git a/src/app/plugins/voice-recorder-kit/useVoiceRecorder.ts b/src/app/plugins/voice-recorder-kit/useVoiceRecorder.ts index e623c1b17..222cc491c 100644 --- a/src/app/plugins/voice-recorder-kit/useVoiceRecorder.ts +++ b/src/app/plugins/voice-recorder-kit/useVoiceRecorder.ts @@ -13,6 +13,8 @@ const WAVEFORM_POINT_COUNT = 100; let sharedAudioContext: AudioContext | null = null; +const createSilenceLevels = (count: number): number[] => Array(count).fill(0.15); + function getSharedAudioContext(): AudioContext { if (!sharedAudioContext || sharedAudioContext.state === 'closed') { sharedAudioContext = new AudioContext(); @@ -22,7 +24,7 @@ function getSharedAudioContext(): AudioContext { // downsample an array of samples to a target count by averaging blocks of samples together function downsampleWaveform(samples: number[], targetCount: number): number[] { - if (samples.length === 0) return Array.from({ length: targetCount }, () => 0.15); + if (samples.length === 0) return createSilenceLevels(targetCount); if (samples.length <= targetCount) { const step = (samples.length - 1) / (targetCount - 1); return Array.from({ length: targetCount }, (_, i) => { @@ -60,9 +62,7 @@ export function useVoiceRecorder(options: UseVoiceRecorderOptions = {}): UseVoic const [isPlaying, setIsPlaying] = useState(false); const [isPaused, setIsPaused] = useState(false); const [seconds, setSeconds] = useState(0); - const [levels, setLevels] = useState(() => - Array.from({ length: BAR_COUNT }, () => 0.15) - ); + const [levels, setLevels] = useState(() => createSilenceLevels(BAR_COUNT)); const [error, setError] = useState(null); const [audioUrl, setAudioUrl] = useState(null); const [audioFile, setAudioFile] = useState(null); @@ -460,7 +460,7 @@ export function useVoiceRecorder(options: UseVoiceRecorderOptions = {}): UseVoic audioContextRef.current.suspend().catch(() => {}); } - setLevels(Array.from({ length: BAR_COUNT }, () => 0.15)); + setLevels(createSilenceLevels(BAR_COUNT)); } catch { setError('Error pausing recording'); } @@ -831,7 +831,7 @@ export function useVoiceRecorder(options: UseVoiceRecorderOptions = {}): UseVoic setSeconds(0); pausedTimeRef.current = 0; startTimeRef.current = null; - setLevels(Array.from({ length: BAR_COUNT }, () => 0.15)); + setLevels(createSilenceLevels(BAR_COUNT)); previousChunksRef.current = []; chunksRef.current = []; waveformSamplesRef.current = []; @@ -873,7 +873,7 @@ export function useVoiceRecorder(options: UseVoiceRecorderOptions = {}): UseVoic setSeconds(0); pausedTimeRef.current = 0; startTimeRef.current = null; - setLevels(Array.from({ length: BAR_COUNT }, () => 0.15)); + setLevels(createSilenceLevels(BAR_COUNT)); previousChunksRef.current = []; chunksRef.current = []; isResumingRef.current = false; diff --git a/src/app/state/closedLobbyCategories.ts b/src/app/state/closedLobbyCategories.ts index 6e1b2325e..195706443 100644 --- a/src/app/state/closedLobbyCategories.ts +++ b/src/app/state/closedLobbyCategories.ts @@ -34,7 +34,7 @@ export const makeClosedLobbyCategoriesAtom = (userId: string): ClosedLobbyCatego return new Set(arrayValue); }, (key, value) => { - const arrayValue = Array.from(value); + const arrayValue = [...value]; setLocalStorageItem(key, arrayValue); } ); diff --git a/src/app/state/closedNavCategories.ts b/src/app/state/closedNavCategories.ts index 4126d6e73..9ba711b8b 100644 --- a/src/app/state/closedNavCategories.ts +++ b/src/app/state/closedNavCategories.ts @@ -34,7 +34,7 @@ export const makeClosedNavCategoriesAtom = (userId: string): ClosedNavCategories return new Set(arrayValue); }, (key, value) => { - const arrayValue = Array.from(value); + const arrayValue = [...value]; setLocalStorageItem(key, arrayValue); } ); diff --git a/src/app/state/mediaVolume.ts b/src/app/state/mediaVolume.ts new file mode 100644 index 000000000..83372b04a --- /dev/null +++ b/src/app/state/mediaVolume.ts @@ -0,0 +1,21 @@ +/** + * Centralized access to the persisted media volume preference. + * + * Plain functions rather than a Jotai atom because the value is applied + * directly to DOM element refs, not read reactively in JSX. + */ + +const MEDIA_VOLUME_KEY = 'mediaVolume'; + +/** Returns the persisted volume (0–1), or undefined if never set. */ +export const getMediaVolume = (): number | undefined => { + const stored = localStorage.getItem(MEDIA_VOLUME_KEY); + if (stored === null) return undefined; + const parsed = parseFloat(stored); + return Number.isNaN(parsed) ? undefined : parsed; +}; + +/** Persist the current volume (0–1). */ +export const setMediaVolume = (volume: number): void => { + localStorage.setItem(MEDIA_VOLUME_KEY, String(volume)); +}; diff --git a/src/app/state/openedSidebarFolder.ts b/src/app/state/openedSidebarFolder.ts index 837335064..8c104b71b 100644 --- a/src/app/state/openedSidebarFolder.ts +++ b/src/app/state/openedSidebarFolder.ts @@ -34,7 +34,7 @@ export const makeOpenedSidebarFolderAtom = (userId: string): OpenedSidebarFolder return new Set(arrayValue); }, (key, value) => { - const arrayValue = Array.from(value); + const arrayValue = [...value]; setLocalStorageItem(key, arrayValue); } ); diff --git a/src/app/state/room-list/utils.ts b/src/app/state/room-list/utils.ts index aad1ecf44..9acd27a25 100644 --- a/src/app/state/room-list/utils.ts +++ b/src/app/state/room-list/utils.ts @@ -22,7 +22,7 @@ export const useBindRoomsWithMembershipsAtom = ( useEffect(() => { const satisfyMembership = (room: Room): boolean => - !!memberships.find((membership) => membership === room.getMyMembership()); + memberships.some((membership) => membership === room.getMyMembership()); setRoomsAtom({ type: 'INITIALIZE', rooms: mx diff --git a/src/app/state/sentryStorage.ts b/src/app/state/sentryStorage.ts new file mode 100644 index 000000000..223c84bd8 --- /dev/null +++ b/src/app/state/sentryStorage.ts @@ -0,0 +1,28 @@ +/** + * Centralized access to the Sentry opt-in preference stored in localStorage. + * + * These must be plain functions because src/instrument.ts reads them + * synchronously at module load time, before React and Jotai mount. + */ + +export const SENTRY_ENABLED_KEY = 'sable_sentry_enabled'; +export const SENTRY_REPLAY_ENABLED_KEY = 'sable_sentry_replay_enabled'; + +export const getSentryEnabled = (): boolean => localStorage.getItem(SENTRY_ENABLED_KEY) === 'true'; + +export const isSentryDecided = (): boolean => localStorage.getItem(SENTRY_ENABLED_KEY) !== null; + +export const setSentryEnabled = (enabled: boolean): void => { + localStorage.setItem(SENTRY_ENABLED_KEY, String(enabled)); +}; + +export const getSentryReplayEnabled = (): boolean => + localStorage.getItem(SENTRY_REPLAY_ENABLED_KEY) === 'true'; + +export const setSentryReplayEnabled = (enabled: boolean): void => { + if (enabled) { + localStorage.setItem(SENTRY_REPLAY_ENABLED_KEY, 'true'); + } else { + localStorage.removeItem(SENTRY_REPLAY_ENABLED_KEY); + } +}; diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index cfa533866..e74948226 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -23,7 +23,7 @@ export enum CaptionPosition { } export type JumboEmojiSize = 'none' | 'extraSmall' | 'small' | 'normal' | 'large' | 'extraLarge'; -export interface Settings { +export type Settings = { themeId?: string; useSystemTheme: boolean; lightThemeId?: string; @@ -111,7 +111,7 @@ export interface Settings { // furry stuff renderAnimals: boolean; -} +}; const defaultSettings: Settings = { themeId: undefined, diff --git a/src/app/state/spaceRooms.ts b/src/app/state/spaceRooms.ts index 572fade3e..ea6d1c486 100644 --- a/src/app/state/spaceRooms.ts +++ b/src/app/state/spaceRooms.ts @@ -15,7 +15,7 @@ const baseSpaceRoomsAtom = atomWithLocalStorage>( return new Set(arrayValue); }, (key, value) => { - const arrayValue = Array.from(value); + const arrayValue = [...value]; setLocalStorageItem(key, arrayValue); } ); @@ -36,7 +36,7 @@ export const spaceRoomsAtom = atom, [SpaceRoomsAction], undefined>( const current = get(baseSpaceRoomsAtom); const { type, roomIds } = action; - if (type === 'DELETE' && roomIds.find((roomId) => current.has(roomId))) { + if (type === 'DELETE' && roomIds.some((roomId) => current.has(roomId))) { set( baseSpaceRoomsAtom, produce(current, (draft) => { diff --git a/src/app/utils/AsyncSearch.ts b/src/app/utils/AsyncSearch.ts index c799c60bb..b6cd24f75 100644 --- a/src/app/utils/AsyncSearch.ts +++ b/src/app/utils/AsyncSearch.ts @@ -78,7 +78,7 @@ export const AsyncSearch = ( if (findingCount !== currentFindingCount) onResult(resultList, query); searchIndex += 1; - sessionScheduleId = globalThis.setTimeout(() => find(query, thisSessionTimestamp), 1); + sessionScheduleId = globalThis.setTimeout(find, 1, query, thisSessionTimestamp); return; } } diff --git a/src/app/utils/MegolmExportEncryption.ts b/src/app/utils/MegolmExportEncryption.ts index 96250e5bd..b9e499360 100644 --- a/src/app/utils/MegolmExportEncryption.ts +++ b/src/app/utils/MegolmExportEncryption.ts @@ -43,7 +43,7 @@ function toArrayBufferView(data: Uint8Array): Uint8Array { function encodeBase64(uint8Array: Uint8Array): string { // Misinterpt the Uint8Array as Latin-1. // window.btoa expects a unicode string with codepoints in the range 0-255. - const latin1String = String.fromCodePoint.apply(null, Array.from(uint8Array)); + const latin1String = String.fromCodePoint(...[...uint8Array]); // Use the builtin base64 encoder. return globalThis.btoa(latin1String); } diff --git a/src/app/utils/abbreviations.ts b/src/app/utils/abbreviations.ts index e6dfcfa3e..718db9d93 100644 --- a/src/app/utils/abbreviations.ts +++ b/src/app/utils/abbreviations.ts @@ -44,7 +44,7 @@ export const splitByAbbreviations = (text: string, abbrMap: Map) const segments: TextSegment[] = []; let lastIndex = 0; - Array.from(text.matchAll(pattern)).forEach((match) => { + [...text.matchAll(pattern)].forEach((match) => { const matchIndex = match.index; if (matchIndex > lastIndex) { segments.push({ id: `txt-${segments.length}`, text: text.slice(lastIndex, matchIndex) }); diff --git a/src/app/utils/debugLogger.ts b/src/app/utils/debugLogger.ts index 1e1c7e74b..301dfa785 100644 --- a/src/app/utils/debugLogger.ts +++ b/src/app/utils/debugLogger.ts @@ -20,14 +20,14 @@ export type LogCategory = | 'error' | 'general'; -export interface LogEntry { +export type LogEntry = { timestamp: number; level: LogLevel; category: LogCategory; namespace: string; message: string; data?: unknown; -} +}; type LogListener = (entry: LogEntry) => void; @@ -136,7 +136,7 @@ class DebugLoggerService { } else { this.disabledBreadcrumbCategories.add(category); } - const disabledArray = Array.from(this.disabledBreadcrumbCategories); + const disabledArray = [...this.disabledBreadcrumbCategories]; if (disabledArray.length > 0) { localStorage.setItem(BREADCRUMB_DISABLED_KEY, JSON.stringify(disabledArray)); } else { diff --git a/src/app/utils/delayedEvents.ts b/src/app/utils/delayedEvents.ts index bbf6245f4..e893a3f27 100644 --- a/src/app/utils/delayedEvents.ts +++ b/src/app/utils/delayedEvents.ts @@ -10,9 +10,9 @@ import { } from '$types/matrix-sdk'; // Grab types needed for encryption -interface EncryptableBackend { +type EncryptableBackend = { encryptEvent(event: MatrixEvent, room: Room): Promise; -} +}; export async function supportsDelayedEvents(mx: MatrixClient): Promise { try { diff --git a/src/app/utils/featureCheck.ts b/src/app/utils/featureCheck.ts index a9474c317..e5f2dcaed 100644 --- a/src/app/utils/featureCheck.ts +++ b/src/app/utils/featureCheck.ts @@ -1,5 +1,5 @@ export const checkIndexedDBSupport = async (): Promise => { - const ts = new Date().getTime(); + const ts = Date.now(); const dbName = `checkIndexedDBSupport-${ts}`; return new Promise((resolve) => { let db; diff --git a/src/app/utils/keyboard.ts b/src/app/utils/keyboard.ts index 5933deeef..861d60156 100644 --- a/src/app/utils/keyboard.ts +++ b/src/app/utils/keyboard.ts @@ -1,7 +1,7 @@ import { isKeyHotkey } from 'is-hotkey'; import { type KeyboardEventHandler } from 'react'; -export interface KeyboardEventLike { +export type KeyboardEventLike = { key: string; which: number; altKey: boolean; @@ -9,7 +9,7 @@ export interface KeyboardEventLike { metaKey: boolean; shiftKey: boolean; preventDefault(): void; -} +}; export const onTabPress = (evt: KeyboardEventLike, callback: () => void) => { if (isKeyHotkey('tab', evt)) { diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index f7562ce29..b1d952931 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -279,7 +279,7 @@ export const addRoomIdToMDirect = async ( }); const roomIds = userIdToRoomIds[userId] || []; - if (roomIds.indexOf(roomId) === -1) { + if (!roomIds.includes(roomId)) { roomIds.push(roomId); } userIdToRoomIds[userId] = roomIds; @@ -415,7 +415,7 @@ export const toggleReaction = ( ); const allReactions = relations?.getSortedAnnotationsByKey() ?? []; const [, reactionsSet] = allReactions.find(([k]: [string, any]) => k === key) ?? []; - const reactions: MatrixEvent[] = reactionsSet ? Array.from(reactionsSet) : []; + const reactions: MatrixEvent[] = reactionsSet ? [...reactionsSet] : []; const myReaction = reactions.find(factoryEventSentBy(mx.getUserId()!)); if (myReaction && !!(myReaction as any)?.isRelation()) { diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index 4cc6a1af7..64192c2f3 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -176,7 +176,7 @@ export const getRoomToParents = (mx: MatrixClient): RoomToParents => { export const getOrphanParents = (roomToParents: RoomToParents, roomId: string): string[] => { const parents = getAllParents(roomToParents, roomId); - return Array.from(parents).filter((parentRoomId) => !roomToParents.has(parentRoomId)); + return [...parents].filter((parentRoomId) => !roomToParents.has(parentRoomId)); }; export const isMutedRule = (rule: IPushRule) => @@ -264,7 +264,7 @@ export const roomHaveUnread = (mx: MatrixClient, room: Room) => { return false; } - const latestEvent = liveEvents[liveEvents.length - 1]; + const latestEvent = liveEvents.at(-1); if (latestEvent?.getSender() === userId) { return false; @@ -316,8 +316,8 @@ export const getUnreadInfo = (room: Room, options?: UnreadInfoOptions): UnreadIn const liveEvents = room.getLiveTimeline().getEvents(); // Exclude the user's own messages: own sent events are always "read" (hasUserReadEvent // returns true for them), which would cause the clamp to fire incorrectly. - const latestNotification = [...liveEvents] - .reverse() + const latestNotification = liveEvents + .toReversed() .find( (event) => !event.isSending() && @@ -538,7 +538,7 @@ export const getMemberSearchStr = ( mxIdToName: (mxId: string) => string ): string[] => [ member.rawDisplayName === member.userId ? mxIdToName(member.userId) : member.rawDisplayName, - query.startsWith('@') || query.indexOf(':') > -1 ? member.userId : mxIdToName(member.userId), + query.startsWith('@') || query.includes(':') ? member.userId : mxIdToName(member.userId), ]; export const getMemberAvatarMxc = (room: Room, userId: string): string | undefined => { @@ -745,7 +745,7 @@ export const guessPerfectParent = ( } }); - return Array.from(specialUsers); + return [...specialUsers]; }; let perfectParent: string | undefined; diff --git a/src/client/initMatrix.ts b/src/client/initMatrix.ts index 67dc1ee43..34c4acece 100644 --- a/src/client/initMatrix.ts +++ b/src/client/initMatrix.ts @@ -230,7 +230,7 @@ export const clearMismatchedStores = async (): Promise => { allDbs.map(async ({ name }) => { if (!name) return; - const containsKnownUser = Array.from(knownUserIds).some((uid) => name.includes(uid)); + const containsKnownUser = [...knownUserIds].some((uid) => name.includes(uid)); const looksLikeUserDb = name.includes('@'); if (looksLikeUserDb && !containsKnownUser && !knownStoreNames.has(name)) { log.warn(`clearMismatchedStores: "${name}" has unknown user — deleting`); diff --git a/src/client/slidingSync.test.ts b/src/client/slidingSync.test.ts index bd0643e5d..4e5515a82 100644 --- a/src/client/slidingSync.test.ts +++ b/src/client/slidingSync.test.ts @@ -15,6 +15,7 @@ * instant (matching Element Web's model). */ import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { type MatrixClient } from '$types/matrix-sdk'; import { SlidingSyncManager, type SlidingSyncConfig } from './slidingSync'; // ── vi.hoisted mocks ───────────────────────────────────────────────────────── @@ -75,7 +76,7 @@ function makeMockMx(overrides: Record = {}) { off: vi.fn(), removeListener: vi.fn(), ...overrides, - } as unknown as import('$types/matrix-sdk').MatrixClient; + } as unknown as MatrixClient; } function makeManager(mx: ReturnType): SlidingSyncManager { diff --git a/src/client/slidingSync.ts b/src/client/slidingSync.ts index 2e11750ac..af0d49179 100644 --- a/src/client/slidingSync.ts +++ b/src/client/slidingSync.ts @@ -305,7 +305,7 @@ export class SlidingSyncManager { const defaultSubscription = buildEncryptedSubscription(roomTimelineLimit); const lists = buildLists(listPageSize, includeInviteList); - this.listKeys = Array.from(lists.keys()); + this.listKeys = [...lists.keys()]; this.slidingSync = new SlidingSync(proxyBaseUrl, lists, defaultSubscription, mx, pollTimeoutMs); // Register the presence extension so m.presence events from the server are fed diff --git a/src/sw.ts b/src/sw.ts index bd09cd8d3..682491c19 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -133,7 +133,7 @@ async function cleanupDeadClients() { const activeClients = await self.clients.matchAll(); const activeIds = new Set(activeClients.map((c) => c.id)); - Array.from(sessions.keys()).forEach((id) => { + [...sessions.keys()].forEach((id) => { if (!activeIds.has(id)) { sessions.delete(id); clientToResolve.delete(id); @@ -370,7 +370,7 @@ async function requestDecryptionFromClient( const eventId = rawEvent.event_id as string; // Chain clients sequentially using reduce to avoid await-in-loop and for-of. - return Array.from(windowClients).reduce( + return [...windowClients].reduce( async (prevPromise, client) => { const prev = await prevPromise; if (prev?.success) return prev; diff --git a/vitest.config.ts b/vitest.config.ts index f5f2dabe6..497c539f9 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -33,6 +33,14 @@ export default defineConfig({ 'src/**/*.test.{ts,tsx}', 'src/**/*.spec.{ts,tsx}', ], + // Baseline locked at current coverage. Raise these thresholds as test + // coverage improves, never lower them. + thresholds: { + statements: 1.5, + branches: 1, + functions: 1.5, + lines: 1.5, + }, }, }, }); From a204b41014fe38728d3ac6eecc76abc170ab5bc7 Mon Sep 17 00:00:00 2001 From: hazre Date: Mon, 30 Mar 2026 00:46:23 +0200 Subject: [PATCH 07/11] chore: update packages and deal with vulnerabilities --- package.json | 34 +- pnpm-lock.yaml | 1249 ++++++++++++++++++++++++++----------------- pnpm-workspace.yaml | 23 +- 3 files changed, 789 insertions(+), 517 deletions(-) diff --git a/package.json b/package.json index 8074cbe1c..20fb1e7d7 100644 --- a/package.json +++ b/package.json @@ -36,27 +36,27 @@ "author": "7w1", "license": "AGPL-3.0-only", "dependencies": { - "@atlaskit/pragmatic-drag-and-drop": "^1.7.7", + "@atlaskit/pragmatic-drag-and-drop": "^1.7.9", "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^1.4.0", "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0", "@fontsource-variable/nunito": "5.2.7", "@fontsource/space-mono": "5.2.9", "@phosphor-icons/react": "^2.1.10", - "@sentry/react": "^10.43.0", - "@tanstack/react-query": "^5.90.21", - "@tanstack/react-query-devtools": "^5.91.3", - "@tanstack/react-virtual": "^3.13.19", + "@sentry/react": "^10.46.0", + "@tanstack/react-query": "^5.95.2", + "@tanstack/react-query-devtools": "^5.95.2", + "@tanstack/react-virtual": "^3.13.23", "@use-gesture/react": "10.3.1", - "@vanilla-extract/css": "^1.18.0", + "@vanilla-extract/css": "^1.20.1", "@vanilla-extract/recipes": "^0.5.7", - "@vanilla-extract/vite-plugin": "^5.2.1", + "@vanilla-extract/vite-plugin": "^5.2.2", "await-to-js": "^3.0.0", "badwords-list": "^2.0.1-4", "blurhash": "^2.0.5", "browser-encrypt-attachment": "^0.3.0", "chroma-js": "^3.2.0", "classnames": "^2.5.1", - "dayjs": "^1.11.19", + "dayjs": "^1.11.20", "domhandler": "^5.0.3", "emojibase": "^15.3.1", "emojibase-data": "^15.3.2", @@ -68,26 +68,26 @@ "framer-motion": "12.34.3", "html-dom-parser": "^5.1.8", "html-react-parser": "^4.2.10", - "i18next": "^25.8.13", + "i18next": "^25.10.10", "i18next-browser-languagedetector": "^8.2.1", "i18next-http-backend": "^2.7.3", "immer": "^9.0.21", "is-hotkey": "^0.2.0", - "jotai": "^2.18.0", + "jotai": "^2.19.0", "linkify-react": "^4.3.2", "linkifyjs": "^4.3.2", "matrix-js-sdk": "^38.4.0", "matrix-widget-api": "^1.16.1", - "pdfjs-dist": "^5.4.624", + "pdfjs-dist": "^5.5.207", "prismjs": "^1.30.0", "react": "^18.3.1", - "react-aria": "^3.46.0", + "react-aria": "^3.47.0", "react-blurhash": "^0.3.0", "react-colorful": "^5.6.1", "react-dom": "^18.3.1", "react-error-boundary": "^4.1.2", "react-google-recaptcha": "^2.1.0", - "react-i18next": "^16.5.4", + "react-i18next": "^16.6.6", "react-range": "^1.10.0", "react-router-dom": "^6.30.3", "sanitize-html": "^2.17.1", @@ -123,8 +123,8 @@ "@types/sanitize-html": "^2.16.0", "@types/ua-parser-js": "^0.7.39", "@vitejs/plugin-react": "^6.0.1", - "@vitest/coverage-v8": "^4.1.0", - "@vitest/ui": "^4.1.0", + "@vitest/coverage-v8": "^4.1.2", + "@vitest/ui": "^4.1.2", "buffer": "^6.0.3", "cloudflared": "^0.7.1", "eslint": "9.39.3", @@ -133,7 +133,7 @@ "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-prettier": "5.5.5", "globals": "17.3.0", - "jsdom": "^29.0.0", + "jsdom": "^29.0.1", "knip": "5.85.0", "prettier": "3.8.1", "typescript": "^5.9.3", @@ -143,7 +143,7 @@ "vite-plugin-static-copy": "^4.0.0", "vite-plugin-svgr": "4.5.0", "vite-plugin-top-level-await": "^1.6.0", - "vitest": "^4.1.0", + "vitest": "^4.1.2", "wrangler": "^4.78.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 935490119..0e74c4204 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,21 +5,17 @@ settings: excludeLinksFromLockfile: false overrides: - brace-expansion: '>=1.1.12' - esbuild: '>=0.25.0' - lodash: '>=4.17.23' - minimatch: '>=10.2.3' - rollup: '>=4.59.0' - serialize-javascript: '>=7.0.3' - flatted: '>=3.4.2' - undici: '>=7.24.0' + serialize-javascript: '>=7.0.5' + picomatch: '>=4.0.4' + smol-toml: '>=1.6.1' + yaml: '>=2.8.3' importers: .: dependencies: '@atlaskit/pragmatic-drag-and-drop': - specifier: ^1.7.7 + specifier: ^1.7.9 version: 1.7.9 '@atlaskit/pragmatic-drag-and-drop-auto-scroll': specifier: ^1.4.0 @@ -37,29 +33,29 @@ importers: specifier: ^2.1.10 version: 2.1.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@sentry/react': - specifier: ^10.43.0 - version: 10.43.0(react@18.3.1) + specifier: ^10.46.0 + version: 10.46.0(react@18.3.1) '@tanstack/react-query': - specifier: ^5.90.21 - version: 5.90.21(react@18.3.1) + specifier: ^5.95.2 + version: 5.95.2(react@18.3.1) '@tanstack/react-query-devtools': - specifier: ^5.91.3 - version: 5.91.3(@tanstack/react-query@5.90.21(react@18.3.1))(react@18.3.1) + specifier: ^5.95.2 + version: 5.95.2(@tanstack/react-query@5.95.2(react@18.3.1))(react@18.3.1) '@tanstack/react-virtual': - specifier: ^3.13.19 - version: 3.13.21(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^3.13.23 + version: 3.13.23(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@use-gesture/react': specifier: 10.3.1 version: 10.3.1(react@18.3.1) '@vanilla-extract/css': - specifier: ^1.18.0 - version: 1.18.0 + specifier: ^1.20.1 + version: 1.20.1 '@vanilla-extract/recipes': specifier: ^0.5.7 - version: 0.5.7(@vanilla-extract/css@1.18.0) + version: 0.5.7(@vanilla-extract/css@1.20.1) '@vanilla-extract/vite-plugin': - specifier: ^5.2.1 - version: 5.2.1(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(yaml@2.8.2) + specifier: ^5.2.2 + version: 5.2.2(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) await-to-js: specifier: ^3.0.0 version: 3.0.0 @@ -79,8 +75,8 @@ importers: specifier: ^2.5.1 version: 2.5.1 dayjs: - specifier: ^1.11.19 - version: 1.11.19 + specifier: ^1.11.20 + version: 1.11.20 domhandler: specifier: ^5.0.3 version: 5.0.3 @@ -104,7 +100,7 @@ importers: version: 10.3.1(prop-types@15.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) folds: specifier: ^2.6.2 - version: 2.6.2(@vanilla-extract/css@1.18.0)(@vanilla-extract/recipes@0.5.7(@vanilla-extract/css@1.18.0))(classnames@2.5.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.6.2(@vanilla-extract/css@1.20.1)(@vanilla-extract/recipes@0.5.7(@vanilla-extract/css@1.20.1))(classnames@2.5.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) framer-motion: specifier: 12.34.3 version: 12.34.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -115,8 +111,8 @@ importers: specifier: ^4.2.10 version: 4.2.10(react@18.3.1) i18next: - specifier: ^25.8.13 - version: 25.8.17(typescript@5.9.3) + specifier: ^25.10.10 + version: 25.10.10(typescript@5.9.3) i18next-browser-languagedetector: specifier: ^8.2.1 version: 8.2.1 @@ -130,8 +126,8 @@ importers: specifier: ^0.2.0 version: 0.2.0 jotai: - specifier: ^2.18.0 - version: 2.18.1(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@18.3.28)(react@18.3.1) + specifier: ^2.19.0 + version: 2.19.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@18.3.28)(react@18.3.1) linkify-react: specifier: ^4.3.2 version: 4.3.2(linkifyjs@4.3.2)(react@18.3.1) @@ -145,7 +141,7 @@ importers: specifier: ^1.16.1 version: 1.17.0 pdfjs-dist: - specifier: ^5.4.624 + specifier: ^5.5.207 version: 5.5.207 prismjs: specifier: ^1.30.0 @@ -154,7 +150,7 @@ importers: specifier: ^18.3.1 version: 18.3.1 react-aria: - specifier: ^3.46.0 + specifier: ^3.47.0 version: 3.47.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-blurhash: specifier: ^0.3.0 @@ -172,8 +168,8 @@ importers: specifier: ^2.1.0 version: 2.1.0(react@18.3.1) react-i18next: - specifier: ^16.5.4 - version: 16.5.7(i18next@25.8.17(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + specifier: ^16.6.6 + version: 16.6.6(i18next@25.10.10(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) react-range: specifier: ^1.10.0 version: 1.10.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -207,13 +203,13 @@ importers: devDependencies: '@cloudflare/vite-plugin': specifier: ^1.30.2 - version: 1.30.2(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workerd@1.20260317.1)(wrangler@4.78.0) + version: 1.30.2(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1))(workerd@1.20260317.1)(wrangler@4.78.0) '@e18e/eslint-plugin': specifier: ^0.3.0 version: 0.3.0(eslint@9.39.3(jiti@2.6.1)) '@esbuild-plugins/node-globals-polyfill': specifier: ^0.2.3 - version: 0.2.3(esbuild@0.27.3) + version: 0.2.3(esbuild@0.27.4) '@eslint/compat': specifier: 2.0.2 version: 2.0.2(eslint@9.39.3(jiti@2.6.1)) @@ -222,16 +218,16 @@ importers: version: 9.39.3 '@rollup/plugin-inject': specifier: ^5.0.5 - version: 5.0.5(rollup@4.59.0) + version: 5.0.5(rollup@4.60.0) '@rollup/plugin-wasm': specifier: ^6.2.2 - version: 6.2.2(rollup@4.59.0) + version: 6.2.2(rollup@4.60.0) '@sableclient/sable-call-embedded': specifier: v1.1.4 version: 1.1.4 '@sentry/vite-plugin': specifier: ^5.1.1 - version: 5.1.1(rollup@4.59.0) + version: 5.1.1(rollup@4.60.0) '@testing-library/jest-dom': specifier: ^6.9.1 version: 6.9.1 @@ -273,13 +269,13 @@ importers: version: 0.7.39 '@vitejs/plugin-react': specifier: ^6.0.1 - version: 6.0.1(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + version: 6.0.1(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) '@vitest/coverage-v8': - specifier: ^4.1.0 - version: 4.1.0(vitest@4.1.0) + specifier: ^4.1.2 + version: 4.1.2(vitest@4.1.2) '@vitest/ui': - specifier: ^4.1.0 - version: 4.1.0(vitest@4.1.0) + specifier: ^4.1.2 + version: 4.1.2(vitest@4.1.2) buffer: specifier: ^6.0.3 version: 6.0.3 @@ -305,8 +301,8 @@ importers: specifier: 17.3.0 version: 17.3.0 jsdom: - specifier: ^29.0.0 - version: 29.0.0 + specifier: ^29.0.1 + version: 29.0.1 knip: specifier: 5.85.0 version: 5.85.0(@types/node@24.10.13)(typescript@5.9.3) @@ -318,25 +314,25 @@ importers: version: 5.9.3 vite: specifier: ^8.0.3 - version: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + version: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) vite-plugin-compression2: specifier: 2.5.3 - version: 2.5.3(rollup@4.59.0) + version: 2.5.3(rollup@4.60.0) vite-plugin-pwa: specifier: ^1.2.0 - version: 1.2.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) + version: 1.2.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) vite-plugin-static-copy: specifier: ^4.0.0 - version: 4.0.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + version: 4.0.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) vite-plugin-svgr: specifier: 4.5.0 - version: 4.5.0(rollup@4.59.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + version: 4.5.0(rollup@4.60.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) vite-plugin-top-level-await: specifier: ^1.6.0 - version: 1.6.0(@swc/helpers@0.5.19)(rollup@4.59.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + version: 1.6.0(@swc/helpers@0.5.19)(rollup@4.60.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) vitest: - specifier: ^4.1.0 - version: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + specifier: ^4.1.2 + version: 4.1.2(@types/node@24.10.13)(@vitest/ui@4.1.2)(jsdom@29.0.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) wrangler: specifier: ^4.78.0 version: 4.78.0 @@ -346,8 +342,8 @@ packages: '@adobe/css-tools@4.4.4': resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} - '@apideck/better-ajv-errors@0.3.6': - resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} + '@apideck/better-ajv-errors@0.3.7': + resolution: {integrity: sha512-TajUJwGWbDwkCx/CZi7tRE8PVB7simCvKJfHUsSdvps+aTM/PDPP4gkLmKnc+x3CE//y9i/nj74GqdL/hwk7Iw==} engines: {node: '>=10'} peerDependencies: ajv: '>=8' @@ -480,6 +476,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} engines: {node: '>=6.9.0'} @@ -1000,7 +1001,7 @@ packages: '@esbuild-plugins/node-globals-polyfill@0.2.3': resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} peerDependencies: - esbuild: '>=0.25.0' + esbuild: '*' '@esbuild/aix-ppc64@0.27.3': resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} @@ -1008,156 +1009,312 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.27.3': resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.27.3': resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.27.3': resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.27.3': resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.27.3': resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.27.3': resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.27.3': resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.27.3': resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.27.3': resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.27.3': resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.27.3': resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.27.3': resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.27.3': resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.27.3': resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.27.3': resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.27.3': resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.27.3': resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.27.3': resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.27.3': resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.27.3': resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.27.3': resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.27.3': resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.27.3': resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.27.3': resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.27.3': resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2330,7 +2487,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0 '@types/babel__core': ^7.1.9 - rollup: '>=4.59.0' + rollup: ^1.20.0||^2.0.0 peerDependenciesMeta: '@types/babel__core': optional: true @@ -2339,7 +2496,7 @@ packages: resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: '>=4.59.0' + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true @@ -2348,7 +2505,7 @@ packages: resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: '>=4.59.0' + rollup: ^2.78.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true @@ -2356,13 +2513,13 @@ packages: '@rollup/plugin-replace@2.4.2': resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} peerDependencies: - rollup: '>=4.59.0' + rollup: ^1.20.0 || ^2.0.0 '@rollup/plugin-terser@0.4.4': resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: '>=4.59.0' + rollup: ^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true @@ -2371,7 +2528,7 @@ packages: resolution: {integrity: sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: '>=4.59.0' + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true @@ -2380,7 +2537,7 @@ packages: resolution: {integrity: sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: '>=4.59.0' + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true @@ -2389,152 +2546,152 @@ packages: resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} peerDependencies: - rollup: '>=4.59.0' + rollup: ^1.20.0||^2.0.0 '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: '>=4.59.0' + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.59.0': - resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + '@rollup/rollup-android-arm-eabi@4.60.0': + resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.59.0': - resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + '@rollup/rollup-android-arm64@4.60.0': + resolution: {integrity: sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.59.0': - resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + '@rollup/rollup-darwin-arm64@4.60.0': + resolution: {integrity: sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.59.0': - resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + '@rollup/rollup-darwin-x64@4.60.0': + resolution: {integrity: sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.59.0': - resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + '@rollup/rollup-freebsd-arm64@4.60.0': + resolution: {integrity: sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.59.0': - resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + '@rollup/rollup-freebsd-x64@4.60.0': + resolution: {integrity: sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + '@rollup/rollup-linux-arm-musleabihf@4.60.0': + resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.59.0': - resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + '@rollup/rollup-linux-arm64-gnu@4.60.0': + resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.59.0': - resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + '@rollup/rollup-linux-arm64-musl@4.60.0': + resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.59.0': - resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + '@rollup/rollup-linux-loong64-gnu@4.60.0': + resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.59.0': - resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + '@rollup/rollup-linux-loong64-musl@4.60.0': + resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.59.0': - resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + '@rollup/rollup-linux-ppc64-gnu@4.60.0': + resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.59.0': - resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + '@rollup/rollup-linux-ppc64-musl@4.60.0': + resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.59.0': - resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + '@rollup/rollup-linux-riscv64-gnu@4.60.0': + resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.59.0': - resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + '@rollup/rollup-linux-riscv64-musl@4.60.0': + resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.59.0': - resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + '@rollup/rollup-linux-s390x-gnu@4.60.0': + resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.59.0': - resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + '@rollup/rollup-linux-x64-gnu@4.60.0': + resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.59.0': - resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + '@rollup/rollup-linux-x64-musl@4.60.0': + resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.59.0': - resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + '@rollup/rollup-openbsd-x64@4.60.0': + resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.59.0': - resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + '@rollup/rollup-openharmony-arm64@4.60.0': + resolution: {integrity: sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.59.0': - resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + '@rollup/rollup-win32-arm64-msvc@4.60.0': + resolution: {integrity: sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.59.0': - resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + '@rollup/rollup-win32-ia32-msvc@4.60.0': + resolution: {integrity: sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.59.0': - resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + '@rollup/rollup-win32-x64-gnu@4.60.0': + resolution: {integrity: sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.59.0': - resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + '@rollup/rollup-win32-x64-msvc@4.60.0': + resolution: {integrity: sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==} cpu: [x64] os: [win32] @@ -2544,28 +2701,28 @@ packages: '@sableclient/sable-call-embedded@1.1.4': resolution: {integrity: sha512-XLRcbUPcn7i3QKZAPjIfUkUEXP0E4DOr0dyRoVCWMjHWj28kq+T7jeB2fRr5lB77olBwNHMjIuoTwrv02xiepQ==} - '@sentry-internal/browser-utils@10.43.0': - resolution: {integrity: sha512-8zYTnzhAPvNkVH1Irs62wl0J/c+0QcJ62TonKnzpSFUUD3V5qz8YDZbjIDGfxy+1EB9fO0sxtddKCzwTHF/MbQ==} + '@sentry-internal/browser-utils@10.46.0': + resolution: {integrity: sha512-WB1gBT9G13V02ekZ6NpUhoI1aGHV2eNfjEPthkU2bGBvFpQKnstwzjg7waIRGR7cu+YSW2Q6UI6aQLgBeOPD1g==} engines: {node: '>=18'} - '@sentry-internal/feedback@10.43.0': - resolution: {integrity: sha512-YoXuwluP6eOcQxTeTtaWb090++MrLyWOVsUTejzUQQ6LFL13Jwt+bDPF1kvBugMq4a7OHw/UNKQfd6//rZMn2g==} + '@sentry-internal/feedback@10.46.0': + resolution: {integrity: sha512-c4pI/z9nZCQXe9GYEw/hE/YTY9AxGBp8/wgKI+T8zylrN35SGHaXv63szzE1WbI8lacBY8lBF7rstq9bQVCaHw==} engines: {node: '>=18'} - '@sentry-internal/replay-canvas@10.43.0': - resolution: {integrity: sha512-ZIw1UNKOFXo1LbPCJPMAx9xv7D8TMZQusLDUgb6BsPQJj0igAuwd7KRGTkjjgnrwBp2O/sxcQFRhQhknWk7QPg==} + '@sentry-internal/replay-canvas@10.46.0': + resolution: {integrity: sha512-ub314MWUsekVCuoH0/HJbbimlI24SkV745UW2pj9xRbxOAEf1wjkmIzxKrMDbTgJGuEunug02XZVdJFJUzOcDw==} engines: {node: '>=18'} - '@sentry-internal/replay@10.43.0': - resolution: {integrity: sha512-khCXlGrlH1IU7P5zCEAJFestMeH97zDVCekj8OsNNDtN/1BmCJ46k6Xi0EqAUzdJgrOLJeLdoYdgtiIjovZ8Sg==} + '@sentry-internal/replay@10.46.0': + resolution: {integrity: sha512-JBsWeXG6bRbxBFK8GzWymWGOB9QE7Kl57BeF3jzgdHTuHSWZ2mRnAmb1K05T4LU+gVygk6yW0KmdC8Py9Qzg9A==} engines: {node: '>=18'} '@sentry/babel-plugin-component-annotate@5.1.1': resolution: {integrity: sha512-x2wEpBHwsTyTF2rWsLKJlzrRF1TTIGOfX+ngdE+Yd5DBkoS58HwQv824QOviPGQRla4/ypISqAXzjdDPL/zalg==} engines: {node: '>= 18'} - '@sentry/browser@10.43.0': - resolution: {integrity: sha512-2V3I3sXi3SMeiZpKixd9ztokSgK27cmvsD9J5oyOyjhGLTW/6QKCwHbKnluMgQMXq20nixQk5zN4wRjRUma3sg==} + '@sentry/browser@10.46.0': + resolution: {integrity: sha512-80DmGlTk5Z2/OxVOzLNxwolMyouuAYKqG8KUcoyintZqHbF6kO1RulI610HmyUt3OagKeBCqt9S7w0VIfCRL+Q==} engines: {node: '>=18'} '@sentry/bundler-plugin-core@5.1.1': @@ -2624,12 +2781,12 @@ packages: engines: {node: '>= 10'} hasBin: true - '@sentry/core@10.43.0': - resolution: {integrity: sha512-l0SszQAPiQGWl/ferw8GP3ALyHXiGiRKJaOvNmhGO+PrTQyZTZ6OYyPnGijAFRg58dE1V3RCH/zw5d2xSUIiNg==} + '@sentry/core@10.46.0': + resolution: {integrity: sha512-N3fj4zqBQOhXliS1Ne9euqIKuciHCGOJfPGQLwBoW9DNz03jF+NB8+dUKtrJ79YLoftjVgf8nbgwtADK7NR+2Q==} engines: {node: '>=18'} - '@sentry/react@10.43.0': - resolution: {integrity: sha512-shvErEpJ41i0Q3lIZl0CDWYQ7m8yHLi7ECG0gFvN8zf8pEdl5grQIOoe3t/GIUzcpCcor16F148ATmKJJypc/Q==} + '@sentry/react@10.46.0': + resolution: {integrity: sha512-Rb1S+9OuUPVwsz7GWnQ6Kgf3azbsseUymIegg3JZHNcW/fM1nPpaljzTBnuineia113DH0pgMBcdrrZDLaosFQ==} engines: {node: '>=18'} peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x @@ -2638,7 +2795,7 @@ packages: resolution: {integrity: sha512-1d5NkdRR6aKWBP7czkY8sFFWiKnfmfRpQOj+m9bJTsyTjbMiEQJst6315w5pCVlRItPhBqpAraqAhutZFgvyVg==} engines: {node: '>= 18'} peerDependencies: - rollup: '>=4.59.0' + rollup: '>=3.2.0' '@sentry/vite-plugin@5.1.1': resolution: {integrity: sha512-i6NWUDi2SDikfSUeMJvJTRdwEKYSfTd+mvBO2Ja51S1YK+hnickBuDfD+RvPerIXLuyRu3GamgNPbNqgCGUg/Q==} @@ -2816,31 +2973,31 @@ packages: '@swc/wasm@1.15.18': resolution: {integrity: sha512-zeSORFArxqUwfVMTRHu8AN9k9LlfSn0CKDSzLhJDITpgLoS0xpnocxsgMjQjUcVYDgO47r9zLP49HEjH/iGsFg==} - '@tanstack/query-core@5.90.20': - resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==} + '@tanstack/query-core@5.95.2': + resolution: {integrity: sha512-o4T8vZHZET4Bib3jZ/tCW9/7080urD4c+0/AUaYVpIqOsr7y0reBc1oX3ttNaSW5mYyvZHctiQ/UOP2PfdmFEQ==} - '@tanstack/query-devtools@5.93.0': - resolution: {integrity: sha512-+kpsx1NQnOFTZsw6HAFCW3HkKg0+2cepGtAWXjiiSOJJ1CtQpt72EE2nyZb+AjAbLRPoeRmPJ8MtQd8r8gsPdg==} + '@tanstack/query-devtools@5.95.2': + resolution: {integrity: sha512-QfaoqBn9uAZ+ICkA8brd1EHj+qBF6glCFgt94U8XP5BT6ppSsDBI8IJ00BU+cAGjQzp6wcKJL2EmRYvxy0TWIg==} - '@tanstack/react-query-devtools@5.91.3': - resolution: {integrity: sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA==} + '@tanstack/react-query-devtools@5.95.2': + resolution: {integrity: sha512-AFQFmbznVkbtfpx8VJ2DylW17wWagQel/qLstVLkYmNRo2CmJt3SNej5hvl6EnEeljJIdC3BTB+W7HZtpsH+3g==} peerDependencies: - '@tanstack/react-query': ^5.90.20 + '@tanstack/react-query': ^5.95.2 react: ^18 || ^19 - '@tanstack/react-query@5.90.21': - resolution: {integrity: sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==} + '@tanstack/react-query@5.95.2': + resolution: {integrity: sha512-/wGkvLj/st5Ud1Q76KF1uFxScV7WeqN1slQx5280ycwAyYkIPGaRZAEgHxe3bjirSd5Zpwkj6zNcR4cqYni/ZA==} peerDependencies: react: ^18 || ^19 - '@tanstack/react-virtual@3.13.21': - resolution: {integrity: sha512-SYXFrmrbPgXBvf+HsOsKhFgqSe4M6B29VHOsX9Jih9TlNkNkDWx0hWMiMLUghMEzyUz772ndzdEeCEBx+3GIZw==} + '@tanstack/react-virtual@3.13.23': + resolution: {integrity: sha512-XnMRnHQ23piOVj2bzJqHrRrLg4r+F86fuBcwteKfbIjJrtGxb4z7tIvPVAe4B+4UVwo9G4Giuz5fmapcrnZ0OQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/virtual-core@3.13.21': - resolution: {integrity: sha512-ww+fmLHyCbPSf7JNbWZP3g7wl6SdNo3ah5Aiw+0e9FDErkVHLKprYUrwTm7dF646FtEkN/KkAKPYezxpmvOjxw==} + '@tanstack/virtual-core@3.13.23': + resolution: {integrity: sha512-zSz2Z2HNyLjCplANTDyl3BcdQJc2k1+yyFoKhNRmCr7V7dY8o8q5m8uFTI1/Pg1kL+Hgrz6u3Xo6eFUB7l66cg==} '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} @@ -3124,14 +3281,11 @@ packages: '@vanilla-extract/babel-plugin-debug-ids@1.2.2': resolution: {integrity: sha512-MeDWGICAF9zA/OZLOKwhoRlsUW+fiMwnfuOAqFVohL31Agj7Q/RBWAYweqjHLgFBCsdnr6XIfwjJnmb2znEWxw==} - '@vanilla-extract/compiler@0.6.0': - resolution: {integrity: sha512-FlZM8s/h1obGHdYSTo05iIXUr6hsNvoE/okv/e9Sq7GN+niofhUKyuZPSwZNVYMK49xxeWNH9mopOlGRRPV4mw==} - - '@vanilla-extract/css@1.18.0': - resolution: {integrity: sha512-/p0dwOjr0o8gE5BRQ5O9P0u/2DjUd6Zfga2JGmE4KaY7ZITWMszTzk4x4CPlM5cKkRr2ZGzbE6XkuPNfp9shSQ==} + '@vanilla-extract/compiler@0.7.0': + resolution: {integrity: sha512-rZQ40HVmsxfGLjoflwwsaUBLfpbpKDoZC19oiDA0FHq4LdrYtyVbFkc0MfqkNo/qBCvaZfsRezCqk0QQxCqZ8w==} - '@vanilla-extract/css@1.20.0': - resolution: {integrity: sha512-yKuajXFlghIjRZmEfy95z6MYj+mzJPoD3nbNLVAUB8Np6I1P9g5vBlznQPD+0A46osCn0za/wIvp/cg8HU3aig==} + '@vanilla-extract/css@1.20.1': + resolution: {integrity: sha512-5I9RNo5uZW9tsBnqrWzJqELegOqTHBrZyDFnES0gR9gJJHBB9dom1N0bwITM9tKwBcfKrTX4a6DHVeQdJ2ubQA==} '@vanilla-extract/integration@8.0.9': resolution: {integrity: sha512-NP+CSo5IYHDmkMMy5vAxY4R9i2+CAg4sxgvVaxuHiuY9q30i6dNUTujNNKZGW2urEkd4HVVI6NggeIyYjbGPwA==} @@ -3144,8 +3298,8 @@ packages: peerDependencies: '@vanilla-extract/css': ^1.0.0 - '@vanilla-extract/vite-plugin@5.2.1': - resolution: {integrity: sha512-1dmCgmTmls/c4G+t453vZIzZ+82ftr+JC2J48C1drVkiwtZ7DscYSIko9Ci0CyDptBLWz5EO9fWnqzfHnns8tg==} + '@vanilla-extract/vite-plugin@5.2.2': + resolution: {integrity: sha512-AUyB4fDR2b/Mo0lcXhhlf6RxnDPYwFMyKKopalJ4BwQNKYzZSoTwHJ1PLPO9SKhpz7lzXc0Z18GHQZOewzl3YA==} peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3162,48 +3316,48 @@ packages: babel-plugin-react-compiler: optional: true - '@vitest/coverage-v8@4.1.0': - resolution: {integrity: sha512-nDWulKeik2bL2Va/Wl4x7DLuTKAXa906iRFooIRPR+huHkcvp9QDkPQ2RJdmjOFrqOqvNfoSQLF68deE3xC3CQ==} + '@vitest/coverage-v8@4.1.2': + resolution: {integrity: sha512-sPK//PHO+kAkScb8XITeB1bf7fsk85Km7+rt4eeuRR3VS1/crD47cmV5wicisJmjNdfeokTZwjMk4Mj2d58Mgg==} peerDependencies: - '@vitest/browser': 4.1.0 - vitest: 4.1.0 + '@vitest/browser': 4.1.2 + vitest: 4.1.2 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.0': - resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==} + '@vitest/expect@4.1.2': + resolution: {integrity: sha512-gbu+7B0YgUJ2nkdsRJrFFW6X7NTP44WlhiclHniUhxADQJH5Szt9mZ9hWnJPJ8YwOK5zUOSSlSvyzRf0u1DSBQ==} - '@vitest/mocker@4.1.0': - resolution: {integrity: sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==} + '@vitest/mocker@4.1.2': + resolution: {integrity: sha512-Ize4iQtEALHDttPRCmN+FKqOl2vxTiNUhzobQFFt/BM1lRUTG7zRCLOykG/6Vo4E4hnUdfVLo5/eqKPukcWW7Q==} peerDependencies: msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@4.1.0': - resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==} + '@vitest/pretty-format@4.1.2': + resolution: {integrity: sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA==} - '@vitest/runner@4.1.0': - resolution: {integrity: sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==} + '@vitest/runner@4.1.2': + resolution: {integrity: sha512-Gr+FQan34CdiYAwpGJmQG8PgkyFVmARK8/xSijia3eTFgVfpcpztWLuP6FttGNfPLJhaZVP/euvujeNYar36OQ==} - '@vitest/snapshot@4.1.0': - resolution: {integrity: sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==} + '@vitest/snapshot@4.1.2': + resolution: {integrity: sha512-g7yfUmxYS4mNxk31qbOYsSt2F4m1E02LFqO53Xpzg3zKMhLAPZAjjfyl9e6z7HrW6LvUdTwAQR3HHfLjpko16A==} - '@vitest/spy@4.1.0': - resolution: {integrity: sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==} + '@vitest/spy@4.1.2': + resolution: {integrity: sha512-DU4fBnbVCJGNBwVA6xSToNXrkZNSiw59H8tcuUspVMsBDBST4nfvsPsEHDHGtWRRnqBERBQu7TrTKskmjqTXKA==} - '@vitest/ui@4.1.0': - resolution: {integrity: sha512-sTSDtVM1GOevRGsCNhp1mBUHKo9Qlc55+HCreFT4fe99AHxl1QQNXSL3uj4Pkjh5yEuWZIx8E2tVC94nnBZECQ==} + '@vitest/ui@4.1.2': + resolution: {integrity: sha512-/irhyeAcKS2u6Zokagf9tqZJ0t8S6kMZq4ZG9BHZv7I+fkRrYfQX4w7geYeC2r6obThz39PDxvXQzZX+qXqGeg==} peerDependencies: - vitest: 4.1.0 + vitest: 4.1.2 - '@vitest/utils@4.1.0': - resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} + '@vitest/utils@4.1.2': + resolution: {integrity: sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -3341,6 +3495,9 @@ packages: badwords-list@2.0.1-4: resolution: {integrity: sha512-FxfZUp7B9yCnesNtFQS9v6PvZdxTYa14Q60JR6vhjdQdWI4naTjJIyx22JzoER8ooeT8SAAKoHLjKfCV7XgYUQ==} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -3372,8 +3529,14 @@ packages: blurhash@2.0.5: resolution: {integrity: sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==} - brace-expansion@5.0.4: - resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + brace-expansion@2.0.3: + resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -3471,6 +3634,9 @@ packages: compute-scroll-into-view@3.1.1: resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -3522,11 +3688,6 @@ packages: css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -3549,8 +3710,8 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} - dayjs@1.11.19: - resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} @@ -3732,6 +3893,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -3979,7 +4145,7 @@ packages: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} peerDependencies: - picomatch: ^3 || ^4 + picomatch: '>=4.0.4' peerDependenciesMeta: picomatch: optional: true @@ -4223,10 +4389,10 @@ packages: i18next-http-backend@2.7.3: resolution: {integrity: sha512-FgZxrXdRA5u44xfYsJlEBL4/KH3f2IluBpgV/7riW0YW2VEyM8FzVt2XHAOi6id0Ppj7vZvCZVpp5LrGXnc8Ig==} - i18next@25.8.17: - resolution: {integrity: sha512-vWtCttyn5bpOK4hWbRAe1ZXkA+Yzcn2OcACT+WJavtfGMcxzkfvXTLMeOU8MUhRmAySKjU4VVuKlo0sSGeBokA==} + i18next@25.10.10: + resolution: {integrity: sha512-cqUW2Z3EkRx7NqSyywjkgCLK7KLCL6IFVFcONG7nVYIJ3ekZ1/N5jUsihHV6Bq37NfhgtczxJcxduELtjTwkuQ==} peerDependencies: - typescript: ^5 + typescript: ^5 || ^6 peerDependenciesMeta: typescript: optional: true @@ -4447,8 +4613,8 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - jotai@2.18.1: - resolution: {integrity: sha512-e0NOzK+yRFwHo7DOp0DS0Ycq74KMEAObDWFGmfEL28PD9nLqBTt3/Ug7jf9ca72x0gC9LQZG9zH+0ISICmy3iA==} + jotai@2.19.0: + resolution: {integrity: sha512-r2wwxEXP1F2JteDLZEOPoIpAHhV89paKsN5GWVYndPNMMP/uVZDcC+fNj0A8NjKgaPWzdyO8Vp8YcYKe0uCEqQ==} engines: {node: '>=12.20.0'} peerDependencies: '@babel/core': '>=7.0.0' @@ -4475,8 +4641,8 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsdom@29.0.0: - resolution: {integrity: sha512-9FshNB6OepopZ08unmmGpsF7/qCjxGPbo3NbgfJAnPeHXnsODE9WWffXZtRFRFe0ntzaAOcSKNJFz8wiyvF1jQ==} + jsdom@29.0.1: + resolution: {integrity: sha512-z6JOK5gRO7aMybVq/y/MlIpKh8JIi68FBKMUtKkK2KH/wMSRlCxQ682d08LB9fYXplyY/UXG8P4XXTScmdjApg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} peerDependencies: canvas: ^3.0.0 @@ -4501,9 +4667,6 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -4746,6 +4909,13 @@ packages: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -4929,18 +5099,6 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - picomatch@4.0.4: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} @@ -5043,14 +5201,14 @@ packages: peerDependencies: react: '>=16.4.1' - react-i18next@16.5.7: - resolution: {integrity: sha512-t/si6ng+hMPvgRGNgGvHAkMuVRBsIBx5mN+exm/yiBPSFL7VooQ37YYfISxSE0LjvQjG+MTe+0htKdOJY0S/vw==} + react-i18next@16.6.6: + resolution: {integrity: sha512-ZgL2HUoW34UKUkOV7uSQFE1CDnRPD+tCR3ywSuWH7u2iapnz86U8Bi3Vrs620qNDzCf1F47NxglCEkchCTDOHw==} peerDependencies: - i18next: '>= 25.6.2' + i18next: '>= 25.10.9' react: '>= 16.8.0' react-dom: '*' react-native: '*' - typescript: ^5 + typescript: ^5 || ^6 peerDependenciesMeta: react-dom: optional: true @@ -5158,8 +5316,13 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rollup@4.59.0: - resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + rollup@2.80.0: + resolution: {integrity: sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==} + engines: {node: '>=10.0.0'} + hasBin: true + + rollup@4.60.0: + resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -5284,8 +5447,8 @@ packages: resolution: {integrity: sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==} engines: {node: '>=20.0.0'} - smol-toml@1.6.0: - resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} + smol-toml@1.6.1: + resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} engines: {node: '>= 18'} snake-case@3.0.4: @@ -5537,8 +5700,12 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici@7.24.3: - resolution: {integrity: sha512-eJdUmK/Wrx2d+mnWWmwwLRyA7OQCkLap60sk3dOK4ViZR7DKwwptwuIvFBg2HaiP9ESaEdhtpSymQPvytpmkCA==} + undici@7.24.4: + resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==} + engines: {node: '>=20.18.1'} + + undici@7.24.6: + resolution: {integrity: sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==} engines: {node: '>=20.18.1'} unenv@2.0.0-rc.24: @@ -5671,7 +5838,7 @@ packages: sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 - yaml: ^2.4.2 + yaml: '>=2.8.3' peerDependenciesMeta: '@types/node': optional: true @@ -5703,7 +5870,7 @@ packages: peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 '@vitejs/devtools': ^0.1.0 - esbuild: '>=0.25.0' + esbuild: ^0.27.0 jiti: '>=1.21.0' less: ^4.0.0 sass: ^1.70.0 @@ -5712,7 +5879,7 @@ packages: sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 - yaml: ^2.4.2 + yaml: '>=2.8.3' peerDependenciesMeta: '@types/node': optional: true @@ -5739,21 +5906,21 @@ packages: yaml: optional: true - vitest@4.1.0: - resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==} + vitest@4.1.2: + resolution: {integrity: sha512-xjR1dMTVHlFLh98JE3i/f/WePqJsah4A0FK9cc8Ehp9Udk0AZk6ccpIZhh1qJ/yxVWRZ+Q54ocnD8TXmkhspGg==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.0 - '@vitest/browser-preview': 4.1.0 - '@vitest/browser-webdriverio': 4.1.0 - '@vitest/ui': 4.1.0 + '@vitest/browser-playwright': 4.1.2 + '@vitest/browser-preview': 4.1.2 + '@vitest/browser-webdriverio': 4.1.2 + '@vitest/ui': 4.1.2 happy-dom: '*' jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -5926,11 +6093,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} - engines: {node: '>= 14.6'} - hasBin: true - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -5954,10 +6116,9 @@ snapshots: '@adobe/css-tools@4.4.4': {} - '@apideck/better-ajv-errors@0.3.6(ajv@8.18.0)': + '@apideck/better-ajv-errors@0.3.7(ajv@8.18.0)': dependencies: ajv: 8.18.0 - json-schema: 0.4.0 jsonpointer: 5.0.1 leven: 3.1.0 @@ -5991,7 +6152,7 @@ snapshots: '@atlaskit/pragmatic-drag-and-drop@1.7.9': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 bind-event-listener: 3.0.0 raf-schd: 4.0.3 @@ -6153,6 +6314,11 @@ snapshots: dependencies: '@babel/types': 7.29.0 + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + optional: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 @@ -6670,12 +6836,12 @@ snapshots: optionalDependencies: workerd: 1.20260317.1 - '@cloudflare/vite-plugin@1.30.2(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workerd@1.20260317.1)(wrangler@4.78.0)': + '@cloudflare/vite-plugin@1.30.2(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1))(workerd@1.20260317.1)(wrangler@4.78.0)': dependencies: '@cloudflare/unenv-preset': 2.16.0(unenv@2.0.0-rc.24)(workerd@1.20260317.1) miniflare: 4.20260317.3 unenv: 2.0.0-rc.24 - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) wrangler: 4.78.0 ws: 8.18.0 transitivePeerDependencies: @@ -6750,88 +6916,166 @@ snapshots: '@emotion/hash@0.9.2': {} - '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.27.3)': + '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.27.4)': dependencies: - esbuild: 0.27.3 + esbuild: 0.27.4 '@esbuild/aix-ppc64@0.27.3': optional: true + '@esbuild/aix-ppc64@0.27.4': + optional: true + '@esbuild/android-arm64@0.27.3': optional: true + '@esbuild/android-arm64@0.27.4': + optional: true + '@esbuild/android-arm@0.27.3': optional: true + '@esbuild/android-arm@0.27.4': + optional: true + '@esbuild/android-x64@0.27.3': optional: true + '@esbuild/android-x64@0.27.4': + optional: true + '@esbuild/darwin-arm64@0.27.3': optional: true + '@esbuild/darwin-arm64@0.27.4': + optional: true + '@esbuild/darwin-x64@0.27.3': optional: true + '@esbuild/darwin-x64@0.27.4': + optional: true + '@esbuild/freebsd-arm64@0.27.3': optional: true + '@esbuild/freebsd-arm64@0.27.4': + optional: true + '@esbuild/freebsd-x64@0.27.3': optional: true + '@esbuild/freebsd-x64@0.27.4': + optional: true + '@esbuild/linux-arm64@0.27.3': optional: true + '@esbuild/linux-arm64@0.27.4': + optional: true + '@esbuild/linux-arm@0.27.3': optional: true + '@esbuild/linux-arm@0.27.4': + optional: true + '@esbuild/linux-ia32@0.27.3': optional: true + '@esbuild/linux-ia32@0.27.4': + optional: true + '@esbuild/linux-loong64@0.27.3': optional: true + '@esbuild/linux-loong64@0.27.4': + optional: true + '@esbuild/linux-mips64el@0.27.3': optional: true + '@esbuild/linux-mips64el@0.27.4': + optional: true + '@esbuild/linux-ppc64@0.27.3': optional: true + '@esbuild/linux-ppc64@0.27.4': + optional: true + '@esbuild/linux-riscv64@0.27.3': optional: true + '@esbuild/linux-riscv64@0.27.4': + optional: true + '@esbuild/linux-s390x@0.27.3': optional: true + '@esbuild/linux-s390x@0.27.4': + optional: true + '@esbuild/linux-x64@0.27.3': optional: true + '@esbuild/linux-x64@0.27.4': + optional: true + '@esbuild/netbsd-arm64@0.27.3': optional: true + '@esbuild/netbsd-arm64@0.27.4': + optional: true + '@esbuild/netbsd-x64@0.27.3': optional: true + '@esbuild/netbsd-x64@0.27.4': + optional: true + '@esbuild/openbsd-arm64@0.27.3': optional: true + '@esbuild/openbsd-arm64@0.27.4': + optional: true + '@esbuild/openbsd-x64@0.27.3': optional: true + '@esbuild/openbsd-x64@0.27.4': + optional: true + '@esbuild/openharmony-arm64@0.27.3': optional: true + '@esbuild/openharmony-arm64@0.27.4': + optional: true + '@esbuild/sunos-x64@0.27.3': optional: true + '@esbuild/sunos-x64@0.27.4': + optional: true + '@esbuild/win32-arm64@0.27.3': optional: true + '@esbuild/win32-arm64@0.27.4': + optional: true + '@esbuild/win32-ia32@0.27.3': optional: true + '@esbuild/win32-ia32@0.27.4': + optional: true + '@esbuild/win32-x64@0.27.3': optional: true + '@esbuild/win32-x64@0.27.4': + optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.3(jiti@2.6.1))': dependencies: eslint: 9.39.3(jiti@2.6.1) @@ -6849,7 +7093,7 @@ snapshots: dependencies: '@eslint/object-schema': 2.1.7 debug: 4.4.3 - minimatch: 10.2.4 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -6874,7 +7118,7 @@ snapshots: ignore: 5.3.2 import-fresh: 3.3.1 js-yaml: 4.1.1 - minimatch: 10.2.4 + minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color @@ -8256,180 +8500,188 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.7': {} - '@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@4.59.0)': + '@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.28.6 - '@rollup/pluginutils': 3.1.0(rollup@4.59.0) - rollup: 4.59.0 + '@rollup/pluginutils': 3.1.0(rollup@2.80.0) + rollup: 2.80.0 optionalDependencies: '@types/babel__core': 7.20.5 transitivePeerDependencies: - supports-color - '@rollup/plugin-inject@5.0.5(rollup@4.59.0)': + '@rollup/plugin-inject@5.0.5(rollup@4.60.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + '@rollup/pluginutils': 5.3.0(rollup@4.60.0) estree-walker: 2.0.2 magic-string: 0.30.21 optionalDependencies: - rollup: 4.59.0 + rollup: 4.60.0 - '@rollup/plugin-node-resolve@15.3.1(rollup@4.59.0)': + '@rollup/plugin-node-resolve@15.3.1(rollup@2.80.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + '@rollup/pluginutils': 5.3.0(rollup@2.80.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.11 optionalDependencies: - rollup: 4.59.0 + rollup: 2.80.0 - '@rollup/plugin-replace@2.4.2(rollup@4.59.0)': + '@rollup/plugin-replace@2.4.2(rollup@2.80.0)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@4.59.0) + '@rollup/pluginutils': 3.1.0(rollup@2.80.0) magic-string: 0.25.9 - rollup: 4.59.0 + rollup: 2.80.0 - '@rollup/plugin-terser@0.4.4(rollup@4.59.0)': + '@rollup/plugin-terser@0.4.4(rollup@2.80.0)': dependencies: serialize-javascript: 7.0.5 smob: 1.6.1 terser: 5.46.1 optionalDependencies: - rollup: 4.59.0 + rollup: 2.80.0 - '@rollup/plugin-virtual@3.0.2(rollup@4.59.0)': + '@rollup/plugin-virtual@3.0.2(rollup@4.60.0)': optionalDependencies: - rollup: 4.59.0 + rollup: 4.60.0 - '@rollup/plugin-wasm@6.2.2(rollup@4.59.0)': + '@rollup/plugin-wasm@6.2.2(rollup@4.60.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + '@rollup/pluginutils': 5.3.0(rollup@4.60.0) optionalDependencies: - rollup: 4.59.0 + rollup: 4.60.0 - '@rollup/pluginutils@3.1.0(rollup@4.59.0)': + '@rollup/pluginutils@3.1.0(rollup@2.80.0)': dependencies: '@types/estree': 0.0.39 estree-walker: 1.0.1 - picomatch: 2.3.2 - rollup: 4.59.0 + picomatch: 4.0.4 + rollup: 2.80.0 - '@rollup/pluginutils@5.3.0(rollup@4.59.0)': + '@rollup/pluginutils@5.3.0(rollup@2.80.0)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: - rollup: 4.59.0 + rollup: 2.80.0 - '@rollup/rollup-android-arm-eabi@4.59.0': + '@rollup/pluginutils@5.3.0(rollup@4.60.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.60.0 + + '@rollup/rollup-android-arm-eabi@4.60.0': optional: true - '@rollup/rollup-android-arm64@4.59.0': + '@rollup/rollup-android-arm64@4.60.0': optional: true - '@rollup/rollup-darwin-arm64@4.59.0': + '@rollup/rollup-darwin-arm64@4.60.0': optional: true - '@rollup/rollup-darwin-x64@4.59.0': + '@rollup/rollup-darwin-x64@4.60.0': optional: true - '@rollup/rollup-freebsd-arm64@4.59.0': + '@rollup/rollup-freebsd-arm64@4.60.0': optional: true - '@rollup/rollup-freebsd-x64@4.59.0': + '@rollup/rollup-freebsd-x64@4.60.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.59.0': + '@rollup/rollup-linux-arm-musleabihf@4.60.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.59.0': + '@rollup/rollup-linux-arm64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.59.0': + '@rollup/rollup-linux-arm64-musl@4.60.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.59.0': + '@rollup/rollup-linux-loong64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-loong64-musl@4.59.0': + '@rollup/rollup-linux-loong64-musl@4.60.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.59.0': + '@rollup/rollup-linux-ppc64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-ppc64-musl@4.59.0': + '@rollup/rollup-linux-ppc64-musl@4.60.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.59.0': + '@rollup/rollup-linux-riscv64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.59.0': + '@rollup/rollup-linux-riscv64-musl@4.60.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.59.0': + '@rollup/rollup-linux-s390x-gnu@4.60.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.59.0': + '@rollup/rollup-linux-x64-gnu@4.60.0': optional: true - '@rollup/rollup-linux-x64-musl@4.59.0': + '@rollup/rollup-linux-x64-musl@4.60.0': optional: true - '@rollup/rollup-openbsd-x64@4.59.0': + '@rollup/rollup-openbsd-x64@4.60.0': optional: true - '@rollup/rollup-openharmony-arm64@4.59.0': + '@rollup/rollup-openharmony-arm64@4.60.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.59.0': + '@rollup/rollup-win32-arm64-msvc@4.60.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.59.0': + '@rollup/rollup-win32-ia32-msvc@4.60.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.59.0': + '@rollup/rollup-win32-x64-gnu@4.60.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.59.0': + '@rollup/rollup-win32-x64-msvc@4.60.0': optional: true '@rtsao/scc@1.1.0': {} '@sableclient/sable-call-embedded@1.1.4': {} - '@sentry-internal/browser-utils@10.43.0': + '@sentry-internal/browser-utils@10.46.0': dependencies: - '@sentry/core': 10.43.0 + '@sentry/core': 10.46.0 - '@sentry-internal/feedback@10.43.0': + '@sentry-internal/feedback@10.46.0': dependencies: - '@sentry/core': 10.43.0 + '@sentry/core': 10.46.0 - '@sentry-internal/replay-canvas@10.43.0': + '@sentry-internal/replay-canvas@10.46.0': dependencies: - '@sentry-internal/replay': 10.43.0 - '@sentry/core': 10.43.0 + '@sentry-internal/replay': 10.46.0 + '@sentry/core': 10.46.0 - '@sentry-internal/replay@10.43.0': + '@sentry-internal/replay@10.46.0': dependencies: - '@sentry-internal/browser-utils': 10.43.0 - '@sentry/core': 10.43.0 + '@sentry-internal/browser-utils': 10.46.0 + '@sentry/core': 10.46.0 '@sentry/babel-plugin-component-annotate@5.1.1': {} - '@sentry/browser@10.43.0': + '@sentry/browser@10.46.0': dependencies: - '@sentry-internal/browser-utils': 10.43.0 - '@sentry-internal/feedback': 10.43.0 - '@sentry-internal/replay': 10.43.0 - '@sentry-internal/replay-canvas': 10.43.0 - '@sentry/core': 10.43.0 + '@sentry-internal/browser-utils': 10.46.0 + '@sentry-internal/feedback': 10.46.0 + '@sentry-internal/replay': 10.46.0 + '@sentry-internal/replay-canvas': 10.46.0 + '@sentry/core': 10.46.0 '@sentry/bundler-plugin-core@5.1.1': dependencies: @@ -8488,27 +8740,27 @@ snapshots: - encoding - supports-color - '@sentry/core@10.43.0': {} + '@sentry/core@10.46.0': {} - '@sentry/react@10.43.0(react@18.3.1)': + '@sentry/react@10.46.0(react@18.3.1)': dependencies: - '@sentry/browser': 10.43.0 - '@sentry/core': 10.43.0 + '@sentry/browser': 10.46.0 + '@sentry/core': 10.46.0 react: 18.3.1 - '@sentry/rollup-plugin@5.1.1(rollup@4.59.0)': + '@sentry/rollup-plugin@5.1.1(rollup@4.60.0)': dependencies: '@sentry/bundler-plugin-core': 5.1.1 magic-string: 0.30.21 - rollup: 4.59.0 + rollup: 4.60.0 transitivePeerDependencies: - encoding - supports-color - '@sentry/vite-plugin@5.1.1(rollup@4.59.0)': + '@sentry/vite-plugin@5.1.1(rollup@4.60.0)': dependencies: '@sentry/bundler-plugin-core': 5.1.1 - '@sentry/rollup-plugin': 5.1.1(rollup@4.59.0) + '@sentry/rollup-plugin': 5.1.1(rollup@4.60.0) transitivePeerDependencies: - encoding - rollup @@ -8528,7 +8780,7 @@ snapshots: eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.3 + picomatch: 4.0.4 '@surma/rollup-plugin-off-main-thread@2.2.3': dependencies: @@ -8666,28 +8918,28 @@ snapshots: '@swc/wasm@1.15.18': {} - '@tanstack/query-core@5.90.20': {} + '@tanstack/query-core@5.95.2': {} - '@tanstack/query-devtools@5.93.0': {} + '@tanstack/query-devtools@5.95.2': {} - '@tanstack/react-query-devtools@5.91.3(@tanstack/react-query@5.90.21(react@18.3.1))(react@18.3.1)': + '@tanstack/react-query-devtools@5.95.2(@tanstack/react-query@5.95.2(react@18.3.1))(react@18.3.1)': dependencies: - '@tanstack/query-devtools': 5.93.0 - '@tanstack/react-query': 5.90.21(react@18.3.1) + '@tanstack/query-devtools': 5.95.2 + '@tanstack/react-query': 5.95.2(react@18.3.1) react: 18.3.1 - '@tanstack/react-query@5.90.21(react@18.3.1)': + '@tanstack/react-query@5.95.2(react@18.3.1)': dependencies: - '@tanstack/query-core': 5.90.20 + '@tanstack/query-core': 5.95.2 react: 18.3.1 - '@tanstack/react-virtual@3.13.21(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tanstack/react-virtual@3.13.23(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@tanstack/virtual-core': 3.13.21 + '@tanstack/virtual-core': 3.13.23 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@tanstack/virtual-core@3.13.21': {} + '@tanstack/virtual-core@3.13.23': {} '@testing-library/dom@10.4.1': dependencies: @@ -8732,7 +8984,7 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 @@ -8746,7 +8998,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 optional: true @@ -8972,12 +9224,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@vanilla-extract/compiler@0.6.0(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2)': + '@vanilla-extract/compiler@0.7.0(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)': dependencies: - '@vanilla-extract/css': 1.20.0 + '@vanilla-extract/css': 1.20.1 '@vanilla-extract/integration': 8.0.9 - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) - vite-node: 3.2.4(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) + vite-node: 3.2.4(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1) transitivePeerDependencies: - '@types/node' - '@vitejs/devtools' @@ -8995,29 +9247,11 @@ snapshots: - tsx - yaml - '@vanilla-extract/css@1.18.0': - dependencies: - '@emotion/hash': 0.9.2 - '@vanilla-extract/private': 1.0.9 - css-what: 6.2.2 - cssesc: 3.0.0 - csstype: 3.2.3 - dedent: 1.7.2 - deep-object-diff: 1.1.9 - deepmerge: 4.3.1 - lru-cache: 10.4.3 - media-query-parser: 2.0.2 - modern-ahocorasick: 1.1.0 - picocolors: 1.1.1 - transitivePeerDependencies: - - babel-plugin-macros - - '@vanilla-extract/css@1.20.0': + '@vanilla-extract/css@1.20.1': dependencies: '@emotion/hash': 0.9.2 '@vanilla-extract/private': 1.0.9 css-what: 6.2.2 - cssesc: 3.0.0 csstype: 3.2.3 dedent: 1.7.2 deep-object-diff: 1.1.9 @@ -9034,9 +9268,9 @@ snapshots: '@babel/core': 7.29.0 '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@vanilla-extract/babel-plugin-debug-ids': 1.2.2 - '@vanilla-extract/css': 1.20.0 + '@vanilla-extract/css': 1.20.1 dedent: 1.7.2 - esbuild: 0.27.3 + esbuild: 0.27.4 eval: 0.1.8 find-up: 5.0.0 javascript-stringify: 2.1.0 @@ -9047,15 +9281,15 @@ snapshots: '@vanilla-extract/private@1.0.9': {} - '@vanilla-extract/recipes@0.5.7(@vanilla-extract/css@1.18.0)': + '@vanilla-extract/recipes@0.5.7(@vanilla-extract/css@1.20.1)': dependencies: - '@vanilla-extract/css': 1.18.0 + '@vanilla-extract/css': 1.20.1 - '@vanilla-extract/vite-plugin@5.2.1(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(yaml@2.8.2)': + '@vanilla-extract/vite-plugin@5.2.2(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1))': dependencies: - '@vanilla-extract/compiler': 0.6.0(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2) + '@vanilla-extract/compiler': 0.7.0(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1) '@vanilla-extract/integration': 8.0.9 - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) transitivePeerDependencies: - '@types/node' - '@vitejs/devtools' @@ -9073,15 +9307,15 @@ snapshots: - tsx - yaml - '@vitejs/plugin-react@6.0.1(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))': + '@vitejs/plugin-react@6.0.1(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) - '@vitest/coverage-v8@4.1.0(vitest@4.1.0)': + '@vitest/coverage-v8@4.1.2(vitest@4.1.2)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.0 + '@vitest/utils': 4.1.2 ast-v8-to-istanbul: 1.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -9090,57 +9324,57 @@ snapshots: obug: 2.1.1 std-env: 4.0.0 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + vitest: 4.1.2(@types/node@24.10.13)(@vitest/ui@4.1.2)(jsdom@29.0.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) - '@vitest/expect@4.1.0': + '@vitest/expect@4.1.2': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.0 - '@vitest/utils': 4.1.0 + '@vitest/spy': 4.1.2 + '@vitest/utils': 4.1.2 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))': + '@vitest/mocker@4.1.2(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1))': dependencies: - '@vitest/spy': 4.1.0 + '@vitest/spy': 4.1.2 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) - '@vitest/pretty-format@4.1.0': + '@vitest/pretty-format@4.1.2': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.0': + '@vitest/runner@4.1.2': dependencies: - '@vitest/utils': 4.1.0 + '@vitest/utils': 4.1.2 pathe: 2.0.3 - '@vitest/snapshot@4.1.0': + '@vitest/snapshot@4.1.2': dependencies: - '@vitest/pretty-format': 4.1.0 - '@vitest/utils': 4.1.0 + '@vitest/pretty-format': 4.1.2 + '@vitest/utils': 4.1.2 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.0': {} + '@vitest/spy@4.1.2': {} - '@vitest/ui@4.1.0(vitest@4.1.0)': + '@vitest/ui@4.1.2(vitest@4.1.2)': dependencies: - '@vitest/utils': 4.1.0 + '@vitest/utils': 4.1.2 fflate: 0.8.2 flatted: 3.4.2 pathe: 2.0.3 sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) + vitest: 4.1.2(@types/node@24.10.13)(@vitest/ui@4.1.2)(jsdom@29.0.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) - '@vitest/utils@4.1.0': + '@vitest/utils@4.1.2': dependencies: - '@vitest/pretty-format': 4.1.0 + '@vitest/pretty-format': 4.1.2 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -9183,7 +9417,7 @@ snapshots: anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.2 + picomatch: 4.0.4 argparse@2.0.1: {} @@ -9312,6 +9546,8 @@ snapshots: badwords-list@2.0.1-4: {} + balanced-match@1.0.2: {} + balanced-match@4.0.4: {} base-x@5.0.1: {} @@ -9332,7 +9568,16 @@ snapshots: blurhash@2.0.5: {} - brace-expansion@5.0.4: + brace-expansion@1.1.13: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.3: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -9427,6 +9672,8 @@ snapshots: compute-scroll-into-view@3.1.1: {} + concat-map@0.0.1: {} + confbox@0.1.8: {} confusing-browser-globals@1.0.11: {} @@ -9473,8 +9720,6 @@ snapshots: css.escape@1.5.1: {} - cssesc@3.0.0: {} - csstype@3.2.3: {} damerau-levenshtein@1.0.8: {} @@ -9504,7 +9749,7 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - dayjs@1.11.19: {} + dayjs@1.11.20: {} debug@3.2.7: dependencies: @@ -9748,6 +9993,35 @@ snapshots: '@esbuild/win32-ia32': 0.27.3 '@esbuild/win32-x64': 0.27.3 + esbuild@0.27.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 + escalade@3.2.0: {} escape-string-regexp@4.0.0: {} @@ -9873,7 +10147,7 @@ snapshots: hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 10.2.4 + minimatch: 3.1.5 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -9901,7 +10175,7 @@ snapshots: hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 - minimatch: 10.2.4 + minimatch: 3.1.5 object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 @@ -9953,7 +10227,7 @@ snapshots: estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 - minimatch: 10.2.4 + minimatch: 3.1.5 object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 @@ -10007,7 +10281,7 @@ snapshots: is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 - minimatch: 10.2.4 + minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -10100,7 +10374,7 @@ snapshots: filelist@1.0.6: dependencies: - minimatch: 10.2.4 + minimatch: 5.1.9 fill-range@7.1.1: dependencies: @@ -10130,10 +10404,10 @@ snapshots: dependencies: tabbable: 6.4.0 - folds@2.6.2(@vanilla-extract/css@1.18.0)(@vanilla-extract/recipes@0.5.7(@vanilla-extract/css@1.18.0))(classnames@2.5.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + folds@2.6.2(@vanilla-extract/css@1.20.1)(@vanilla-extract/recipes@0.5.7(@vanilla-extract/css@1.20.1))(classnames@2.5.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@vanilla-extract/css': 1.18.0 - '@vanilla-extract/recipes': 0.5.7(@vanilla-extract/css@1.18.0) + '@vanilla-extract/css': 1.20.1 + '@vanilla-extract/recipes': 0.5.7(@vanilla-extract/css@1.20.1) classnames: 2.5.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10357,9 +10631,9 @@ snapshots: transitivePeerDependencies: - encoding - i18next@25.8.17(typescript@5.9.3): + i18next@25.10.10(typescript@5.9.3): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 optionalDependencies: typescript: 5.9.3 @@ -10571,7 +10845,7 @@ snapshots: jiti@2.6.1: {} - jotai@2.18.1(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@18.3.28)(react@18.3.1): + jotai@2.19.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@18.3.28)(react@18.3.1): optionalDependencies: '@babel/core': 7.29.0 '@babel/template': 7.28.6 @@ -10586,7 +10860,7 @@ snapshots: dependencies: argparse: 2.0.1 - jsdom@29.0.0: + jsdom@29.0.1: dependencies: '@asamuzakjp/css-color': 5.0.1 '@asamuzakjp/dom-selector': 7.0.3 @@ -10603,7 +10877,7 @@ snapshots: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.1 - undici: 7.24.3 + undici: 7.24.6 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -10622,8 +10896,6 @@ snapshots: json-schema-traverse@1.0.0: {} - json-schema@0.4.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: @@ -10666,8 +10938,8 @@ snapshots: minimist: 1.2.8 oxc-resolver: 11.19.1 picocolors: 1.1.1 - picomatch: 4.0.3 - smol-toml: 1.6.0 + picomatch: 4.0.4 + smol-toml: 1.6.1 strip-json-comments: 5.0.3 typescript: 5.9.3 zod: 4.3.6 @@ -10825,14 +11097,14 @@ snapshots: media-query-parser@2.0.2: dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 merge2@1.4.1: {} micromatch@4.0.8: dependencies: braces: 3.0.3 - picomatch: 2.3.1 + picomatch: 4.0.4 min-indent@1.0.1: {} @@ -10840,7 +11112,7 @@ snapshots: dependencies: '@cspotcode/source-map-support': 0.8.1 sharp: 0.34.5 - undici: 7.24.3 + undici: 7.24.4 workerd: 1.20260317.1 ws: 8.18.0 youch: 4.1.0-beta.10 @@ -10850,7 +11122,15 @@ snapshots: minimatch@10.2.4: dependencies: - brace-expansion: 5.0.4 + brace-expansion: 5.0.5 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.13 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.3 minimist@1.2.8: {} @@ -11049,12 +11329,6 @@ snapshots: picocolors@1.1.1: {} - picomatch@2.3.1: {} - - picomatch@2.3.2: {} - - picomatch@4.0.3: {} - picomatch@4.0.4: {} pkg-types@1.3.1: @@ -11187,11 +11461,11 @@ snapshots: react: 18.3.1 react-async-script: 1.2.0(react@18.3.1) - react-i18next@16.5.7(i18next@25.8.17(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3): + react-i18next@16.6.6(i18next@25.10.10(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 html-parse-stringify: 3.0.1 - i18next: 25.8.17(typescript@5.9.3) + i18next: 25.10.10(typescript@5.9.3) react: 18.3.1 use-sync-external-store: 1.6.0(react@18.3.1) optionalDependencies: @@ -11227,7 +11501,7 @@ snapshots: readdirp@3.6.0: dependencies: - picomatch: 2.3.2 + picomatch: 4.0.4 redent@3.0.0: dependencies: @@ -11321,35 +11595,39 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.12 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.12 - rollup@4.59.0: + rollup@2.80.0: + optionalDependencies: + fsevents: 2.3.3 + + rollup@4.60.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.59.0 - '@rollup/rollup-android-arm64': 4.59.0 - '@rollup/rollup-darwin-arm64': 4.59.0 - '@rollup/rollup-darwin-x64': 4.59.0 - '@rollup/rollup-freebsd-arm64': 4.59.0 - '@rollup/rollup-freebsd-x64': 4.59.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 - '@rollup/rollup-linux-arm-musleabihf': 4.59.0 - '@rollup/rollup-linux-arm64-gnu': 4.59.0 - '@rollup/rollup-linux-arm64-musl': 4.59.0 - '@rollup/rollup-linux-loong64-gnu': 4.59.0 - '@rollup/rollup-linux-loong64-musl': 4.59.0 - '@rollup/rollup-linux-ppc64-gnu': 4.59.0 - '@rollup/rollup-linux-ppc64-musl': 4.59.0 - '@rollup/rollup-linux-riscv64-gnu': 4.59.0 - '@rollup/rollup-linux-riscv64-musl': 4.59.0 - '@rollup/rollup-linux-s390x-gnu': 4.59.0 - '@rollup/rollup-linux-x64-gnu': 4.59.0 - '@rollup/rollup-linux-x64-musl': 4.59.0 - '@rollup/rollup-openbsd-x64': 4.59.0 - '@rollup/rollup-openharmony-arm64': 4.59.0 - '@rollup/rollup-win32-arm64-msvc': 4.59.0 - '@rollup/rollup-win32-ia32-msvc': 4.59.0 - '@rollup/rollup-win32-x64-gnu': 4.59.0 - '@rollup/rollup-win32-x64-msvc': 4.59.0 + '@rollup/rollup-android-arm-eabi': 4.60.0 + '@rollup/rollup-android-arm64': 4.60.0 + '@rollup/rollup-darwin-arm64': 4.60.0 + '@rollup/rollup-darwin-x64': 4.60.0 + '@rollup/rollup-freebsd-arm64': 4.60.0 + '@rollup/rollup-freebsd-x64': 4.60.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.0 + '@rollup/rollup-linux-arm-musleabihf': 4.60.0 + '@rollup/rollup-linux-arm64-gnu': 4.60.0 + '@rollup/rollup-linux-arm64-musl': 4.60.0 + '@rollup/rollup-linux-loong64-gnu': 4.60.0 + '@rollup/rollup-linux-loong64-musl': 4.60.0 + '@rollup/rollup-linux-ppc64-gnu': 4.60.0 + '@rollup/rollup-linux-ppc64-musl': 4.60.0 + '@rollup/rollup-linux-riscv64-gnu': 4.60.0 + '@rollup/rollup-linux-riscv64-musl': 4.60.0 + '@rollup/rollup-linux-s390x-gnu': 4.60.0 + '@rollup/rollup-linux-x64-gnu': 4.60.0 + '@rollup/rollup-linux-x64-musl': 4.60.0 + '@rollup/rollup-openbsd-x64': 4.60.0 + '@rollup/rollup-openharmony-arm64': 4.60.0 + '@rollup/rollup-win32-arm64-msvc': 4.60.0 + '@rollup/rollup-win32-ia32-msvc': 4.60.0 + '@rollup/rollup-win32-x64-gnu': 4.60.0 + '@rollup/rollup-win32-x64-msvc': 4.60.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -11534,7 +11812,7 @@ snapshots: smob@1.6.1: {} - smol-toml@1.6.0: {} + smol-toml@1.6.1: {} snake-case@3.0.4: dependencies: @@ -11726,7 +12004,7 @@ snapshots: ts-declaration-location@1.0.7(typescript@5.9.3): dependencies: - picomatch: 4.0.3 + picomatch: 4.0.4 typescript: 5.9.3 tsconfig-paths@3.15.0: @@ -11803,7 +12081,9 @@ snapshots: undici-types@7.16.0: {} - undici@7.24.3: {} + undici@7.24.4: {} + + undici@7.24.6: {} unenv@2.0.0-rc.24: dependencies: @@ -11877,13 +12157,13 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - vite-node@3.2.4(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2): + vite-node@3.2.4(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1) transitivePeerDependencies: - '@types/node' - jiti @@ -11898,61 +12178,61 @@ snapshots: - tsx - yaml - vite-plugin-compression2@2.5.3(rollup@4.59.0): + vite-plugin-compression2@2.5.3(rollup@4.60.0): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + '@rollup/pluginutils': 5.3.0(rollup@4.60.0) tar-mini: 0.2.0 transitivePeerDependencies: - rollup - vite-plugin-pwa@1.2.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0): + vite-plugin-pwa@1.2.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) workbox-build: 7.4.0(@types/babel__core@7.20.5) workbox-window: 7.4.0 transitivePeerDependencies: - supports-color - vite-plugin-static-copy@4.0.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): + vite-plugin-static-copy@4.0.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)): dependencies: chokidar: 3.6.0 p-map: 7.0.4 picocolors: 1.1.1 tinyglobby: 0.2.15 - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) - vite-plugin-svgr@4.5.0(rollup@4.59.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): + vite-plugin-svgr@4.5.0(rollup@4.60.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + '@rollup/pluginutils': 5.3.0(rollup@4.60.0) '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) transitivePeerDependencies: - rollup - supports-color - typescript - vite-plugin-top-level-await@1.6.0(@swc/helpers@0.5.19)(rollup@4.59.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): + vite-plugin-top-level-await@1.6.0(@swc/helpers@0.5.19)(rollup@4.60.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)): dependencies: - '@rollup/plugin-virtual': 3.0.2(rollup@4.59.0) + '@rollup/plugin-virtual': 3.0.2(rollup@4.60.0) '@swc/core': 1.15.18(@swc/helpers@0.5.19) '@swc/wasm': 1.15.18 uuid: 10.0.0 - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) transitivePeerDependencies: - '@swc/helpers' - rollup - vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.2): + vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1): dependencies: - esbuild: 0.27.3 + esbuild: 0.27.4 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.8 - rollup: 4.59.0 + rollup: 4.60.0 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.10.13 @@ -11960,9 +12240,8 @@ snapshots: jiti: 2.6.1 lightningcss: 1.32.0 terser: 5.46.1 - yaml: 2.8.2 - vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2): + vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -11971,38 +12250,37 @@ snapshots: tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.10.13 - esbuild: 0.27.3 + esbuild: 0.27.4 fsevents: 2.3.3 jiti: 2.6.1 terser: 5.46.1 - yaml: 2.8.2 - vitest@4.1.0(@types/node@24.10.13)(@vitest/ui@4.1.0)(jsdom@29.0.0)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)): + vitest@4.1.2(@types/node@24.10.13)(@vitest/ui@4.1.2)(jsdom@29.0.1)(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)): dependencies: - '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2)) - '@vitest/pretty-format': 4.1.0 - '@vitest/runner': 4.1.0 - '@vitest/snapshot': 4.1.0 - '@vitest/spy': 4.1.0 - '@vitest/utils': 4.1.0 + '@vitest/expect': 4.1.2 + '@vitest/mocker': 4.1.2(vite@8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1)) + '@vitest/pretty-format': 4.1.2 + '@vitest/runner': 4.1.2 + '@vitest/snapshot': 4.1.2 + '@vitest/spy': 4.1.2 + '@vitest/utils': 4.1.2 es-module-lexer: 2.0.0 expect-type: 1.3.0 magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 - picomatch: 4.0.3 + picomatch: 4.0.4 std-env: 4.0.0 tinybench: 2.9.0 tinyexec: 1.0.4 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.1)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.10.13)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.10.13 - '@vitest/ui': 4.1.0(vitest@4.1.0) - jsdom: 29.0.0 + '@vitest/ui': 4.1.2(vitest@4.1.2) + jsdom: 29.0.1 transitivePeerDependencies: - msw @@ -12104,14 +12382,14 @@ snapshots: workbox-build@7.4.0(@types/babel__core@7.20.5): dependencies: - '@apideck/better-ajv-errors': 0.3.6(ajv@8.18.0) + '@apideck/better-ajv-errors': 0.3.7(ajv@8.18.0) '@babel/core': 7.29.0 '@babel/preset-env': 7.29.2(@babel/core@7.29.0) '@babel/runtime': 7.29.2 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@4.59.0) - '@rollup/plugin-node-resolve': 15.3.1(rollup@4.59.0) - '@rollup/plugin-replace': 2.4.2(rollup@4.59.0) - '@rollup/plugin-terser': 0.4.4(rollup@4.59.0) + '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0) + '@rollup/plugin-node-resolve': 15.3.1(rollup@2.80.0) + '@rollup/plugin-replace': 2.4.2(rollup@2.80.0) + '@rollup/plugin-terser': 0.4.4(rollup@2.80.0) '@surma/rollup-plugin-off-main-thread': 2.2.3 ajv: 8.18.0 common-tags: 1.8.2 @@ -12120,7 +12398,7 @@ snapshots: glob: 11.1.0 lodash: 4.17.23 pretty-bytes: 5.6.0 - rollup: 4.59.0 + rollup: 2.80.0 source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 @@ -12238,9 +12516,6 @@ snapshots: yallist@3.1.1: {} - yaml@2.8.2: - optional: true - yocto-queue@0.1.0: {} youch-core@0.3.3: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index fbcf9139d..ebb82f27f 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -12,19 +12,16 @@ minimumReleaseAgeExclude: - '@sableclient/sable-call-embedded' overrides: - brace-expansion: '>=1.1.12' - esbuild: '>=0.25.0' - flatted: '>=3.4.2' - lodash: '>=4.17.23' - minimatch: '>=10.2.3' - rollup: '>=4.59.0' - serialize-javascript: '>=7.0.3' - undici: '>=7.24.0' + serialize-javascript: '>=7.0.5' + picomatch: '>=4.0.4' + smol-toml: '>=1.6.1' + yaml: '>=2.8.3' peerDependencyRules: allowedVersions: - 'folds>@vanilla-extract/css': '1.18.0' - 'folds>@vanilla-extract/recipes': '0.5.7' - 'folds>classnames': '2.5.1' - 'folds>react': '18.3.1' - 'folds>react-dom': '18.3.1' + 'folds>@vanilla-extract/css': '^1.20.1' + 'folds>@vanilla-extract/recipes': '^0.5.7' + 'folds>classnames': '^2.5.1' + 'folds>react': '^18.3.1' + 'folds>react-dom': '^18.3.1' + 'vite-plugin-pwa>vite': '^8.0.3' From ebc5e118769af71cce201353b442916858b9f974 Mon Sep 17 00:00:00 2001 From: hazre Date: Tue, 31 Mar 2026 00:04:19 +0200 Subject: [PATCH 08/11] refactor: simplify tsconfig layout --- .github/workflows/cloudflare-web-preview.yml | 4 +- .github/workflows/sentry-preview-issues.yml | 2 +- eslint.config.js | 4 +- knip.json | 7 ++- package.json | 2 +- scripts/migrate-matrix-sdk-imports.js | 6 +- scripts/normalize-imports.js | 4 +- tsconfig.build.json | 11 ---- tsconfig.json | 58 ++++---------------- tsconfig.web.json | 51 +++++++++++++++++ vite.config.ts | 2 +- 11 files changed, 79 insertions(+), 72 deletions(-) delete mode 100644 tsconfig.build.json create mode 100644 tsconfig.web.json diff --git a/.github/workflows/cloudflare-web-preview.yml b/.github/workflows/cloudflare-web-preview.yml index db6611ff2..1c768a453 100644 --- a/.github/workflows/cloudflare-web-preview.yml +++ b/.github/workflows/cloudflare-web-preview.yml @@ -8,8 +8,8 @@ on: - 'package.json' - 'package-lock.json' - 'vite.config.ts' + - 'tsconfig.web.json' - 'tsconfig.json' - - 'tsconfig.build.json' - 'tsconfig.node.json' - '.github/workflows/cloudflare-web-preview.yml' - '.github/actions/setup/**' @@ -22,8 +22,8 @@ on: - 'package.json' - 'package-lock.json' - 'vite.config.ts' + - 'tsconfig.web.json' - 'tsconfig.json' - - 'tsconfig.build.json' - 'tsconfig.node.json' - '.github/workflows/cloudflare-web-preview.yml' - '.github/actions/setup/**' diff --git a/.github/workflows/sentry-preview-issues.yml b/.github/workflows/sentry-preview-issues.yml index 31d748925..eb5077992 100644 --- a/.github/workflows/sentry-preview-issues.yml +++ b/.github/workflows/sentry-preview-issues.yml @@ -8,8 +8,8 @@ on: - 'index.html' - 'package.json' - 'vite.config.ts' + - 'tsconfig.web.json' - 'tsconfig.json' - - 'tsconfig.build.json' - 'tsconfig.node.json' workflow_dispatch: inputs: diff --git a/eslint.config.js b/eslint.config.js index 07303ad44..f7cf561c8 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -118,7 +118,7 @@ const projectOverrides = defineConfig([ 'import-x/resolver-next': [ createTypeScriptImportResolver({ alwaysTryTypes: true, - project: ['tsconfig.json', 'tsconfig.node.json'], + project: ['tsconfig.web.json', 'tsconfig.node.json'], }), ], }, @@ -165,7 +165,7 @@ const projectOverrides = defineConfig([ languageOptions: { parserOptions: { projectService: false, - project: ['tsconfig.json', 'tsconfig.node.json'], + project: ['tsconfig.web.json', 'tsconfig.node.json'], tsconfigRootDir: import.meta.dirname, }, }, diff --git a/knip.json b/knip.json index e011aaea4..f3b110164 100644 --- a/knip.json +++ b/knip.json @@ -1,7 +1,12 @@ { "$schema": "https://unpkg.com/knip@5/schema.json", "entry": ["src/sw.ts"], - "ignore": ["src/ext.d.ts", "src/types/matrix-sdk-events.d.ts"], + "ignore": [ + "src/ext.d.ts", + "src/types/matrix-sdk-events.d.ts", + "src/client/secretStorageKeys.d.ts", + "src/app/utils/bgColorImg.d.ts" + ], "ignoreExportsUsedInFile": { "interface": true, "type": true diff --git a/package.json b/package.json index 20fb1e7d7..970ad116d 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "lint:fix": "eslint . --fix", "fmt": "prettier --write .", "fmt:check": "prettier --check .", - "typecheck": "tsc -b tsconfig.build.json", + "typecheck": "tsc -b", "test": "vitest", "test:ui": "vitest --ui", "test:run": "vitest run", diff --git a/scripts/migrate-matrix-sdk-imports.js b/scripts/migrate-matrix-sdk-imports.js index ab0934874..af862aeeb 100644 --- a/scripts/migrate-matrix-sdk-imports.js +++ b/scripts/migrate-matrix-sdk-imports.js @@ -94,12 +94,12 @@ function parseArgs(argv) { * @returns {import('typescript').Program} */ function loadProgram(projectRoot) { - const tsconfigPath = path.join(projectRoot, 'tsconfig.json'); + const tsconfigPath = path.join(projectRoot, 'tsconfig.web.json'); const configResult = ts.readConfigFile(tsconfigPath, ts.sys.readFile); if (configResult.error) { const message = ts.flattenDiagnosticMessageText(configResult.error.messageText, '\n'); - throw new Error(`Failed to read tsconfig.json: ${message}`); + throw new Error(`Failed to read tsconfig.web.json: ${message}`); } const parsedConfig = ts.parseJsonConfigFileContent( @@ -114,7 +114,7 @@ function loadProgram(projectRoot) { const message = parsedConfig.errors .map((error) => ts.flattenDiagnosticMessageText(error.messageText, '\n')) .join('\n'); - throw new Error(`Failed to parse tsconfig.json:\n${message}`); + throw new Error(`Failed to parse tsconfig.web.json:\n${message}`); } return ts.createProgram({ diff --git a/scripts/normalize-imports.js b/scripts/normalize-imports.js index a8dc36b1c..2fb08797b 100644 --- a/scripts/normalize-imports.js +++ b/scripts/normalize-imports.js @@ -72,13 +72,13 @@ async function main() { const projectRoot = process.cwd(); const { write, roots } = parseArgs(process.argv.slice(2)); const aliases = await loadAliasMapFromTsconfig( - path.join(projectRoot, 'tsconfig.json'), + path.join(projectRoot, 'tsconfig.web.json'), projectRoot ); const { dim, red, green } = createTextHelpers(); if (aliases.length === 0) { - throw new Error('No aliases found in tsconfig.json'); + throw new Error('No aliases found in tsconfig.web.json'); } const targetRoots = roots.map((root) => path.resolve(projectRoot, root)); diff --git a/tsconfig.build.json b/tsconfig.build.json deleted file mode 100644 index 1195be209..000000000 --- a/tsconfig.build.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.json" - } - ] -} diff --git a/tsconfig.json b/tsconfig.json index 80d6c8ece..a41f5c356 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,51 +1,13 @@ { - "compilerOptions": { - "jsx": "react-jsx", - "target": "ESNext", - "module": "ESNext", - "lib": ["ESNext", "DOM", "DOM.Iterable"], - "allowJs": false, - "checkJs": false, - "strict": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "composite": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - "verbatimModuleSyntax": true, - "noEmit": true, - "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.tsbuildinfo", - "baseUrl": ".", - "paths": { - "$hooks": ["src/app/hooks"], - "$hooks/*": ["src/app/hooks/*"], - "$plugins": ["src/app/plugins"], - "$plugins/*": ["src/app/plugins/*"], - "$components": ["src/app/components"], - "$components/*": ["src/app/components/*"], - "$features": ["src/app/features"], - "$features/*": ["src/app/features/*"], - "$state": ["src/app/state"], - "$state/*": ["src/app/state/*"], - "$styles": ["src/app/styles"], - "$styles/*": ["src/app/styles/*"], - "$utils": ["src/app/utils"], - "$utils/*": ["src/app/utils/*"], - "$pages": ["src/app/pages"], - "$pages/*": ["src/app/pages/*"], - "$generated": ["src/app/generated"], - "$generated/*": ["src/app/generated/*"], - "$types": ["src/types"], - "$types/*": ["src/types/*"], - "$public": ["public"], - "$public/*": ["public/*"], - "$client": ["src/client"], - "$client/*": ["src/client/*"] + "extends": "./tsconfig.web.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.web.json" + }, + { + "path": "./tsconfig.node.json" } - }, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "src/**/*.js", "src/**/*.jsx"], - "exclude": ["node_modules", "dist", "coverage"] + ] } diff --git a/tsconfig.web.json b/tsconfig.web.json new file mode 100644 index 000000000..80d6c8ece --- /dev/null +++ b/tsconfig.web.json @@ -0,0 +1,51 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "target": "ESNext", + "module": "ESNext", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "allowJs": false, + "checkJs": false, + "strict": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "composite": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "noEmit": true, + "tsBuildInfoFile": "./.tsbuildinfo/tsconfig.tsbuildinfo", + "baseUrl": ".", + "paths": { + "$hooks": ["src/app/hooks"], + "$hooks/*": ["src/app/hooks/*"], + "$plugins": ["src/app/plugins"], + "$plugins/*": ["src/app/plugins/*"], + "$components": ["src/app/components"], + "$components/*": ["src/app/components/*"], + "$features": ["src/app/features"], + "$features/*": ["src/app/features/*"], + "$state": ["src/app/state"], + "$state/*": ["src/app/state/*"], + "$styles": ["src/app/styles"], + "$styles/*": ["src/app/styles/*"], + "$utils": ["src/app/utils"], + "$utils/*": ["src/app/utils/*"], + "$pages": ["src/app/pages"], + "$pages/*": ["src/app/pages/*"], + "$generated": ["src/app/generated"], + "$generated/*": ["src/app/generated/*"], + "$types": ["src/types"], + "$types/*": ["src/types/*"], + "$public": ["public"], + "$public/*": ["public/*"], + "$client": ["src/client"], + "$client/*": ["src/client/*"] + } + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "src/**/*.js", "src/**/*.jsx"], + "exclude": ["node_modules", "dist", "coverage"] +} diff --git a/vite.config.ts b/vite.config.ts index c59789218..88815ee98 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -226,7 +226,7 @@ export default defineConfig(({ command }) => ({ '@vanilla-extract/recipes/createRuntimeFn', ], needsInterop: ['matrix-widget-api'], - esbuildOptions: { + rolldownOptions: { define: { global: 'globalThis', }, From 94ba091ecf9f08c420136957289d80ba7e35253f Mon Sep 17 00:00:00 2001 From: hazre Date: Thu, 2 Apr 2026 12:47:08 +0200 Subject: [PATCH 09/11] chore: update knope installer --- .github/workflows/release.yml | 2 +- scripts/install-knope.js | 56 ++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d3314e27b..6037b7363 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: - uses: knope-dev/action@19617851f9f13ab2f27a05989c55efb18aca3675 # v2.1.2 with: - version: 0.22.3 + version: 0.22.4 - name: Create Release run: knope release --verbose diff --git a/scripts/install-knope.js b/scripts/install-knope.js index 4b8d0118a..27e7bb609 100644 --- a/scripts/install-knope.js +++ b/scripts/install-knope.js @@ -1,5 +1,6 @@ #!/usr/bin/env node import { spawnSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; import process from 'node:process'; import { chmodSync, existsSync, mkdirSync, realpathSync, writeFileSync } from 'node:fs'; import { join, dirname, resolve, sep } from 'node:path'; @@ -10,18 +11,37 @@ import { PrefixedLogger, createTextHelpers } from './utils/console-style.js'; const __dirname = dirname(fileURLToPath(import.meta.url)); -const VERSION = '0.22.3'; +const VERSION = '0.22.4'; /** * @typedef {'linux-x64' | 'linux-arm64' | 'darwin-x64' | 'darwin-arm64' | 'win32-x64'} SupportedTargetKey */ -/** @type {Record} */ +/** + * Pinned to the published release asset digests for knope. + * Source: GitHub release asset metadata at publish time. + * @type {Record} + */ const TARGETS = { - 'linux-x64': 'x86_64-unknown-linux-musl', - 'linux-arm64': 'aarch64-unknown-linux-musl', - 'darwin-x64': 'x86_64-apple-darwin', - 'darwin-arm64': 'aarch64-apple-darwin', - 'win32-x64': 'x86_64-pc-windows-msvc', + 'linux-x64': { + target: 'x86_64-unknown-linux-musl', + digest: 'sha256:45a74925ae9f4c9c2c33b51992ae50241ec4fa836bf8d2977c0b8e8172dd69cf', + }, + 'linux-arm64': { + target: 'aarch64-unknown-linux-musl', + digest: 'sha256:95e882afdb4154c5baaba91f7bbd1fb1d41cec6898363a2b30e7abad4057b83b', + }, + 'darwin-x64': { + target: 'x86_64-apple-darwin', + digest: 'sha256:010dc197bf159bbd9d60e897252248ba2b0e204beae7250ce54a9deae1ec4876', + }, + 'darwin-arm64': { + target: 'aarch64-apple-darwin', + digest: 'sha256:02131f284315c8ece8a4ef69a0aff5f658309d4df73b95cfdfbe0fbd9e9ce259', + }, + 'win32-x64': { + target: 'x86_64-pc-windows-msvc', + digest: 'sha256:09f735b2da42cd594189042d1379c0a3a350a8c0ccb741015a84c6ff334543b1', + }, }; /** @@ -150,6 +170,14 @@ function isPathWithin(candidatePath, rootPath) { return candidate === root || candidate.startsWith(`${root}${sep}`); } +/** + * @param {Buffer} buffer + * @returns {string} + */ +function getSha256Digest(buffer) { + return `sha256:${createHash('sha256').update(buffer).digest('hex')}`; +} + const logger = new PrefixedLogger('[postinstall:knope]'); const { dim, red, green } = createTextHelpers({ useColor: logger.useColor }); @@ -159,16 +187,17 @@ if (process.env.GITHUB_ACTIONS && process.env.CI) { } const targetKey = `${process.platform}-${process.arch}`; -const target = Object.hasOwn(TARGETS, targetKey) +const targetConfig = Object.hasOwn(TARGETS, targetKey) ? TARGETS[/** @type {SupportedTargetKey} */ (targetKey)] : undefined; -if (!target) { +if (!targetConfig) { const supported = Object.keys(TARGETS).join(', '); logger.error( `${dim('Unsupported platform: ')}${red(`${process.platform}-${process.arch}`)}${dim('. Supported targets: ')}${supported}` ); process.exit(1); } +const { target, digest: expectedDigest } = targetConfig; const bin = join( __dirname, @@ -214,7 +243,8 @@ if (systemKnopePath) { } } -const url = `https://github.com/knope-dev/knope/releases/download/knope%2Fv${VERSION}/knope-${target}.tgz`; +const assetName = `knope-${target}.tgz`; +const url = `https://github.com/knope-dev/knope/releases/download/knope%2Fv${VERSION}/${assetName}`; logger.info( `${dim('Downloading knope ')}${green(`v${VERSION}`)}${dim(' for ')}${target}${dim('...')}` ); @@ -223,6 +253,12 @@ if (!response.ok) { throw new Error(`Failed to download knope: ${response.status} ${response.statusText}`); } const gzipBytes = Buffer.from(await response.arrayBuffer()); +const actualDigest = getSha256Digest(gzipBytes); +if (actualDigest !== expectedDigest) { + throw new Error( + `Downloaded ${assetName} digest mismatch: expected ${expectedDigest}, got ${actualDigest}` + ); +} const tarBytes = gunzipSync(gzipBytes); const expectedBinaryName = process.platform === 'win32' ? 'knope.exe' : 'knope'; const knopeBinary = extractRegularFileFromTar(tarBytes, expectedBinaryName); From cfa52ddc243ce941b528348717ec2e68233619ab Mon Sep 17 00:00:00 2001 From: hazre Date: Thu, 2 Apr 2026 12:48:53 +0200 Subject: [PATCH 10/11] chore: update github actions --- .github/actions/prepare-tofu/action.yml | 2 +- .github/actions/setup/action.yml | 2 +- .github/workflows/docker-publish.yml | 10 +++++----- .github/workflows/quality-checks.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/prepare-tofu/action.yml b/.github/actions/prepare-tofu/action.yml index c64332e3c..dcb95842c 100644 --- a/.github/actions/prepare-tofu/action.yml +++ b/.github/actions/prepare-tofu/action.yml @@ -28,7 +28,7 @@ runs: SENTRY_PROJECT: ${{ env.SENTRY_PROJECT }} - name: Setup OpenTofu - uses: opentofu/setup-opentofu@9d84900f3238fab8cd84ce47d658d25dd008be2f # v1.0.8 + uses: opentofu/setup-opentofu@fc711fa910b93cba0f3fbecaafc9f42fd0c411cb # v2.0.0 with: tofu_version: ${{ inputs.opentofu-version }} diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 9b4c9acbb..f7d1e4180 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -19,7 +19,7 @@ runs: using: composite steps: - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 03a63ef99..540ded829 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -39,7 +39,7 @@ jobs: - name: Log in to GitHub Container Registry if: github.event_name != 'pull_request' - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -64,7 +64,7 @@ jobs: - name: Extract metadata id: meta - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} flavor: | @@ -94,14 +94,14 @@ jobs: NODE_OPTIONS=--max_old_space_size=4096 pnpm run build - name: Set up QEMU - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Build and push Docker image id: push - uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: context: . push: ${{ github.event_name != 'pull_request' }} diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 5d56101fd..b1d8f99e1 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -151,7 +151,7 @@ jobs: fi - name: Update PR comment - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 continue-on-error: true with: script: | From 800044a109c9a9776791134d6a45b81faab1b572 Mon Sep 17 00:00:00 2001 From: hazre Date: Thu, 2 Apr 2026 14:06:11 +0200 Subject: [PATCH 11/11] fix: resolve PR check failures --- scripts/utils/import-rewrites.js | 2 +- src/app/components/power/PowerIcon.tsx | 25 ++++-- .../components/url-preview/ClientPreview.tsx | 4 +- .../user-profile/UserRoomProfile.tsx | 3 +- src/app/hooks/useCommands.ts | 10 +-- src/app/utils/sanitize.test.ts | 12 ++- src/app/utils/sanitize.ts | 82 ++++++++++++++++++- src/sw.ts | 4 +- 8 files changed, 120 insertions(+), 22 deletions(-) diff --git a/scripts/utils/import-rewrites.js b/scripts/utils/import-rewrites.js index 5f4be69b0..376a3cfb0 100644 --- a/scripts/utils/import-rewrites.js +++ b/scripts/utils/import-rewrites.js @@ -55,7 +55,7 @@ export const MATRIX_IMPORT_BOUNDARY_FILES = new Set([ * @returns {string} */ export function toPosix(inputPath) { - return inputPath.split(path.sep).join('/'); + return inputPath.replace(/\\/g, '/'); } /** diff --git a/src/app/components/power/PowerIcon.tsx b/src/app/components/power/PowerIcon.tsx index f86331035..69bb3e90c 100644 --- a/src/app/components/power/PowerIcon.tsx +++ b/src/app/components/power/PowerIcon.tsx @@ -5,10 +5,25 @@ type PowerIconProps = css.PowerIconVariants & { iconSrc: string; name?: string; }; + +const ALLOWED_ICON_PROTOCOLS = new Set(['http:', 'https:']); + +function getSafeIconUrl(iconSrc: string): string | undefined { + try { + const parsed = new URL(iconSrc); + return ALLOWED_ICON_PROTOCOLS.has(parsed.protocol) ? parsed.href : undefined; + } catch { + return undefined; + } +} + export function PowerIcon({ size, iconSrc, name }: PowerIconProps) { - return JUMBO_EMOJI_REG.test(iconSrc) ? ( - {iconSrc} - ) : ( - {name} - ); + if (JUMBO_EMOJI_REG.test(iconSrc)) { + return {iconSrc}; + } + + const safeIconUrl = getSafeIconUrl(iconSrc); + if (!safeIconUrl) return null; + + return {name}; } diff --git a/src/app/components/url-preview/ClientPreview.tsx b/src/app/components/url-preview/ClientPreview.tsx index 9921fd3f8..8dbcb0bdb 100644 --- a/src/app/components/url-preview/ClientPreview.tsx +++ b/src/app/components/url-preview/ClientPreview.tsx @@ -167,7 +167,7 @@ function parseYoutubeLink(url: Readonly): YoutubeLink | null { // new URL can throw return null; } - const urlHost = parsedURL.host; + const urlHost = parsedURL.hostname.toLowerCase(); const urlSearchParams = parsedURL.searchParams; /** @@ -203,7 +203,7 @@ function parseYoutubeLink(url: Readonly): YoutubeLink | null { videoId, timestamp, playlist, - isMusic: url.includes('music.youtube.com'), + isMusic: urlHost === 'music.youtube.com' || urlHost.endsWith('.music.youtube.com'), }; } diff --git a/src/app/components/user-profile/UserRoomProfile.tsx b/src/app/components/user-profile/UserRoomProfile.tsx index 20cec6b51..b756810f9 100644 --- a/src/app/components/user-profile/UserRoomProfile.tsx +++ b/src/app/components/user-profile/UserRoomProfile.tsx @@ -33,6 +33,7 @@ import { useSpoilerClickHandler } from '$hooks/useSpoilerClickHandler'; import { RenderBody } from '$components/message'; import { getSettings, settingsAtom } from '$state/settings'; import { filterPronounsByLanguage } from '$utils/pronouns'; +import { extractPlainTextFromCustomHtml } from '$utils/sanitize'; import { useSetting } from '$state/hooks/settings'; import { useSettingsLinkBaseUrl } from '$features/settings/useSettingsLinkBaseUrl'; import { CreatorChip } from './CreatorChip'; @@ -134,7 +135,7 @@ function UserExtendedSection({ const safetyTrim = rawBio.length > 2048 ? rawBio.slice(0, 2048) : rawBio; - const visibleText = safetyTrim.replaceAll(/<[^>]*>?/gm, ''); + const visibleText = extractPlainTextFromCustomHtml(safetyTrim); const VISIBLE_LIMIT = 1024; if (visibleText.length <= VISIBLE_LIMIT) { diff --git a/src/app/hooks/useCommands.ts b/src/app/hooks/useCommands.ts index cba409952..b402164df 100644 --- a/src/app/hooks/useCommands.ts +++ b/src/app/hooks/useCommands.ts @@ -31,6 +31,7 @@ import { settingsAtom } from '$state/settings'; import { useOpenBugReportModal } from '$state/hooks/bugReportModal'; import { createRoomEncryptionState } from '$components/create-room'; import { parsePronounsInput } from '$utils/pronouns'; +import { extractPlainTextFromCustomHtml } from '$utils/sanitize'; import { sendFeedback } from '$utils/sendFeedbackToUser'; import { PKitCommandMessageHandler } from '$plugins/pluralkit-handler/PKitCommandMessageHandler'; import { useRoomNavigate } from './useRoomNavigate'; @@ -1352,14 +1353,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { exe: async (payload) => { await mx.sendMessage(room.roomId, { msgtype: MsgType.Text, - body: payload - .replaceAll('
', '\n') - .replaceAll('
  • ', '\n- ') - .replaceAll( - /(.*?))"(.*?)>(?(.*?))<\/a>/g, - '[$]($)' - ) - .replaceAll(/<[^>]*>/g, ''), + body: extractPlainTextFromCustomHtml(payload), format: 'org.matrix.custom.html', formatted_body: payload, }); diff --git a/src/app/utils/sanitize.test.ts b/src/app/utils/sanitize.test.ts index c1332cfc7..fce7c1f4e 100644 --- a/src/app/utils/sanitize.test.ts +++ b/src/app/utils/sanitize.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { sanitizeCustomHtml } from './sanitize'; +import { extractPlainTextFromCustomHtml, sanitizeCustomHtml } from './sanitize'; describe('sanitizeCustomHtml', () => { it('keeps permitted Matrix v1.18 tags', () => { @@ -138,3 +138,13 @@ describe('sanitizeCustomHtml', () => { expect((result.match(/
    /g) ?? []).length).toBeLessThanOrEqual(100); }); }); + +describe('extractPlainTextFromCustomHtml', () => { + it('converts sanitized html into readable plain text', () => { + const result = extractPlainTextFromCustomHtml( + '

    Hello
    world

    • One
    • Two
    ' + ); + + expect(result).toBe('Hello\nworld\n- One\n- Two'); + }); +}); diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts index f7106fdc4..1111e3dce 100644 --- a/src/app/utils/sanitize.ts +++ b/src/app/utils/sanitize.ts @@ -78,6 +78,31 @@ const forbiddenContentTags = ['mx-reply', 'script', 'style', 'textarea', 'option const codeLanguageClassRegex = /^language-[A-Za-z0-9_-]+$/; const orderedListStartRegex = /^-?\d+$/; const allowedUriRegex = /^(?:https?|ftp|mailto|magnet|mxc):/i; +const textBlockTags = new Set([ + 'blockquote', + 'caption', + 'details', + 'div', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'li', + 'ol', + 'p', + 'pre', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr', + 'ul', +]); export function sanitizeText(body: string): string { const tagsToReplace: Record = { @@ -273,7 +298,7 @@ const pruneInvalidEmptyElements = ( }); }; -export const sanitizeCustomHtml = (customHtml: string): string => { +export function sanitizeCustomHtml(customHtml: string): string { if (typeof window === 'undefined') { return sanitizeText(customHtml); } @@ -345,4 +370,57 @@ export const sanitizeCustomHtml = (customHtml: string): string => { const container = document.createElement('div'); container.append(fragment); return restoreProtectedImageSources(container.innerHTML, protectedSources); -}; +} + +function appendPlainTextLineBreak(parts: string[]) { + const previous = parts.at(-1); + if (previous?.endsWith('\n')) return; + parts.push('\n'); +} + +function collectPlainTextFromNode(node: Node, parts: string[]): void { + if (node.nodeType === Node.TEXT_NODE) { + const text = node.textContent; + if (text) parts.push(text); + return; + } + + if (!(node instanceof Element)) return; + + const tagName = node.tagName.toLowerCase(); + + if (tagName === 'br') { + appendPlainTextLineBreak(parts); + return; + } + + if (tagName === 'li') { + parts.push('- '); + } + + [...node.childNodes].forEach((child) => collectPlainTextFromNode(child, parts)); + + if (textBlockTags.has(tagName)) { + appendPlainTextLineBreak(parts); + } +} + +export function extractPlainTextFromCustomHtml(customHtml: string): string { + if (typeof DOMParser === 'undefined') { + return customHtml; + } + + const parser = new DOMParser(); + const doc = parser.parseFromString(sanitizeCustomHtml(customHtml), 'text/html'); + const parts: string[] = []; + + [...doc.body.childNodes].forEach((child) => collectPlainTextFromNode(child, parts)); + + return parts + .join('') + .replace(/\r\n?/g, '\n') + .replace(/\u00a0/g, ' ') + .replace(/[ \t]+\n/g, '\n') + .replace(/\n{3,}/g, '\n\n') + .trim(); +} diff --git a/src/sw.ts b/src/sw.ts index 682491c19..f3266b7a5 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -164,7 +164,7 @@ function setSession(clientId: string, accessToken: unknown, baseUrl: unknown, us } const resolveSession = clientToResolve.get(clientId); - if (resolveSession) { + if (typeof resolveSession === 'function') { resolveSession(sessions.get(clientId)); clientToResolve.delete(clientId); clientToSessionPromise.delete(clientId); @@ -562,7 +562,7 @@ self.addEventListener('message', (event: ExtendableMessageEvent) => { const { eventId } = data as { eventId?: string }; if (typeof eventId === 'string') { const resolve = decryptionPendingMap.get(eventId); - if (resolve) { + if (typeof resolve === 'function') { decryptionPendingMap.delete(eventId); resolve(data as DecryptionResult); }