add: settings window

This commit is contained in:
alikia2x (寒寒) 2024-11-27 22:39:48 +08:00
parent 0a7a8eeffc
commit 2c6c07647a
Signed by: alikia2x
GPG Key ID: 56209E0CCD8420C6
24 changed files with 532 additions and 228 deletions

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

3
i18n/ar.json Executable file
View File

@ -0,0 +1,3 @@
{
}

2
i18n/de.json Executable file
View File

@ -0,0 +1,2 @@
{
}

3
i18n/en.json Executable file
View File

@ -0,0 +1,3 @@
{
"settings": "Settings"
}

2
i18n/es.json Executable file
View File

@ -0,0 +1,2 @@
{
}

2
i18n/fr.json Executable file
View File

@ -0,0 +1,2 @@
{
}

2
i18n/it.json Executable file
View File

@ -0,0 +1,2 @@
{
}

3
i18n/ja.json Normal file
View File

@ -0,0 +1,3 @@
{
}

3
i18n/ko.json Executable file
View File

@ -0,0 +1,3 @@
{
}

3
i18n/zh.json Normal file
View File

@ -0,0 +1,3 @@
{
"settings": "设置"
}

View File

@ -3,7 +3,6 @@
"version": "1.0.0", "version": "1.0.0",
"type": "module", "type": "module",
"description": "", "description": "",
"main": "src/main.js",
"scripts": { "scripts": {
"dev": "cross-env NODE_ENV=dev bun run dev:all", "dev": "cross-env NODE_ENV=dev bun run dev:all",
"dev:all": "concurrently -n=react,electron -c='#ff3e00',blue \"bun run dev:react\" \"bun run dev:electron\"", "dev:all": "concurrently -n=react,electron -c='#ff3e00',blue \"bun run dev:react\" \"bun run dev:electron\"",
@ -19,8 +18,14 @@
"electron-reloader": "^1.2.3", "electron-reloader": "^1.2.3",
"electron-serve": "^2.1.1", "electron-serve": "^2.1.1",
"electron-window-state": "^5.0.3", "electron-window-state": "^5.0.3",
"i18next": "^24.0.2",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-icu": "^2.3.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1" "react-dom": "^18.3.1",
"react-i18next": "^15.1.2",
"react-router-dom": "^7.0.1",
"vite-tsconfig-paths": "^5.1.3"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.13.0", "@eslint/js": "^9.13.0",

10
pages/settings/index.tsx Normal file
View File

@ -0,0 +1,10 @@
import { useTranslation } from "react-i18next";
export default function SettingsPage() {
const { t } = useTranslation();
return (
<div>
<h1>{t('settings')}</h1>
</div>
)
}

View File

@ -23,12 +23,30 @@ importers:
electron-window-state: electron-window-state:
specifier: ^5.0.3 specifier: ^5.0.3
version: 5.0.3 version: 5.0.3
i18next:
specifier: ^24.0.2
version: 24.0.2(typescript@5.6.3)
i18next-browser-languagedetector:
specifier: ^8.0.0
version: 8.0.0
i18next-icu:
specifier: ^2.3.0
version: 2.3.0(intl-messageformat@10.7.7)
react: react:
specifier: ^18.3.1 specifier: ^18.3.1
version: 18.3.1 version: 18.3.1
react-dom: react-dom:
specifier: ^18.3.1 specifier: ^18.3.1
version: 18.3.1(react@18.3.1) version: 18.3.1(react@18.3.1)
react-i18next:
specifier: ^15.1.2
version: 15.1.2(i18next@24.0.2(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-router-dom:
specifier: ^7.0.1
version: 7.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
vite-tsconfig-paths:
specifier: ^5.1.3
version: 5.1.3(typescript@5.6.3)(vite@5.4.11(@types/node@20.17.7))
devDependencies: devDependencies:
'@eslint/js': '@eslint/js':
specifier: ^9.13.0 specifier: ^9.13.0
@ -50,13 +68,13 @@ importers:
version: 7.0.3 version: 7.0.3
eslint: eslint:
specifier: ^9.13.0 specifier: ^9.13.0
version: 9.15.0 version: 9.15.0(jiti@1.21.6)
eslint-plugin-react-hooks: eslint-plugin-react-hooks:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.0.0(eslint@9.15.0) version: 5.0.0(eslint@9.15.0(jiti@1.21.6))
eslint-plugin-react-refresh: eslint-plugin-react-refresh:
specifier: ^0.4.14 specifier: ^0.4.14
version: 0.4.14(eslint@9.15.0) version: 0.4.14(eslint@9.15.0(jiti@1.21.6))
globals: globals:
specifier: ^15.11.0 specifier: ^15.11.0
version: 15.12.0 version: 15.12.0
@ -65,7 +83,7 @@ importers:
version: 5.6.3 version: 5.6.3
typescript-eslint: typescript-eslint:
specifier: ^8.11.0 specifier: ^8.11.0
version: 8.15.0(eslint@9.15.0)(typescript@5.6.3) version: 8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)
vite: vite:
specifier: ^5.4.10 specifier: ^5.4.10
version: 5.4.11(@types/node@20.17.7) version: 5.4.11(@types/node@20.17.7)
@ -143,6 +161,10 @@ packages:
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
'@babel/runtime@7.26.0':
resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==}
engines: {node: '>=6.9.0'}
'@babel/template@7.25.9': '@babel/template@7.25.9':
resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -331,6 +353,21 @@ packages:
resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==} resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@formatjs/ecma402-abstract@2.2.4':
resolution: {integrity: sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==}
'@formatjs/fast-memoize@2.2.3':
resolution: {integrity: sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==}
'@formatjs/icu-messageformat-parser@2.9.4':
resolution: {integrity: sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==}
'@formatjs/icu-skeleton-parser@1.8.8':
resolution: {integrity: sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==}
'@formatjs/intl-localematcher@0.5.8':
resolution: {integrity: sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==}
'@humanfs/core@0.19.1': '@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'} engines: {node: '>=18.18.0'}
@ -494,6 +531,9 @@ packages:
'@types/cacheable-request@6.0.3': '@types/cacheable-request@6.0.3':
resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==}
'@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
'@types/estree@1.0.6': '@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
@ -709,6 +749,10 @@ packages:
convert-source-map@2.0.0: convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
cookie@1.0.2:
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
engines: {node: '>=18'}
cross-env@7.0.3: cross-env@7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
@ -999,6 +1043,9 @@ packages:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
globrex@0.1.2:
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
gopd@1.0.1: gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
@ -1031,6 +1078,9 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
html-parse-stringify@3.0.1:
resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
http-cache-semantics@4.1.1: http-cache-semantics@4.1.1:
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
@ -1038,6 +1088,22 @@ packages:
resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==}
engines: {node: '>=10.19.0'} engines: {node: '>=10.19.0'}
i18next-browser-languagedetector@8.0.0:
resolution: {integrity: sha512-zhXdJXTTCoG39QsrOCiOabnWj2jecouOqbchu3EfhtSHxIB5Uugnm9JaizenOy39h7ne3+fLikIjeW88+rgszw==}
i18next-icu@2.3.0:
resolution: {integrity: sha512-x+j7kd5nDJCfbU53uwsMfXD7ALPu5uv0bqjAMQ5nVvXRoj1L7gkmswKtM3XDWYo4YUHf1jznlhSdPyy0xEwU+Q==}
peerDependencies:
intl-messageformat: ^10.3.3
i18next@24.0.2:
resolution: {integrity: sha512-D88xyIGcWAKwBTAs4RSqASi8NXR/NhCVSTM4LDbdoU8qb/5dcEZjNCLDhtQBB7Epw/Cp1w2vH/3ujoTbqLSs5g==}
peerDependencies:
typescript: ^5
peerDependenciesMeta:
typescript:
optional: true
ignore@5.3.2: ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
@ -1050,6 +1116,9 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'} engines: {node: '>=0.8.19'}
intl-messageformat@10.7.7:
resolution: {integrity: sha512-F134jIoeYMro/3I0h08D0Yt4N9o9pjddU/4IIxMMURqbAtI2wu70X8hvG1V48W49zXHXv3RKSF/po+0fDfsGjA==}
is-binary-path@2.1.0: is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -1081,6 +1150,10 @@ packages:
isexe@2.0.0: isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
jiti@1.21.6:
resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
hasBin: true
js-tokens@4.0.0: js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -1285,10 +1358,40 @@ packages:
peerDependencies: peerDependencies:
react: ^18.3.1 react: ^18.3.1
react-i18next@15.1.2:
resolution: {integrity: sha512-tl7AfbWyz9a4BefFXnVooc+gvQBVlavUkVTphGUcvhsNmbRf5UixJVdHeSFkE4gUyQkmFPYHVwTuxIdHjfQgiA==}
peerDependencies:
i18next: '>= 23.2.3'
react: '>= 16.8.0'
react-dom: '*'
react-native: '*'
peerDependenciesMeta:
react-dom:
optional: true
react-native:
optional: true
react-refresh@0.14.2: react-refresh@0.14.2:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
react-router-dom@7.0.1:
resolution: {integrity: sha512-duBzwAAiIabhFPZfDjcYpJ+f08TMbPMETgq254GWne2NW1ZwRHhZLj7tpSp8KGb7JvZzlLcjGUnqLxpZQVEPng==}
engines: {node: '>=20.0.0'}
peerDependencies:
react: '>=18'
react-dom: '>=18'
react-router@7.0.1:
resolution: {integrity: sha512-WVAhv9oWCNsja5AkK6KLpXJDSJCQizOIyOd4vvB/+eHGbYx5vkhcmcmwWjQ9yqkRClogi+xjEg9fNEOd5EX/tw==}
engines: {node: '>=20.0.0'}
peerDependencies:
react: '>=18'
react-dom: '>=18'
peerDependenciesMeta:
react-dom:
optional: true
react@18.3.1: react@18.3.1:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -1297,6 +1400,9 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
regenerator-runtime@0.14.1:
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
require-directory@2.1.1: require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -1349,6 +1455,9 @@ packages:
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
engines: {node: '>=10'} engines: {node: '>=10'}
set-cookie-parser@2.7.1:
resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
shebang-command@2.0.0: shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -1429,9 +1538,22 @@ packages:
peerDependencies: peerDependencies:
typescript: '>=4.2.0' typescript: '>=4.2.0'
tsconfck@3.1.4:
resolution: {integrity: sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==}
engines: {node: ^18 || >=20}
hasBin: true
peerDependencies:
typescript: ^5.0.0
peerDependenciesMeta:
typescript:
optional: true
tslib@2.8.1: tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
turbo-stream@2.4.0:
resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==}
type-check@0.4.0: type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -1475,6 +1597,14 @@ packages:
uri-js@4.4.1: uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
vite-tsconfig-paths@5.1.3:
resolution: {integrity: sha512-0bz+PDlLpGfP2CigeSKL9NFTF1KtXkeHGZSSaGQSuPZH77GhoiQaA8IjYgOaynSuwlDTolSUEU0ErVvju3NURg==}
peerDependencies:
vite: '*'
peerDependenciesMeta:
vite:
optional: true
vite@5.4.11: vite@5.4.11:
resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
@ -1506,6 +1636,10 @@ packages:
terser: terser:
optional: true optional: true
void-elements@3.1.0:
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
engines: {node: '>=0.10.0'}
which@2.0.2: which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -1638,6 +1772,10 @@ snapshots:
'@babel/core': 7.26.0 '@babel/core': 7.26.0
'@babel/helper-plugin-utils': 7.25.9 '@babel/helper-plugin-utils': 7.25.9
'@babel/runtime@7.26.0':
dependencies:
regenerator-runtime: 0.14.1
'@babel/template@7.25.9': '@babel/template@7.25.9':
dependencies: dependencies:
'@babel/code-frame': 7.26.2 '@babel/code-frame': 7.26.2
@ -1744,9 +1882,9 @@ snapshots:
'@esbuild/win32-x64@0.21.5': '@esbuild/win32-x64@0.21.5':
optional: true optional: true
'@eslint-community/eslint-utils@4.4.1(eslint@9.15.0)': '@eslint-community/eslint-utils@4.4.1(eslint@9.15.0(jiti@1.21.6))':
dependencies: dependencies:
eslint: 9.15.0 eslint: 9.15.0(jiti@1.21.6)
eslint-visitor-keys: 3.4.3 eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.1': {} '@eslint-community/regexpp@4.12.1': {}
@ -1783,6 +1921,31 @@ snapshots:
dependencies: dependencies:
levn: 0.4.1 levn: 0.4.1
'@formatjs/ecma402-abstract@2.2.4':
dependencies:
'@formatjs/fast-memoize': 2.2.3
'@formatjs/intl-localematcher': 0.5.8
tslib: 2.8.1
'@formatjs/fast-memoize@2.2.3':
dependencies:
tslib: 2.8.1
'@formatjs/icu-messageformat-parser@2.9.4':
dependencies:
'@formatjs/ecma402-abstract': 2.2.4
'@formatjs/icu-skeleton-parser': 1.8.8
tslib: 2.8.1
'@formatjs/icu-skeleton-parser@1.8.8':
dependencies:
'@formatjs/ecma402-abstract': 2.2.4
tslib: 2.8.1
'@formatjs/intl-localematcher@0.5.8':
dependencies:
tslib: 2.8.1
'@humanfs/core@0.19.1': {} '@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.6': '@humanfs/node@0.16.6':
@ -1913,6 +2076,8 @@ snapshots:
'@types/node': 20.17.7 '@types/node': 20.17.7
'@types/responselike': 1.0.3 '@types/responselike': 1.0.3
'@types/cookie@0.6.0': {}
'@types/estree@1.0.6': {} '@types/estree@1.0.6': {}
'@types/http-cache-semantics@4.0.4': {} '@types/http-cache-semantics@4.0.4': {}
@ -1947,15 +2112,15 @@ snapshots:
'@types/node': 20.17.7 '@types/node': 20.17.7
optional: true optional: true
'@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3)': '@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)':
dependencies: dependencies:
'@eslint-community/regexpp': 4.12.1 '@eslint-community/regexpp': 4.12.1
'@typescript-eslint/parser': 8.15.0(eslint@9.15.0)(typescript@5.6.3) '@typescript-eslint/parser': 8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)
'@typescript-eslint/scope-manager': 8.15.0 '@typescript-eslint/scope-manager': 8.15.0
'@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) '@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)
'@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) '@typescript-eslint/utils': 8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)
'@typescript-eslint/visitor-keys': 8.15.0 '@typescript-eslint/visitor-keys': 8.15.0
eslint: 9.15.0 eslint: 9.15.0(jiti@1.21.6)
graphemer: 1.4.0 graphemer: 1.4.0
ignore: 5.3.2 ignore: 5.3.2
natural-compare: 1.4.0 natural-compare: 1.4.0
@ -1965,14 +2130,14 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3)': '@typescript-eslint/parser@8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)':
dependencies: dependencies:
'@typescript-eslint/scope-manager': 8.15.0 '@typescript-eslint/scope-manager': 8.15.0
'@typescript-eslint/types': 8.15.0 '@typescript-eslint/types': 8.15.0
'@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3) '@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3)
'@typescript-eslint/visitor-keys': 8.15.0 '@typescript-eslint/visitor-keys': 8.15.0
debug: 4.3.7 debug: 4.3.7
eslint: 9.15.0 eslint: 9.15.0(jiti@1.21.6)
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.3
transitivePeerDependencies: transitivePeerDependencies:
@ -1983,12 +2148,12 @@ snapshots:
'@typescript-eslint/types': 8.15.0 '@typescript-eslint/types': 8.15.0
'@typescript-eslint/visitor-keys': 8.15.0 '@typescript-eslint/visitor-keys': 8.15.0
'@typescript-eslint/type-utils@8.15.0(eslint@9.15.0)(typescript@5.6.3)': '@typescript-eslint/type-utils@8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)':
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3) '@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3)
'@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) '@typescript-eslint/utils': 8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)
debug: 4.3.7 debug: 4.3.7
eslint: 9.15.0 eslint: 9.15.0(jiti@1.21.6)
ts-api-utils: 1.4.0(typescript@5.6.3) ts-api-utils: 1.4.0(typescript@5.6.3)
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.3
@ -2012,13 +2177,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/utils@8.15.0(eslint@9.15.0)(typescript@5.6.3)': '@typescript-eslint/utils@8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)':
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0(jiti@1.21.6))
'@typescript-eslint/scope-manager': 8.15.0 '@typescript-eslint/scope-manager': 8.15.0
'@typescript-eslint/types': 8.15.0 '@typescript-eslint/types': 8.15.0
'@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3) '@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3)
eslint: 9.15.0 eslint: 9.15.0(jiti@1.21.6)
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.3
transitivePeerDependencies: transitivePeerDependencies:
@ -2167,6 +2332,8 @@ snapshots:
convert-source-map@2.0.0: {} convert-source-map@2.0.0: {}
cookie@1.0.2: {}
cross-env@7.0.3: cross-env@7.0.3:
dependencies: dependencies:
cross-spawn: 7.0.6 cross-spawn: 7.0.6
@ -2308,13 +2475,13 @@ snapshots:
escape-string-regexp@5.0.0: {} escape-string-regexp@5.0.0: {}
eslint-plugin-react-hooks@5.0.0(eslint@9.15.0): eslint-plugin-react-hooks@5.0.0(eslint@9.15.0(jiti@1.21.6)):
dependencies: dependencies:
eslint: 9.15.0 eslint: 9.15.0(jiti@1.21.6)
eslint-plugin-react-refresh@0.4.14(eslint@9.15.0): eslint-plugin-react-refresh@0.4.14(eslint@9.15.0(jiti@1.21.6)):
dependencies: dependencies:
eslint: 9.15.0 eslint: 9.15.0(jiti@1.21.6)
eslint-scope@8.2.0: eslint-scope@8.2.0:
dependencies: dependencies:
@ -2325,9 +2492,9 @@ snapshots:
eslint-visitor-keys@4.2.0: {} eslint-visitor-keys@4.2.0: {}
eslint@9.15.0: eslint@9.15.0(jiti@1.21.6):
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0(jiti@1.21.6))
'@eslint-community/regexpp': 4.12.1 '@eslint-community/regexpp': 4.12.1
'@eslint/config-array': 0.19.0 '@eslint/config-array': 0.19.0
'@eslint/core': 0.9.0 '@eslint/core': 0.9.0
@ -2361,6 +2528,8 @@ snapshots:
minimatch: 3.1.2 minimatch: 3.1.2
natural-compare: 1.4.0 natural-compare: 1.4.0
optionator: 0.9.4 optionator: 0.9.4
optionalDependencies:
jiti: 1.21.6
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -2504,6 +2673,8 @@ snapshots:
gopd: 1.0.1 gopd: 1.0.1
optional: true optional: true
globrex@0.1.2: {}
gopd@1.0.1: gopd@1.0.1:
dependencies: dependencies:
get-intrinsic: 1.2.4 get-intrinsic: 1.2.4
@ -2545,6 +2716,10 @@ snapshots:
function-bind: 1.1.2 function-bind: 1.1.2
optional: true optional: true
html-parse-stringify@3.0.1:
dependencies:
void-elements: 3.1.0
http-cache-semantics@4.1.1: {} http-cache-semantics@4.1.1: {}
http2-wrapper@1.0.3: http2-wrapper@1.0.3:
@ -2552,6 +2727,20 @@ snapshots:
quick-lru: 5.1.1 quick-lru: 5.1.1
resolve-alpn: 1.2.1 resolve-alpn: 1.2.1
i18next-browser-languagedetector@8.0.0:
dependencies:
'@babel/runtime': 7.26.0
i18next-icu@2.3.0(intl-messageformat@10.7.7):
dependencies:
intl-messageformat: 10.7.7
i18next@24.0.2(typescript@5.6.3):
dependencies:
'@babel/runtime': 7.26.0
optionalDependencies:
typescript: 5.6.3
ignore@5.3.2: {} ignore@5.3.2: {}
import-fresh@3.3.0: import-fresh@3.3.0:
@ -2561,6 +2750,13 @@ snapshots:
imurmurhash@0.1.4: {} imurmurhash@0.1.4: {}
intl-messageformat@10.7.7:
dependencies:
'@formatjs/ecma402-abstract': 2.2.4
'@formatjs/fast-memoize': 2.2.3
'@formatjs/icu-messageformat-parser': 2.9.4
tslib: 2.8.1
is-binary-path@2.1.0: is-binary-path@2.1.0:
dependencies: dependencies:
binary-extensions: 2.3.0 binary-extensions: 2.3.0
@ -2581,6 +2777,9 @@ snapshots:
isexe@2.0.0: {} isexe@2.0.0: {}
jiti@1.21.6:
optional: true
js-tokens@4.0.0: {} js-tokens@4.0.0: {}
js-yaml@4.1.0: js-yaml@4.1.0:
@ -2748,8 +2947,33 @@ snapshots:
react: 18.3.1 react: 18.3.1
scheduler: 0.23.2 scheduler: 0.23.2
react-i18next@15.1.2(i18next@24.0.2(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@babel/runtime': 7.26.0
html-parse-stringify: 3.0.1
i18next: 24.0.2(typescript@5.6.3)
react: 18.3.1
optionalDependencies:
react-dom: 18.3.1(react@18.3.1)
react-refresh@0.14.2: {} react-refresh@0.14.2: {}
react-router-dom@7.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-router: 7.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-router@7.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@types/cookie': 0.6.0
cookie: 1.0.2
react: 18.3.1
set-cookie-parser: 2.7.1
turbo-stream: 2.4.0
optionalDependencies:
react-dom: 18.3.1(react@18.3.1)
react@18.3.1: react@18.3.1:
dependencies: dependencies:
loose-envify: 1.4.0 loose-envify: 1.4.0
@ -2758,6 +2982,8 @@ snapshots:
dependencies: dependencies:
picomatch: 2.3.1 picomatch: 2.3.1
regenerator-runtime@0.14.1: {}
require-directory@2.1.1: {} require-directory@2.1.1: {}
resolve-alpn@1.2.1: {} resolve-alpn@1.2.1: {}
@ -2828,6 +3054,8 @@ snapshots:
type-fest: 0.13.1 type-fest: 0.13.1
optional: true optional: true
set-cookie-parser@2.7.1: {}
shebang-command@2.0.0: shebang-command@2.0.0:
dependencies: dependencies:
shebang-regex: 3.0.0 shebang-regex: 3.0.0
@ -2902,8 +3130,14 @@ snapshots:
dependencies: dependencies:
typescript: 5.6.3 typescript: 5.6.3
tsconfck@3.1.4(typescript@5.6.3):
optionalDependencies:
typescript: 5.6.3
tslib@2.8.1: {} tslib@2.8.1: {}
turbo-stream@2.4.0: {}
type-check@0.4.0: type-check@0.4.0:
dependencies: dependencies:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
@ -2911,12 +3145,12 @@ snapshots:
type-fest@0.13.1: type-fest@0.13.1:
optional: true optional: true
typescript-eslint@8.15.0(eslint@9.15.0)(typescript@5.6.3): typescript-eslint@8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3):
dependencies: dependencies:
'@typescript-eslint/eslint-plugin': 8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3) '@typescript-eslint/eslint-plugin': 8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)
'@typescript-eslint/parser': 8.15.0(eslint@9.15.0)(typescript@5.6.3) '@typescript-eslint/parser': 8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)
'@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) '@typescript-eslint/utils': 8.15.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.6.3)
eslint: 9.15.0 eslint: 9.15.0(jiti@1.21.6)
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.3
transitivePeerDependencies: transitivePeerDependencies:
@ -2943,6 +3177,17 @@ snapshots:
dependencies: dependencies:
punycode: 2.3.1 punycode: 2.3.1
vite-tsconfig-paths@5.1.3(typescript@5.6.3)(vite@5.4.11(@types/node@20.17.7)):
dependencies:
debug: 4.3.7
globrex: 0.1.2
tsconfck: 3.1.4(typescript@5.6.3)
optionalDependencies:
vite: 5.4.11(@types/node@20.17.7)
transitivePeerDependencies:
- supports-color
- typescript
vite@5.4.11(@types/node@20.17.7): vite@5.4.11(@types/node@20.17.7):
dependencies: dependencies:
esbuild: 0.21.5 esbuild: 0.21.5
@ -2952,6 +3197,8 @@ snapshots:
'@types/node': 20.17.7 '@types/node': 20.17.7
fsevents: 2.3.3 fsevents: 2.3.3
void-elements@3.1.0: {}
which@2.0.2: which@2.0.2:
dependencies: dependencies:
isexe: 2.0.0 isexe: 2.0.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

