Skip to content

feat: 重构为 Lingua 多语言学习平台#1

Open
tuxiaobin-123 wants to merge 1 commit into
mainfrom
trae/solo-agent-IwAbhC
Open

feat: 重构为 Lingua 多语言学习平台#1
tuxiaobin-123 wants to merge 1 commit into
mainfrom
trae/solo-agent-IwAbhC

Conversation

@tuxiaobin-123

Copy link
Copy Markdown
Owner

🎯 Changes

1. 核心应用重构

  • 将原有“聊天/沟通训练”应用完全重构为“Lingua 多语言学习平台”。
  • 移除旧有聊天相关功能(如快速反应、AI 复盘、情绪趋势图等)。
  • 新增多语言学习核心模块,包括分级课程、单词、语法、口语、听力、推荐、社区、成就和个人档案。

2. 数据层更新

  • 新增 assets/lingua-data.js 文件,包含英语、日语、韩语的 A1-C2 级别词汇、语法、口语、听力、课程大纲、社区示例和成就徽章数据。
  • 提供 buildLessonsbuildWords 工具方法,用于按级别聚合和生成结构化学习数据。

3. 样式与主题

  • 新增 assets/lingua.css 文件,引入完整的深色主题样式。
  • 覆盖了网格布局、卡片、首页 Hero、分级课程轨道、闪卡 3D 翻转动画、答题面板、口语跟读反馈区、听力播放控制、每日任务、社区发帖、成就徽章、排行榜、学习档案、热力图、弹层和 Toast 通知等所有主要 UI 元素。
  • 适配 960px 和 520px 两种响应式断点。

4. 前端交互逻辑

  • 新增 assets/lingua.js 作为前端主脚本,实现以下功能:
    • 用户存储(localStorage)、登录/注册、语种与水平切换。
    • 首页每日金句与预览。
    • 分级课程列表与筛选。
    • 单词闪卡(翻面、TTS 朗读、间隔重复、洗牌、自定义单词、我的词本)。
    • 语法选择题作答与反馈。
    • 口语跟读(TTS + Web Speech API 录音识别、相似度/语速/词数打分)。
    • 听力训练(多倍速播放、原文切换、理解题作答)。
    • 个性化推荐与薄弱模块分析、每日任务清单。
    • 社区发帖、筛选、点赞。
    • 成就徽章解锁与本地 XP 排行榜。
    • 个人档案、水平自评、热力图、学习活动记录、XP 与连续天数统计。
    • 键盘快捷键支持(空格翻面、1/2/3 快速标记记忆)。

5. HTML 结构调整

  • index.html 文件内容大幅改写,以适应新的“Lingua 多语言学习平台”主题。
  • 移除旧有脚本引用 (app.js, ai-coach.js, sw.js)。
  • 新增左侧导航栏、语言切换栏、各模块视图容器、闪卡与单词添加弹层、语法答题面板、口语跟读卡、听力播放区、社区发帖表单、徽章网格、排行榜、个人档案卡片、水平自评表单、热力图、学习记录表格、登录注册弹窗和全局 Toast 容器。
  • 引入新的 assets/lingua-data.jsassets/lingua.js 脚本。

💡 Technical Highlights

  • 模块化设计: 将数据、样式和逻辑分离,便于维护和扩展。
  • 多语言支持: 数据层支持多语种内容,前端实现语种切换功能。
  • Web Speech API 集成: 利用 speechSynthesis 实现 TTS 朗读,结合 Web Speech API 实现口语录音识别和打分,提供沉浸式学习体验。
  • 响应式设计: 样式文件适配不同屏幕尺寸,提供良好的用户体验。
  • 本地存储与用户体验: 利用 localStorage 存储用户偏好和学习进度,结合键盘快捷键提升交互效率。
  • 数据驱动: 学习内容通过 lingua-data.js 集中管理,并通过工具方法动态生成,便于内容更新和扩展。

Co-authored-by: traeagent <traeagent@users.noreply.github.com>
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment Jun 18, 2026 12:43pm

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread assets/lingua.js
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));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread assets/lingua-data.js
Comment on lines +351 to +355
{ 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 },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread assets/lingua.js
Comment on lines +723 to +727
{ 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 }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread assets/lingua.js
cell.className = 'heat-cell';
let lvl = 0;
if (min > 0 && min < 10) lvl = 1;
else if (min < 30) lvl = 2;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant