diff --git a/next.config.ts b/next.config.ts
index ca2fd69..a4e3c95 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -3,7 +3,17 @@ import createNextIntlPlugin from "next-intl/plugin";
const nextConfig: NextConfig = {
/* config options here */
output: "standalone",
- allowedDevOrigins: ["192.168.3.65", "192.168.3.66"],
+ images: {
+ remotePatterns: [
+ {
+ protocol: "https",
+ hostname: "avatars.githubusercontent.com",
+ port: "",
+ pathname: "/u/**",
+ },
+ ],
+ },
+ // allowedDevOrigins: ["192.168.3.65", "192.168.3.66"],
};
const withNextIntl = createNextIntlPlugin();
diff --git a/package-lock.json b/package-lock.json
index 6abab2b..cc89742 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,7 @@
"pg": "^8.16.3",
"react": "19.1.0",
"react-dom": "19.1.0",
+ "unstorage": "^1.17.2",
"zod": "^3.25.76"
},
"devDependencies": {
@@ -5229,8 +5230,6 @@
"resolved": "https://mirrors.cloud.tencent.com/npm/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"license": "ISC",
- "optional": true,
- "peer": true,
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -6133,6 +6132,21 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/chrome-launcher": {
"version": "0.15.2",
"resolved": "https://mirrors.cloud.tencent.com/npm/chrome-launcher/-/chrome-launcher-0.15.2.tgz",
@@ -6479,6 +6493,12 @@
"node": ">= 0.6"
}
},
+ "node_modules/cookie-es": {
+ "version": "1.2.2",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/cookie-es/-/cookie-es-1.2.2.tgz",
+ "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==",
+ "license": "MIT"
+ },
"node_modules/core-js-compat": {
"version": "3.46.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/core-js-compat/-/core-js-compat-3.46.0.tgz",
@@ -6518,6 +6538,15 @@
"node": ">= 8"
}
},
+ "node_modules/crossws": {
+ "version": "0.3.5",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/crossws/-/crossws-0.3.5.tgz",
+ "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==",
+ "license": "MIT",
+ "dependencies": {
+ "uncrypto": "^0.1.3"
+ }
+ },
"node_modules/crypto-random-string": {
"version": "2.0.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
@@ -6710,6 +6739,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/defu": {
+ "version": "6.1.4",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/defu/-/defu-6.1.4.tgz",
+ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
+ "license": "MIT"
+ },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -6730,6 +6765,12 @@
"node": ">= 0.8"
}
},
+ "node_modules/destr": {
+ "version": "2.0.5",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/destr/-/destr-2.0.5.tgz",
+ "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==",
+ "license": "MIT"
+ },
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/destroy/-/destroy-1.2.0.tgz",
@@ -8263,6 +8304,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/h3": {
+ "version": "1.15.4",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/h3/-/h3-1.15.4.tgz",
+ "integrity": "sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie-es": "^1.2.2",
+ "crossws": "^0.3.5",
+ "defu": "^6.1.4",
+ "destr": "^2.0.5",
+ "iron-webcrypto": "^1.2.1",
+ "node-mock-http": "^1.0.2",
+ "radix3": "^1.1.2",
+ "ufo": "^1.6.1",
+ "uncrypto": "^0.1.3"
+ }
+ },
"node_modules/has-bigints": {
"version": "1.1.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/has-bigints/-/has-bigints-1.1.0.tgz",
@@ -8586,6 +8644,15 @@
"loose-envify": "^1.0.0"
}
},
+ "node_modules/iron-webcrypto": {
+ "version": "1.2.1",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz",
+ "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/brc-dd"
+ }
+ },
"node_modules/is-array-buffer": {
"version": "3.0.5",
"resolved": "https://mirrors.cloud.tencent.com/npm/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
@@ -11722,6 +11789,12 @@
}
}
},
+ "node_modules/node-fetch-native": {
+ "version": "1.6.7",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/node-fetch-native/-/node-fetch-native-1.6.7.tgz",
+ "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==",
+ "license": "MIT"
+ },
"node_modules/node-forge": {
"version": "1.3.1",
"resolved": "https://mirrors.cloud.tencent.com/npm/node-forge/-/node-forge-1.3.1.tgz",
@@ -11741,6 +11814,12 @@
"optional": true,
"peer": true
},
+ "node_modules/node-mock-http": {
+ "version": "1.0.3",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/node-mock-http/-/node-mock-http-1.0.3.tgz",
+ "integrity": "sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==",
+ "license": "MIT"
+ },
"node_modules/node-releases": {
"version": "2.0.27",
"resolved": "https://mirrors.cloud.tencent.com/npm/node-releases/-/node-releases-2.0.27.tgz",
@@ -11754,8 +11833,6 @@
"resolved": "https://mirrors.cloud.tencent.com/npm/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"license": "MIT",
- "optional": true,
- "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -11937,6 +12014,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/ofetch": {
+ "version": "1.5.1",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/ofetch/-/ofetch-1.5.1.tgz",
+ "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==",
+ "license": "MIT",
+ "dependencies": {
+ "destr": "^2.0.5",
+ "node-fetch-native": "^1.6.7",
+ "ufo": "^1.6.1"
+ }
+ },
"node_modules/oidc-token-hash": {
"version": "5.2.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/oidc-token-hash/-/oidc-token-hash-5.2.0.tgz",
@@ -12464,7 +12552,6 @@
"version": "2.3.1",
"resolved": "https://mirrors.cloud.tencent.com/npm/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -12815,6 +12902,12 @@
],
"license": "MIT"
},
+ "node_modules/radix3": {
+ "version": "1.1.2",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/radix3/-/radix3-1.1.2.tgz",
+ "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==",
+ "license": "MIT"
+ },
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://mirrors.cloud.tencent.com/npm/range-parser/-/range-parser-1.2.1.tgz",
@@ -12928,6 +13021,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"resolved": "https://mirrors.cloud.tencent.com/npm/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -14790,6 +14896,12 @@
"node": ">=14.17"
}
},
+ "node_modules/ufo": {
+ "version": "1.6.1",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/ufo/-/ufo-1.6.1.tgz",
+ "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
+ "license": "MIT"
+ },
"node_modules/unbox-primitive": {
"version": "1.1.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
@@ -14809,6 +14921,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/uncrypto": {
+ "version": "0.1.3",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/uncrypto/-/uncrypto-0.1.3.tgz",
+ "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==",
+ "license": "MIT"
+ },
"node_modules/undici": {
"version": "6.22.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/undici/-/undici-6.22.0.tgz",
@@ -14945,6 +15063,108 @@
"@unrs/resolver-binding-win32-x64-msvc": "1.11.1"
}
},
+ "node_modules/unstorage": {
+ "version": "1.17.2",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/unstorage/-/unstorage-1.17.2.tgz",
+ "integrity": "sha512-cKEsD6iBWJgOMJ6vW1ID/SYuqNf8oN4yqRk8OYqaVQ3nnkJXOT1PSpaMh2QfzLs78UN5kSNRD2c/mgjT8tX7+w==",
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "^3.1.3",
+ "chokidar": "^4.0.3",
+ "destr": "^2.0.5",
+ "h3": "^1.15.4",
+ "lru-cache": "^10.4.3",
+ "node-fetch-native": "^1.6.7",
+ "ofetch": "^1.5.0",
+ "ufo": "^1.6.1"
+ },
+ "peerDependencies": {
+ "@azure/app-configuration": "^1.8.0",
+ "@azure/cosmos": "^4.2.0",
+ "@azure/data-tables": "^13.3.0",
+ "@azure/identity": "^4.6.0",
+ "@azure/keyvault-secrets": "^4.9.0",
+ "@azure/storage-blob": "^12.26.0",
+ "@capacitor/preferences": "^6.0.3 || ^7.0.0",
+ "@deno/kv": ">=0.9.0",
+ "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0",
+ "@planetscale/database": "^1.19.0",
+ "@upstash/redis": "^1.34.3",
+ "@vercel/blob": ">=0.27.1",
+ "@vercel/functions": "^2.2.12 || ^3.0.0",
+ "@vercel/kv": "^1.0.1",
+ "aws4fetch": "^1.0.20",
+ "db0": ">=0.2.1",
+ "idb-keyval": "^6.2.1",
+ "ioredis": "^5.4.2",
+ "uploadthing": "^7.4.4"
+ },
+ "peerDependenciesMeta": {
+ "@azure/app-configuration": {
+ "optional": true
+ },
+ "@azure/cosmos": {
+ "optional": true
+ },
+ "@azure/data-tables": {
+ "optional": true
+ },
+ "@azure/identity": {
+ "optional": true
+ },
+ "@azure/keyvault-secrets": {
+ "optional": true
+ },
+ "@azure/storage-blob": {
+ "optional": true
+ },
+ "@capacitor/preferences": {
+ "optional": true
+ },
+ "@deno/kv": {
+ "optional": true
+ },
+ "@netlify/blobs": {
+ "optional": true
+ },
+ "@planetscale/database": {
+ "optional": true
+ },
+ "@upstash/redis": {
+ "optional": true
+ },
+ "@vercel/blob": {
+ "optional": true
+ },
+ "@vercel/functions": {
+ "optional": true
+ },
+ "@vercel/kv": {
+ "optional": true
+ },
+ "aws4fetch": {
+ "optional": true
+ },
+ "db0": {
+ "optional": true
+ },
+ "idb-keyval": {
+ "optional": true
+ },
+ "ioredis": {
+ "optional": true
+ },
+ "uploadthing": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/unstorage/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
"node_modules/update-browserslist-db": {
"version": "1.1.4",
"resolved": "https://mirrors.cloud.tencent.com/npm/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
diff --git a/package.json b/package.json
index 1a6d411..9d85291 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"pg": "^8.16.3",
"react": "19.1.0",
"react-dom": "19.1.0",
+ "unstorage": "^1.17.2",
"zod": "^3.25.76"
},
"devDependencies": {
diff --git a/public/changelog.txt b/public/changelog.txt
index 0fdf6f2..c617b1a 100644
--- a/public/changelog.txt
+++ b/public/changelog.txt
@@ -1,3 +1,4 @@
+2025.11.10 重构了translator,将其改为并发请求多个数据,速度大大提升
2025.10.31 添加国际化支持
2025.10.30 添加背单词功能
2025.10.12 添加朗读器本地保存功能
@@ -8,4 +9,3 @@
2025.10.05 新增IPA生成与文本朗读功能
2025.09.25 优化了主界面UI
2025.09.19 更新了单词板,单词不再会重叠
-
diff --git a/public/images/github-mark/github-mark-white.png b/public/images/github-mark/github-mark-white.png
new file mode 100644
index 0000000..50b8175
Binary files /dev/null and b/public/images/github-mark/github-mark-white.png differ
diff --git a/public/images/github-mark/github-mark-white.svg b/public/images/github-mark/github-mark-white.svg
new file mode 100644
index 0000000..d5e6491
--- /dev/null
+++ b/public/images/github-mark/github-mark-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/images/github-mark/github-mark.png b/public/images/github-mark/github-mark.png
new file mode 100644
index 0000000..6cb3b70
Binary files /dev/null and b/public/images/github-mark/github-mark.png differ
diff --git a/public/images/github-mark/github-mark.svg b/public/images/github-mark/github-mark.svg
new file mode 100644
index 0000000..37fa923
--- /dev/null
+++ b/public/images/github-mark/github-mark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/messages/en-US/navbar.json b/public/messages/en-US/navbar.json
index 0600dda..d0fa739 100644
--- a/public/messages/en-US/navbar.json
+++ b/public/messages/en-US/navbar.json
@@ -1,5 +1,7 @@
{
"title": "LL",
"about": "About",
- "sourceCode": "GitHub"
+ "sourceCode": "GitHub",
+ "login": "Login",
+ "profile": "Profile"
}
diff --git a/public/messages/zh-CN/navbar.json b/public/messages/zh-CN/navbar.json
index f261619..b9514e9 100644
--- a/public/messages/zh-CN/navbar.json
+++ b/public/messages/zh-CN/navbar.json
@@ -1,5 +1,7 @@
{
"title": "学语言",
"about": "关于",
- "sourceCode": "源码"
+ "sourceCode": "源码",
+ "login": "登录",
+ "profile": "个人资料"
}
diff --git a/src/app/alphabet/page.tsx b/src/app/alphabet/page.tsx
index 25dee3a..b39439a 100644
--- a/src/app/alphabet/page.tsx
+++ b/src/app/alphabet/page.tsx
@@ -4,7 +4,7 @@ import LightButton from "@/components/buttons/LightButton";
import { Letter, SupportedAlphabets } from "@/interfaces";
import { useEffect, useState } from "react";
import MemoryCard from "./MemoryCard";
-import { Navbar } from "@/components/Navbar";
+
import { useTranslations } from "next-intl";
export default function Alphabet() {
@@ -58,7 +58,6 @@ export default function Alphabet() {
if (!chosenAlphabet)
return (
<>
-
{session.data?.user?.name}
+Email: {session.data?.user?.email}
+