View File

@ -1,42 +0,0 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}

View File

@ -1,24 +0,0 @@
import {useState} from 'react'
function App() {
const [count, setCount] = useState(0)
return (
<div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>s
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</div>
)
}
export default App

18
src/app.tsx Normal file
View File

@ -0,0 +1,18 @@
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import SettingsPage from "pages/settings";
import "./i18n.ts";
const router = createBrowserRouter([
{
path: "/settings",
element: <SettingsPage/>
}
]);
export function App() {
return (
<div>
<RouterProvider router={router} />
</div>
);
}

View File

@ -1,20 +1,96 @@
import windowStateManager from 'electron-window-state'; import windowStateManager from 'electron-window-state';
import { app, BrowserWindow, ipcMain, screen, globalShortcut } from 'electron'; import { app, BrowserWindow, screen,ipcMain, globalShortcut, Tray, Menu } from 'electron';
import contextMenu from 'electron-context-menu'; import contextMenu from 'electron-context-menu';
import serve from 'electron-serve'; import serve from 'electron-serve';
try { let tray = null
require('electron-reloader')(module);
} catch (e) { function createTray() {
console.error(e); // 创建托盘图标
tray = new Tray('./assets/icon.png')
// 创建托盘菜单
const contextMenu = Menu.buildFromTemplate([
{
label: '显示主窗口',
click: () => {
if (!mainWindow) createMainWindow();
mainWindow.show();
}
},
{
label: '显示设置',
click: () => {
if (!settingsWindow) createSettingsWindow();
settingsWindow.show();
}
},
{ type: 'separator' },
{
label: '退出',
click: () => {
app.quit()
}
}
])
// 设置托盘的上下文菜单
tray.setContextMenu(contextMenu)
// 设置托盘的提示文字
tray.setToolTip('我的应用程序')
// 点击托盘图标时显示主窗口
// tray.on('click', () => {
// mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show()
// })
} }
const serveURL = serve({ directory: '.' }); const serveURL = serve({ directory: '.' });
const port = process.env.PORT || 5173; const port = process.env.PORT || "5173";
const dev = !app.isPackaged; const dev = !app.isPackaged;
let mainWindow;
function createWindow() { let mainWindow;
let settingsWindow;
function createSettingsWindow() {
const window = new BrowserWindow({
width: 400,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
},
});
window.once('ready-to-show', () => {
window.show();
window.focus();
});
settingsWindow = window;
if (dev) loadVite(window ,port, "settings");
else serveURL(mainWindow);
}
contextMenu({
showLookUpSelection: true,
showSearchWithGoogle: true,
showCopyImage: true,
});
function loadVite(window, port, path = "") {
console.log(`http://localhost:${port}/${path}`);
window.loadURL(`http://localhost:${port}/${path}`).catch((e) => {
console.log('Error loading URL, retrying', e);
setTimeout(() => {
loadVite(window, port, path);
}, 1000);
});
}
function createMainWindow() {
const display = screen.getPrimaryDisplay(); const display = screen.getPrimaryDisplay();
const { width, height } = display.bounds; const { width, height } = display.bounds;
let windowState = windowStateManager({ let windowState = windowStateManager({
@ -22,7 +98,7 @@ function createWindow() {
defaultHeight: height, defaultHeight: height,
}); });
const mainWindow = new BrowserWindow({ const window = new BrowserWindow({
width, width,
height, height,
x: 0, x: 0,
@ -40,62 +116,44 @@ function createWindow() {
roundedCorners: false roundedCorners: false
}); });
windowState.manage(mainWindow); windowState.manage(window);
mainWindow.once('ready-to-show', () => { window.once('ready-to-show', () => {
mainWindow.show(); window.show();
mainWindow.setAlwaysOnTop(true, 'screen-saver'); window.setAlwaysOnTop(true, 'screen-saver');
mainWindow.setBounds({ x: 0, y: 0, width, height }); window.setBounds({ x: 0, y: 0, width, height });
mainWindow.focus(); window.focus();
}); });
mainWindow.on('close', () => { window.on('close', () => {
windowState.saveState(mainWindow); windowState.saveState(window);
}); });
window.once('close', () => {
return mainWindow;
}
contextMenu({
showLookUpSelection: true,
showSearchWithGoogle: true,
showCopyImage: true,
});
function loadVite(port) {
mainWindow.loadURL(`http://localhost:${port}`).catch((e) => {
console.log('Error loading URL, retrying', e);
setTimeout(() => {
loadVite(port);
}, 200);
});
}
function createMainWindow() {
mainWindow = createWindow();
mainWindow.once('close', () => {
mainWindow = null; mainWindow = null;
}); });
mainWindow = window;
if (dev) loadVite(port); if (dev) loadVite(port);
else serveURL(mainWindow); else serveURL(mainWindow);
} }
app.once('ready', createMainWindow); app.once('ready', () => {
app.on('activate', () => { app.dock.hide();
if (!mainWindow) {
createMainWindow();
}
}); });
app.on('activate', () => {
});
app.on('ready', () => { app.on('ready', () => {
createTray();
globalShortcut.register('Escape', () => { globalShortcut.register('Escape', () => {
app.quit(); mainWindow.hide();
}); });
}); });
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit(); if (process.platform !== 'darwin') app.quit();
}); });
ipcMain.on('to-main', (event, count) => { ipcMain.on('to-main', (_event, count) => {
return mainWindow.webContents.send('from-main', `next count is ${count + 1}`); return mainWindow.webContents.send('from-main', `next count is ${count + 1}`);
}); });

