diff --git a/assets/icon.png b/assets/icon.png
new file mode 100644
index 0000000..4ea8c76
Binary files /dev/null and b/assets/icon.png differ
diff --git a/i18n/ar.json b/i18n/ar.json
new file mode 100755
index 0000000..0db3279
--- /dev/null
+++ b/i18n/ar.json
@@ -0,0 +1,3 @@
+{
+
+}
diff --git a/i18n/de.json b/i18n/de.json
new file mode 100755
index 0000000..2c63c08
--- /dev/null
+++ b/i18n/de.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/i18n/en.json b/i18n/en.json
new file mode 100755
index 0000000..5efbe30
--- /dev/null
+++ b/i18n/en.json
@@ -0,0 +1,3 @@
+{
+ "settings": "Settings"
+}
diff --git a/i18n/es.json b/i18n/es.json
new file mode 100755
index 0000000..2c63c08
--- /dev/null
+++ b/i18n/es.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/i18n/fr.json b/i18n/fr.json
new file mode 100755
index 0000000..2c63c08
--- /dev/null
+++ b/i18n/fr.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/i18n/it.json b/i18n/it.json
new file mode 100755
index 0000000..2c63c08
--- /dev/null
+++ b/i18n/it.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/i18n/ja.json b/i18n/ja.json
new file mode 100644
index 0000000..0db3279
--- /dev/null
+++ b/i18n/ja.json
@@ -0,0 +1,3 @@
+{
+
+}
diff --git a/i18n/ko.json b/i18n/ko.json
new file mode 100755
index 0000000..0db3279
--- /dev/null
+++ b/i18n/ko.json
@@ -0,0 +1,3 @@
+{
+
+}
diff --git a/i18n/zh.json b/i18n/zh.json
new file mode 100644
index 0000000..7a7ef51
--- /dev/null
+++ b/i18n/zh.json
@@ -0,0 +1,3 @@
+{
+ "settings": "设置"
+}
diff --git a/package.json b/package.json
index 35b0618..908a073 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,6 @@
"version": "1.0.0",
"type": "module",
"description": "",
- "main": "src/main.js",
"scripts": {
"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\"",
@@ -19,8 +18,14 @@
"electron-reloader": "^1.2.3",
"electron-serve": "^2.1.1",
"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-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": {
"@eslint/js": "^9.13.0",
diff --git a/pages/settings/index.tsx b/pages/settings/index.tsx
new file mode 100644
index 0000000..926f1c2
--- /dev/null
+++ b/pages/settings/index.tsx
@@ -0,0 +1,10 @@
+import { useTranslation } from "react-i18next";
+
+export default function SettingsPage() {
+ const { t } = useTranslation();
+ return (
+
+
{t('settings')}
+
+ )
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5d5bc24..3ef8f67 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -23,12 +23,30 @@ importers:
electron-window-state:
specifier: ^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:
specifier: ^18.3.1
version: 18.3.1
react-dom:
specifier: ^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:
'@eslint/js':
specifier: ^9.13.0
@@ -50,13 +68,13 @@ importers:
version: 7.0.3
eslint:
specifier: ^9.13.0
- version: 9.15.0
+ version: 9.15.0(jiti@1.21.6)
eslint-plugin-react-hooks:
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:
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:
specifier: ^15.11.0
version: 15.12.0
@@ -65,7 +83,7 @@ importers:
version: 5.6.3
typescript-eslint:
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:
specifier: ^5.4.10
version: 5.4.11(@types/node@20.17.7)
@@ -143,6 +161,10 @@ packages:
peerDependencies:
'@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':
resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==}
engines: {node: '>=6.9.0'}
@@ -331,6 +353,21 @@ packages:
resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==}
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':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'}
@@ -494,6 +531,9 @@ packages:
'@types/cacheable-request@6.0.3':
resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==}
+ '@types/cookie@0.6.0':
+ resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
+
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
@@ -709,6 +749,10 @@ packages:
convert-source-map@2.0.0:
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:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
@@ -999,6 +1043,9 @@ packages:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
+ globrex@0.1.2:
+ resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
+
gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
@@ -1031,6 +1078,9 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
+ html-parse-stringify@3.0.1:
+ resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
+
http-cache-semantics@4.1.1:
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
@@ -1038,6 +1088,22 @@ packages:
resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==}
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:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
@@ -1050,6 +1116,9 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
+ intl-messageformat@10.7.7:
+ resolution: {integrity: sha512-F134jIoeYMro/3I0h08D0Yt4N9o9pjddU/4IIxMMURqbAtI2wu70X8hvG1V48W49zXHXv3RKSF/po+0fDfsGjA==}
+
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
@@ -1081,6 +1150,10 @@ packages:
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ jiti@1.21.6:
+ resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
+ hasBin: true
+
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -1285,10 +1358,40 @@ packages:
peerDependencies:
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:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
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:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'}
@@ -1297,6 +1400,9 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
+ regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
@@ -1349,6 +1455,9 @@ packages:
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
engines: {node: '>=10'}
+ set-cookie-parser@2.7.1:
+ resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
+
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -1429,9 +1538,22 @@ packages:
peerDependencies:
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:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+ turbo-stream@2.4.0:
+ resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==}
+
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
@@ -1475,6 +1597,14 @@ packages:
uri-js@4.4.1:
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:
resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -1506,6 +1636,10 @@ packages:
terser:
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:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
@@ -1638,6 +1772,10 @@ snapshots:
'@babel/core': 7.26.0
'@babel/helper-plugin-utils': 7.25.9
+ '@babel/runtime@7.26.0':
+ dependencies:
+ regenerator-runtime: 0.14.1
+
'@babel/template@7.25.9':
dependencies:
'@babel/code-frame': 7.26.2
@@ -1744,9 +1882,9 @@ snapshots:
'@esbuild/win32-x64@0.21.5':
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:
- eslint: 9.15.0
+ eslint: 9.15.0(jiti@1.21.6)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.1': {}
@@ -1783,6 +1921,31 @@ snapshots:
dependencies:
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/node@0.16.6':
@@ -1913,6 +2076,8 @@ snapshots:
'@types/node': 20.17.7
'@types/responselike': 1.0.3
+ '@types/cookie@0.6.0': {}
+
'@types/estree@1.0.6': {}
'@types/http-cache-semantics@4.0.4': {}
@@ -1947,15 +2112,15 @@ snapshots:
'@types/node': 20.17.7
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:
'@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/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3)
- '@typescript-eslint/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(jiti@1.21.6))(typescript@5.6.3)
'@typescript-eslint/visitor-keys': 8.15.0
- eslint: 9.15.0
+ eslint: 9.15.0(jiti@1.21.6)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
@@ -1965,14 +2130,14 @@ snapshots:
transitivePeerDependencies:
- 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:
'@typescript-eslint/scope-manager': 8.15.0
'@typescript-eslint/types': 8.15.0
'@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3)
'@typescript-eslint/visitor-keys': 8.15.0
debug: 4.3.7
- eslint: 9.15.0
+ eslint: 9.15.0(jiti@1.21.6)
optionalDependencies:
typescript: 5.6.3
transitivePeerDependencies:
@@ -1983,12 +2148,12 @@ snapshots:
'@typescript-eslint/types': 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:
'@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
- eslint: 9.15.0
+ eslint: 9.15.0(jiti@1.21.6)
ts-api-utils: 1.4.0(typescript@5.6.3)
optionalDependencies:
typescript: 5.6.3
@@ -2012,13 +2177,13 @@ snapshots:
transitivePeerDependencies:
- 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:
- '@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/types': 8.15.0
'@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3)
- eslint: 9.15.0
+ eslint: 9.15.0(jiti@1.21.6)
optionalDependencies:
typescript: 5.6.3
transitivePeerDependencies:
@@ -2167,6 +2332,8 @@ snapshots:
convert-source-map@2.0.0: {}
+ cookie@1.0.2: {}
+
cross-env@7.0.3:
dependencies:
cross-spawn: 7.0.6
@@ -2308,13 +2475,13 @@ snapshots:
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:
- 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:
- eslint: 9.15.0
+ eslint: 9.15.0(jiti@1.21.6)
eslint-scope@8.2.0:
dependencies:
@@ -2325,9 +2492,9 @@ snapshots:
eslint-visitor-keys@4.2.0: {}
- eslint@9.15.0:
+ eslint@9.15.0(jiti@1.21.6):
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/config-array': 0.19.0
'@eslint/core': 0.9.0
@@ -2361,6 +2528,8 @@ snapshots:
minimatch: 3.1.2
natural-compare: 1.4.0
optionator: 0.9.4
+ optionalDependencies:
+ jiti: 1.21.6
transitivePeerDependencies:
- supports-color
@@ -2504,6 +2673,8 @@ snapshots:
gopd: 1.0.1
optional: true
+ globrex@0.1.2: {}
+
gopd@1.0.1:
dependencies:
get-intrinsic: 1.2.4
@@ -2545,6 +2716,10 @@ snapshots:
function-bind: 1.1.2
optional: true
+ html-parse-stringify@3.0.1:
+ dependencies:
+ void-elements: 3.1.0
+
http-cache-semantics@4.1.1: {}
http2-wrapper@1.0.3:
@@ -2552,6 +2727,20 @@ snapshots:
quick-lru: 5.1.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: {}
import-fresh@3.3.0:
@@ -2561,6 +2750,13 @@ snapshots:
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:
dependencies:
binary-extensions: 2.3.0
@@ -2581,6 +2777,9 @@ snapshots:
isexe@2.0.0: {}
+ jiti@1.21.6:
+ optional: true
+
js-tokens@4.0.0: {}
js-yaml@4.1.0:
@@ -2748,8 +2947,33 @@ snapshots:
react: 18.3.1
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-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:
dependencies:
loose-envify: 1.4.0
@@ -2758,6 +2982,8 @@ snapshots:
dependencies:
picomatch: 2.3.1
+ regenerator-runtime@0.14.1: {}
+
require-directory@2.1.1: {}
resolve-alpn@1.2.1: {}
@@ -2828,6 +3054,8 @@ snapshots:
type-fest: 0.13.1
optional: true
+ set-cookie-parser@2.7.1: {}
+
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
@@ -2902,8 +3130,14 @@ snapshots:
dependencies:
typescript: 5.6.3
+ tsconfck@3.1.4(typescript@5.6.3):
+ optionalDependencies:
+ typescript: 5.6.3
+
tslib@2.8.1: {}
+ turbo-stream@2.4.0: {}
+
type-check@0.4.0:
dependencies:
prelude-ls: 1.2.1
@@ -2911,12 +3145,12 @@ snapshots:
type-fest@0.13.1:
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:
- '@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/parser': 8.15.0(eslint@9.15.0)(typescript@5.6.3)
- '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3)
- eslint: 9.15.0
+ '@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(jiti@1.21.6))(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(jiti@1.21.6)
optionalDependencies:
typescript: 5.6.3
transitivePeerDependencies:
@@ -2943,6 +3177,17 @@ snapshots:
dependencies:
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):
dependencies:
esbuild: 0.21.5
@@ -2952,6 +3197,8 @@ snapshots:
'@types/node': 20.17.7
fsevents: 2.3.3
+ void-elements@3.1.0: {}
+
which@2.0.2:
dependencies:
isexe: 2.0.0
diff --git a/screen.png b/screen.png
deleted file mode 100644
index 9000131..0000000
Binary files a/screen.png and /dev/null differ
diff --git a/src/App.css b/src/App.css
deleted file mode 100644
index b9d355d..0000000
--- a/src/App.css
+++ /dev/null
@@ -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;
-}
diff --git a/src/App.tsx b/src/App.tsx
deleted file mode 100644
index dde66ca..0000000
--- a/src/App.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import {useState} from 'react'
-
-function App() {
- const [count, setCount] = useState(0)
-
- return (
-
-
Vite + React
-
-
-
- Edit src/App.tsx
and save to test HMR
-
s
-
-
- Click on the Vite and React logos to learn more
-
-
- )
-}
-
-export default App
diff --git a/src/app.tsx b/src/app.tsx
new file mode 100644
index 0000000..3954f16
--- /dev/null
+++ b/src/app.tsx
@@ -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:
+ }
+]);
+
+export function App() {
+ return (
+
+
+
+ );
+}
diff --git a/src/electron.js b/src/electron.js
index 1bf329e..2d18722 100644
--- a/src/electron.js
+++ b/src/electron.js
@@ -1,20 +1,96 @@
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 serve from 'electron-serve';
-try {
- require('electron-reloader')(module);
-} catch (e) {
- console.error(e);
+let tray = null
+
+function createTray() {
+ // 创建托盘图标
+ 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 port = process.env.PORT || 5173;
+const port = process.env.PORT || "5173";
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 { width, height } = display.bounds;
let windowState = windowStateManager({
@@ -22,7 +98,7 @@ function createWindow() {
defaultHeight: height,
});
- const mainWindow = new BrowserWindow({
+ const window = new BrowserWindow({
width,
height,
x: 0,
@@ -40,62 +116,44 @@ function createWindow() {
roundedCorners: false
});
- windowState.manage(mainWindow);
+ windowState.manage(window);
- mainWindow.once('ready-to-show', () => {
- mainWindow.show();
- mainWindow.setAlwaysOnTop(true, 'screen-saver');
- mainWindow.setBounds({ x: 0, y: 0, width, height });
- mainWindow.focus();
+ window.once('ready-to-show', () => {
+ window.show();
+ window.setAlwaysOnTop(true, 'screen-saver');
+ window.setBounds({ x: 0, y: 0, width, height });
+ window.focus();
});
- mainWindow.on('close', () => {
- windowState.saveState(mainWindow);
+ window.on('close', () => {
+ windowState.saveState(window);
});
-
- 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', () => {
+ window.once('close', () => {
mainWindow = null;
});
+ mainWindow = window;
+
if (dev) loadVite(port);
else serveURL(mainWindow);
}
-app.once('ready', createMainWindow);
-app.on('activate', () => {
- if (!mainWindow) {
- createMainWindow();
- }
+app.once('ready', () => {
+ app.dock.hide();
});
+app.on('activate', () => {
+});
+
app.on('ready', () => {
+ createTray();
globalShortcut.register('Escape', () => {
- app.quit();
+ mainWindow.hide();
});
});
app.on('window-all-closed', () => {
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}`);
});
\ No newline at end of file
diff --git a/src/i18n.ts b/src/i18n.ts
new file mode 100644
index 0000000..16b49c6
--- /dev/null
+++ b/src/i18n.ts
@@ -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: []
+ }
+ });
diff --git a/src/index.css b/src/index.css
index 6119ad9..b5c61c9 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,68 +1,3 @@
-:root {
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- 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;
- }
-}
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/src/main.tsx b/src/main.tsx
index bef5202..ea4e6af 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,10 +1,12 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import './index.css'
-import App from './App.tsx'
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import { App } from "./app";
+import "./index.css";
-createRoot(document.getElementById('root')!).render(
-
-
- ,
-)
+const app = createRoot(document.getElementById("root")!);
+
+app.render(
+
+
+
+);
diff --git a/tailwind.config.ts b/tailwind.config.ts
new file mode 100644
index 0000000..90c1bed
--- /dev/null
+++ b/tailwind.config.ts
@@ -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;
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 88664c8..78479d1 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"baseUrl": ".",
+ "composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
@@ -9,8 +10,9 @@
"skipLibCheck": true,
/* Bundler mode */
- "moduleResolution": "Bundler",
+ "moduleResolution": "bundler",
"allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
@@ -20,10 +22,7 @@
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true,
- "noUncheckedSideEffectImports": true
+ "noFallthroughCasesInSwitch": true
},
- "include": [
- "src"
- ]
+ "include": ["src", "**/*.ts", "**/*.tsx", "global.d.ts"]
}
diff --git a/vite.config.ts b/vite.config.ts
index 8b0f57b..46d3965 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,7 +1,8 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
+import tsconfigPaths from "vite-tsconfig-paths";
// https://vite.dev/config/
export default defineConfig({
- plugins: [react()],
+ plugins: [react(),tsconfigPaths()],
})