feat: 重构为 Lingua 多语言学习平台#1
Conversation
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 85c70c5c65
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const all = base.concat(extras); | ||
| // 合并本地单词 | ||
| const local = Object.values(currentLangState().words).map(w => w.word); | ||
| lang.words.filter(w => !all.find(a => a.word === w.word) && local.includes(w.word)).forEach(w => all.push(w)); |
There was a problem hiding this comment.
Include user-added words in flashcard deck
In rebuildDeck(), custom entries saved by the Add Word dialog only live in currentLangState().words, but this merge iterates over lang.words and only pushes built-in words whose text was seen before. When a learner adds a new word that is not already in LinguaData, it appears in the wordbook but is never added to currentDeck, so the flashcard module can never review it.
Useful? React with 👍 / 👎.
| { id: 'lesson_10', title: '课程开始', desc: '完成 10 节课', icon: '🎯', check: (s) => s.doneLessons.length >= 10 }, | ||
| { id: 'lesson_50', title: '课程达人', desc: '完成 50 节课', icon: '🎓', check: (s) => s.doneLessons.length >= 50 }, | ||
| { id: 'speak_10', title: '开口的勇气', desc: '完成 10 次口语练习', icon: '🎙️', check: (s) => (s.speakCount || 0) >= 10 }, | ||
| { id: 'listen_10', title: '听力敏锐', desc: '完成 10 次听力练习', icon: '👂', check: (s) => (s.listenCount || 0) >= 10 }, | ||
| { id: 'community_1', title: '初次发声', desc: '在社区发布第一条帖子', icon: '💬', check: (s) => s.myPosts.length >= 1 }, |
There was a problem hiding this comment.
Compare achievement counters as numbers
checkBadges() builds doneLessons and myPosts as numeric counts, but these badge predicates read .length, so s.doneLessons.length and s.myPosts.length are undefined and the lesson/community achievements never unlock when a learner completes 10/50 lessons or posts for the first time.
Useful? React with 👍 / 👎.
| { id: 'vocab5', label: '复习 5 个单词', check: () => countSessionVocabSeen() >= 5, target: 'vocabulary' }, | ||
| { id: 'grammar3', label: '答对 3 题语法', check: () => countSessionGrammarCorrect() >= 3, target: 'grammar' }, | ||
| { id: 'speak1', label: '完成 1 次口语跟读', check: () => (currentLangState().speakCount || 0) >= 1, target: 'speaking' }, | ||
| { id: 'listen1', label: '完成 1 次听力练习', check: () => (currentLangState().listenCount || 0) >= 1, target: 'listening' }, | ||
| { id: 'min10', label: `累计学习 ${store.dailyMin} 分钟`, check: () => totalMinutes() >= store.dailyMin, target: null } |
There was a problem hiding this comment.
Scope daily tasks to the current day
These “daily” task checks are backed by lifetime counters (seen, grammarDone, speakCount, listenCount, and totalMinutes()) rather than values for today's date, so once a learner has ever reviewed 5 words, answered 3 grammar questions, or reached the minute target, those tasks remain completed on every later day.
Useful? React with 👍 / 👎.
| cell.className = 'heat-cell'; | ||
| let lvl = 0; | ||
| if (min > 0 && min < 10) lvl = 1; | ||
| else if (min < 30) lvl = 2; |
There was a problem hiding this comment.
Leave zero-minute heatmap days inactive
For days with no recorded study time, min is 0; the first guard is false, but min < 30 is true, so every inactive day gets data-level="2" instead of level 0. This makes the profile heatmap show activity for all empty days and misrepresents the learner's history.
Useful? React with 👍 / 👎.
🎯 Changes
1. 核心应用重构
2. 数据层更新
assets/lingua-data.js文件,包含英语、日语、韩语的 A1-C2 级别词汇、语法、口语、听力、课程大纲、社区示例和成就徽章数据。buildLessons和buildWords工具方法,用于按级别聚合和生成结构化学习数据。3. 样式与主题
assets/lingua.css文件,引入完整的深色主题样式。4. 前端交互逻辑
assets/lingua.js作为前端主脚本,实现以下功能:5. HTML 结构调整
index.html文件内容大幅改写,以适应新的“Lingua 多语言学习平台”主题。app.js,ai-coach.js,sw.js)。assets/lingua-data.js和assets/lingua.js脚本。💡 Technical Highlights
speechSynthesis实现 TTS 朗读,结合Web Speech API实现口语录音识别和打分,提供沉浸式学习体验。localStorage存储用户偏好和学习进度,结合键盘快捷键提升交互效率。lingua-data.js集中管理,并通过工具方法动态生成,便于内容更新和扩展。