53
src/i18n.ts Normal file
View File

@ -0,0 +1,53 @@
import * as en from "i18n/en.json";
import * as zh from "i18n/zh.json";
import * as ja from "i18n/ja.json";
import * as de from "i18n/de.json";
import * as es from "i18n/es.json";
import * as fr from "i18n/fr.json";
import * as it from "i18n/it.json";
import * as ko from "i18n/ko.json";
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import ICU from "i18next-icu";
i18n.use(initReactI18next) // passes i18n down to react-i18next
.use(LanguageDetector)
.use(ICU)
.init({
resources: {
en: {
translation: en
},
zh: {
translation: zh
},
ja: {
translation: ja
},
de: {
translation: de
},
es: {
translation: es
},
fr: {
translation: fr
},
it: {
translation: it
},
ko: {
translation: ko
},
},
fallbackLng: "en",
interpolation: {
escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
},
detection: {
order: ["navigator"],
caches: []
}
});

View File

@ -1,68 +1,3 @@
:root { @tailwind base;
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; @tailwind components;
line-height: 1.5; @tailwind utilities;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

View File

@ -1,10 +1,12 @@
import { StrictMode } from 'react' import { StrictMode } from "react";
import { createRoot } from 'react-dom/client' import { createRoot } from "react-dom/client";
import './index.css' import { App } from "./app";
import App from './App.tsx' import "./index.css";
createRoot(document.getElementById('root')!).render( const app = createRoot(document.getElementById("root")!);
<StrictMode>
<App /> app.render(
</StrictMode>, <StrictMode>
) <App />
</StrictMode>
);

19
tailwind.config.ts Normal file
View File

@ -0,0 +1,19 @@
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/**/*.{js,ts,jsx,tsx,mdx}"
],
theme: {
extend: {
backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))"
}
}
},
plugins: []
};
export default config;

View File

@ -1,6 +1,7 @@
{ {
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020", "target": "ES2020",
"useDefineForClassFields": true, "useDefineForClassFields": true,
@ -9,8 +10,9 @@
"skipLibCheck": true, "skipLibCheck": true,
/* Bundler mode */ /* Bundler mode */
"moduleResolution": "Bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"moduleDetection": "force", "moduleDetection": "force",
"noEmit": true, "noEmit": true,
@ -20,10 +22,7 @@
"strict": true, "strict": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true
"noUncheckedSideEffectImports": true
}, },
"include": [ "include": ["src", "**/*.ts", "**/*.tsx", "global.d.ts"]
"src"
]
} }

View File

@ -1,7 +1,8 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react'
import tsconfigPaths from "vite-tsconfig-paths";
// https://vite.dev/config/ // https://vite.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react(),tsconfigPaths()],
}) })