diff --git a/src/frontend/index.html b/src/frontend/index.html index f4720d6d..d6a3eff2 100644 --- a/src/frontend/index.html +++ b/src/frontend/index.html @@ -6,22 +6,6 @@ - - - - %VITE_APP_TITLE% diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 8f6d7ff5..9fee6bd1 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -10,8 +10,6 @@ "dependencies": { "@fontsource-variable/atkinson-hyperlegible-next": "5.2.6", "@fontsource-variable/lexend": "5.2.11", - "@fontsource-variable/material-symbols-outlined": "5.2.34", - "@fontsource/material-icons-outlined": "5.2.6", "@fontsource/opendyslexic": "5.2.5", "@livekit/components-react": "2.9.19", "@livekit/components-styles": "1.2.0", @@ -61,6 +59,7 @@ "rollup-plugin-visualizer": "7.0.1", "typescript": "5.8.3", "vite": "7.3.2", + "vite-plugin-svgr": "5.2.0", "vite-tsconfig-paths": "6.1.1" } }, @@ -1012,24 +1011,6 @@ "url": "https://github.com/sponsors/ayuhito" } }, - "node_modules/@fontsource-variable/material-symbols-outlined": { - "version": "5.2.34", - "resolved": "https://registry.npmjs.org/@fontsource-variable/material-symbols-outlined/-/material-symbols-outlined-5.2.34.tgz", - "integrity": "sha512-FfJVoKdYlxvIHflVZlrevf6e1WmbJGeAdbcLmOmkftoP2Du0qrRD/SmNchIXijsKXF7j3z1m++e92Qi6/U+jRA==", - "license": "OFL-1.1", - "funding": { - "url": "https://github.com/sponsors/ayuhito" - } - }, - "node_modules/@fontsource/material-icons-outlined": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@fontsource/material-icons-outlined/-/material-icons-outlined-5.2.6.tgz", - "integrity": "sha512-99XKAkwnCg0s0/ywax+o3m01HSNM5gGzSBw+WnlWG2+WY3wOjcN+wXMfm4zP37Yme7Yze2DvKxF78tHWOrlwFw==", - "license": "OFL-1.1", - "funding": { - "url": "https://github.com/sponsors/ayuhito" - } - }, "node_modules/@fontsource/opendyslexic": { "version": "5.2.5", "resolved": "https://registry.npmjs.org/@fontsource/opendyslexic/-/opendyslexic-5.2.5.tgz", @@ -4106,6 +4087,42 @@ "dev": true, "license": "MIT" }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", @@ -4456,6 +4473,231 @@ "win32" ] }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, "node_modules/@swc/helpers": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", @@ -5880,6 +6122,19 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001774", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz", @@ -6190,6 +6445,33 @@ "url": "https://opencollective.com/express" } }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/crisp-sdk-web": { "version": "1.0.27", "resolved": "https://registry.npmjs.org/crisp-sdk-web/-/crisp-sdk-web-1.0.27.tgz", @@ -6543,6 +6825,17 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -6621,6 +6914,16 @@ "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==" }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -8250,6 +8553,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -8643,6 +8953,13 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -9032,6 +9349,13 @@ "url": "https://github.com/sponsors/antonk52" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, "node_modules/livekit-client": { "version": "2.17.1", "resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-2.17.1.tgz", @@ -9138,6 +9462,16 @@ "loose-envify": "cli.js" } }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -9352,6 +9686,17 @@ "node": ">= 0.6" } }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node_modules/node-eval": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/node-eval/-/node-eval-2.0.0.tgz", @@ -9610,6 +9955,25 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -9702,6 +10066,16 @@ "url": "https://opencollective.com/express" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -10928,6 +11302,17 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/sort-keys": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.1.0.tgz", @@ -11115,6 +11500,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true, + "license": "MIT" + }, "node_modules/symlink-or-copy": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz", @@ -11823,6 +12215,21 @@ } } }, + "node_modules/vite-plugin-svgr": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-5.2.0.tgz", + "integrity": "sha512-qj2eAKF8C6PZWemVTvQA0xgQIcP1hHU6Buh7fl6BhvayWwnuxE+z417miKxeDvRWbDrupQ1oK99hfxElopJ3sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.3.0", + "@svgr/core": "^8.1.0", + "@svgr/plugin-jsx": "^8.1.0" + }, + "peerDependencies": { + "vite": ">=3.0.0" + } + }, "node_modules/vite-tsconfig-paths": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-6.1.1.tgz", diff --git a/src/frontend/package.json b/src/frontend/package.json index 993753f6..d3f8033a 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -16,8 +16,6 @@ "dependencies": { "@fontsource-variable/atkinson-hyperlegible-next": "5.2.6", "@fontsource-variable/lexend": "5.2.11", - "@fontsource-variable/material-symbols-outlined": "5.2.34", - "@fontsource/material-icons-outlined": "5.2.6", "@fontsource/opendyslexic": "5.2.5", "@livekit/components-react": "2.9.19", "@livekit/components-styles": "1.2.0", @@ -67,6 +65,7 @@ "rollup-plugin-visualizer": "7.0.1", "typescript": "5.8.3", "vite": "7.3.2", + "vite-plugin-svgr": "5.2.0", "vite-tsconfig-paths": "6.1.1" } } diff --git a/src/frontend/src/assets/icons/article.svg b/src/frontend/src/assets/icons/article.svg new file mode 100644 index 00000000..9cd25255 --- /dev/null +++ b/src/frontend/src/assets/icons/article.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/chevron_forward.svg b/src/frontend/src/assets/icons/chevron_forward.svg new file mode 100644 index 00000000..976b2ae4 --- /dev/null +++ b/src/frontend/src/assets/icons/chevron_forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/cloud_download.svg b/src/frontend/src/assets/icons/cloud_download.svg new file mode 100644 index 00000000..d45089bc --- /dev/null +++ b/src/frontend/src/assets/icons/cloud_download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/language.svg b/src/frontend/src/assets/icons/language.svg new file mode 100644 index 00000000..f851a272 --- /dev/null +++ b/src/frontend/src/assets/icons/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/login.svg b/src/frontend/src/assets/icons/login.svg new file mode 100644 index 00000000..ddc929be --- /dev/null +++ b/src/frontend/src/assets/icons/login.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/mail.svg b/src/frontend/src/assets/icons/mail.svg new file mode 100644 index 00000000..82e6eb1e --- /dev/null +++ b/src/frontend/src/assets/icons/mail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/mode_standby.svg b/src/frontend/src/assets/icons/mode_standby.svg new file mode 100644 index 00000000..f9c74c99 --- /dev/null +++ b/src/frontend/src/assets/icons/mode_standby.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/person_raised_hand.svg b/src/frontend/src/assets/icons/person_raised_hand.svg new file mode 100644 index 00000000..4b89fe3a --- /dev/null +++ b/src/frontend/src/assets/icons/person_raised_hand.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/screen_record.svg b/src/frontend/src/assets/icons/screen_record.svg new file mode 100644 index 00000000..1934b235 --- /dev/null +++ b/src/frontend/src/assets/icons/screen_record.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/assets/icons/speech_to_text.svg b/src/frontend/src/assets/icons/speech_to_text.svg new file mode 100644 index 00000000..ef9a538a --- /dev/null +++ b/src/frontend/src/assets/icons/speech_to_text.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/features/recording/components/LoginPrompt.tsx b/src/frontend/src/features/recording/components/LoginPrompt.tsx index e46740ba..cdc7edf0 100644 --- a/src/frontend/src/features/recording/components/LoginPrompt.tsx +++ b/src/frontend/src/features/recording/components/LoginPrompt.tsx @@ -24,7 +24,7 @@ export const LoginPrompt = ({ heading, body }: LoginPromptProps) => { })} > - + {heading} diff --git a/src/frontend/src/features/recording/components/RecordingStatusIcon.tsx b/src/frontend/src/features/recording/components/RecordingStatusIcon.tsx index 7bf65cb9..bc0f109f 100644 --- a/src/frontend/src/features/recording/components/RecordingStatusIcon.tsx +++ b/src/frontend/src/features/recording/components/RecordingStatusIcon.tsx @@ -15,8 +15,8 @@ export const RecordingStatusIcon = ({ } if (isTranscriptActive) { - return + return } - return + return } diff --git a/src/frontend/src/features/recording/components/RequestRecording.tsx b/src/frontend/src/features/recording/components/RequestRecording.tsx index 8af710bd..7135355d 100644 --- a/src/frontend/src/features/recording/components/RequestRecording.tsx +++ b/src/frontend/src/features/recording/components/RequestRecording.tsx @@ -59,7 +59,7 @@ export const RequestRecording = ({ })} > - + {heading} diff --git a/src/frontend/src/features/recording/components/RowWrapper.tsx b/src/frontend/src/features/recording/components/RowWrapper.tsx index f94140a0..6d7038c1 100644 --- a/src/frontend/src/features/recording/components/RowWrapper.tsx +++ b/src/frontend/src/features/recording/components/RowWrapper.tsx @@ -45,7 +45,6 @@ export const RowWrapper = ({ paddingInline: '0.25rem', })} > - {/* fixme - doesn't handle properly material-symbols */}
- +
) @@ -168,7 +168,7 @@ export const Tools = () => { {isTranscriptEnabled && ( } + icon={} title={t('tools.transcript.title')} description={t('tools.transcript.body')} onPress={() => openTranscript()} @@ -176,7 +176,7 @@ export const Tools = () => { )} {isScreenRecordingEnabled && ( } + icon={} title={t('tools.screenRecording.title')} description={t('tools.screenRecording.body')} onPress={() => openScreenRecording()} diff --git a/src/frontend/src/features/settings/components/SettingsDialogExtended.tsx b/src/frontend/src/features/settings/components/SettingsDialogExtended.tsx index ed4a782b..5f6f6cca 100644 --- a/src/frontend/src/features/settings/components/SettingsDialogExtended.tsx +++ b/src/frontend/src/features/settings/components/SettingsDialogExtended.tsx @@ -116,7 +116,7 @@ export const SettingsDialogExtended = (props: SettingsDialogExtended) => { {isAdminOrOwner && ( - + {isWideScreen && t(`tabs.${SettingsDialogExtendedKey.TRANSCRIPTION}`)} diff --git a/src/frontend/src/main.tsx b/src/frontend/src/main.tsx index ee1483ae..ed319314 100644 --- a/src/frontend/src/main.tsx +++ b/src/frontend/src/main.tsx @@ -2,9 +2,6 @@ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' -// Supports weights 100-700 -import '@fontsource-variable/material-symbols-outlined' - ReactDOM.createRoot(document.getElementById('root')!).render( diff --git a/src/frontend/src/primitives/Icon.tsx b/src/frontend/src/primitives/Icon.tsx index 7275fad0..9f64b095 100644 --- a/src/frontend/src/primitives/Icon.tsx +++ b/src/frontend/src/primitives/Icon.tsx @@ -1,48 +1,43 @@ import { cva, RecipeVariantProps } from '@/styled-system/css' -import { ComponentPropsWithoutRef } from 'react' +import { ComponentPropsWithoutRef, FunctionComponent, SVGProps } from 'react' + +// Eagerly import every .svg in the icons folder as a React component. +// Drop a new file in /assets/icons and it's available immediately. +const modules = import.meta.glob<{ + default: FunctionComponent> +}>('../assets/icons/*.svg', { eager: true, query: '?react', import: 'default' }) + +// Build the registry: { 'chevron-down': Component, 'check': Component, ... } +// Key = filename without extension. +const icons = Object.fromEntries( + Object.entries(modules).map(([path, mod]) => { + const name = path + .split('/') + .pop()! + .replace(/\.svg$/, '') + return [name, mod as unknown as FunctionComponent>] + }) +) as Record>> + +export type IconName = keyof typeof icons const iconRecipe = cva({ base: { - fontWeight: 'normal', - fontStyle: 'normal', display: 'inline-block', + flexShrink: 0, lineHeight: 1, - textTransform: 'none', - letterSpacing: 'normal', - wordWrap: 'normal', - whiteSpace: 'nowrap', - direction: 'ltr', + color: 'currentColor', + fill: 'currentColor', }, variants: { - type: { - icons: { - fontFamily: 'Material Icons Outlined', - webkitFontSmoothing: 'antialiased', - mozOsxFontSmoothing: 'grayscale', - textRendering: 'optimizeLegibility', - fontFeatureSettings: '"liga"', - }, - symbols: { - fontFamily: 'Material Symbols Outlined Variable', - }, - }, size: { - sm: { - fontSize: '18px', - }, - md: { - fontSize: '24px', - }, - lg: { - fontSize: '32px', - }, - xl: { - fontSize: '40px', - }, + sm: { width: '18px', height: '18px' }, + md: { width: '24px', height: '24px' }, + lg: { width: '32px', height: '32px' }, + xl: { width: '40px', height: '40px' }, }, }, defaultVariants: { - type: 'icons', size: 'md', }, }) @@ -50,22 +45,33 @@ const iconRecipe = cva({ export type IconRecipeProps = RecipeVariantProps export type IconProps = IconRecipeProps & - ComponentPropsWithoutRef<'span'> & { - name: string + Omit, 'name'> & { + name: IconName } export const Icon = ({ name, ...props }: IconProps) => { const [variantProps, componentProps] = iconRecipe.splitVariantProps(props) - const { className, ...remainingComponentProps } = componentProps + const { className, ...rest } = componentProps + + const SvgIcon = icons[name] + + if (!SvgIcon) { + if (process.env.NODE_ENV !== 'production') { + console.warn( + `[Icon] Unknown icon name: "${name}". Available: ${Object.keys(icons).join(', ')}` + ) + } + return null + } return ( - + focusable="false" + className={[iconRecipe(variantProps), className] + .filter(Boolean) + .join(' ')} + {...rest} + /> ) } diff --git a/src/frontend/src/styles/index.css b/src/frontend/src/styles/index.css index 8944fe9a..69019621 100644 --- a/src/frontend/src/styles/index.css +++ b/src/frontend/src/styles/index.css @@ -76,39 +76,6 @@ html:has(.lk-video-conference) { } } -/* Generated using the Advanced installation guidelines from - * https://fontsource.org/fonts/material-icons-outlined/install - */ -@font-face { - font-family: 'Material Icons Outlined'; - font-style: normal; - font-display: block; - font-weight: 400; - src: url(@fontsource/material-icons-outlined/files/material-icons-outlined-latin-400-normal.woff2) - format('woff2'); - unicode-range: - U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, - U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, - U+2212, U+2215, U+FEFF, U+FFFD; -} - -/* Generated using the Advanced installation guidelines from - * https://fontsource.org/fonts/material-symbols-outlined/install - */ -/* material-symbols-outlined-latin-wght-normal */ -@font-face { - font-family: 'Material Symbols Outlined Variable'; - font-style: normal; - font-display: block; - font-weight: 100 700; - src: url(@fontsource-variable/material-symbols-outlined/files/material-symbols-outlined-latin-wght-normal.woff2) - format('woff2-variations'); - unicode-range: - U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, - U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, - U+2212, U+2215, U+FEFF, U+FFFD; -} - .hoverGroup .hoverGroupChild { opacity: 0; pointer-events: none; diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts index cfef2a31..a0258422 100644 --- a/src/frontend/vite.config.ts +++ b/src/frontend/vite.config.ts @@ -2,6 +2,7 @@ import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' import tsconfigPaths from 'vite-tsconfig-paths' import { visualizer } from 'rollup-plugin-visualizer' +import svgr from 'vite-plugin-svgr' // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { @@ -10,6 +11,11 @@ export default defineConfig(({ mode }) => { plugins: [ react(), tsconfigPaths(), + svgr({ + svgrOptions: { + replaceAttrValues: { '#000': 'currentColor', '#000000': 'currentColor', '#1f1f1f': 'currentColor' }, + }, + }), env.VITE_ANALYZE === 'true' && visualizer({ open: true, filename: 'rollup-plugin-visualizer/stats.html',