Skip to content

feat(frontend): 设计系统 + macOS Layout + 三套主题 + i18n — 重构 Stage 2 (MOC-254)#504

Open
Cmochance wants to merge 2 commits into
feat/frontend-vue-scaffoldfrom
feat/frontend-vue-stage2
Open

feat(frontend): 设计系统 + macOS Layout + 三套主题 + i18n — 重构 Stage 2 (MOC-254)#504
Cmochance wants to merge 2 commits into
feat/frontend-vue-scaffoldfrom
feat/frontend-vue-stage2

Conversation

@Cmochance

Copy link
Copy Markdown
Owner

重构 Stage 2(stacked on #503)。设计系统 + macOS 外壳 + 三套主题 + i18n 移植。页面真实功能 stage3+ 迁移。

改动

  • 三套主题(白 light / 黑 dark / 国风 inkwash 宣纸水墨):tokens.css + html[data-theme] + useAppearance 切换持久化;国风标题衬线(毛笔意境)
  • macOS sidebar 布局:AppLayout / AppSidebar(毛玻璃 backdrop-filter + 分组导航 + lucide 图标)/ AppTitlebar
  • i18n:从旧 i18n.js 机械提取 zh/en 字典(759/758 keys 零丢失)→ zh.ts/en.ts + t() reactive composable(切语言全局自动重渲染)
  • router:9 页路由(createWebHashHistory)+ 10 页占位
  • ui 原子:AppButton / AppSwitch / SegmentedControl / ThemeSwitcher;unplugin-icons + lucide(编译期内联 SVG, CSP 友好)

验证

playwright(1100×760)真机:三主题切换 + sidebar 导航 + 中英切换全部生效;vue-tsc + vite build 通过。

⚠️ stacked on #503, base = feat/frontend-vue-scaffold。按计划全部 stage 完成 + e2e 验收后才逐个合并, 暂不 merge

Refs MOC-254

stacked on stage1。本阶段搭设计系统与外壳, 页面真实功能 stage3+ 迁移。

- 三套主题 tokens(白 light / 黑 dark / 国风 inkwash 宣纸水墨, html[data-theme]),
  国风标题用衬线(毛笔意境); useAppearance 切换 + 持久化(stage3 接 /api/settings)
- macOS 左侧 sidebar 布局(毛玻璃 backdrop-filter + 分组导航 + lucide 图标) +
  AppLayout / AppSidebar / AppTitlebar
- i18n: 从旧 i18n.js 机械提取 zh/en 字典(759/758 keys 零丢失)→ zh.ts/en.ts +
  t() reactive composable(切语言全局自动重渲染, 替代旧 [data-i18n] 遍历)
- vue-router(createWebHashHistory) 9 页路由骨架 + 10 个页面占位
- ui 原子: AppButton / AppSwitch / SegmentedControl / ThemeSwitcher; 图标走
  unplugin-icons + lucide(编译期内联 SVG, CSP 友好)
- 真机验证(playwright 1100x760): 三主题切换 + sidebar 导航 + 中英切换全部生效

Refs MOC-254
按用户反馈推翻左侧 sidebar 多页设计, 改 FineTune(macOS 原生 SwiftUI 设置 app)极简风格:

- 顶部居中 tab 导航(图标上+文字下, 选中浅色圆角)替代左侧 sidebar; 内容居中
  (max-width 720)+ 慷慨留白
- 分组圆角卡片 SettingsGroup(粗体 section 标题 + 白卡片)+ 设置行 SettingsRow
  (左 标题+灰描述 / 右 控件, 行间细分隔线), 对齐 FineTune Settings 范式
- SettingsPage 示范: 主题/语言用分段选择器, 开关用 macOS 原生 AppSwitch
- 删 AppSidebar/AppTitlebar(死代码); 默认路由 → /providers(顶部 tab 无 dashboard)
- 三主题(白/黑/国风)playwright 真机验证, 国风衬线 section 标题(毛笔意境)

Refs MOC-254

@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: 98c850d33f

ℹ️ 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 frontend/src/main.ts
useAppearance().load()
setLocale(cachedLocale())

createApp(App).use(createPinia()).use(router).mount('#app')

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 Restore the Tauri deeplink listener

When the app is opened via codex-app-transfer://v1/import?..., src-tauri/src/main.rs still emits a codex-deeplink event to the main window, but this new Vue bootstrap mounts the app without registering any listener for that event. The previous frontend consumed it to show the MCP/plugin import confirmation, so these deep links now focus the window and then get dropped silently.

Useful? React with 👍 / 👎.

<SegmentedControl
:model-value="i18nState.locale"
:options="langOptions"
@update:model-value="(v) => setLocale(v as 'zh' | 'en')"

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 Persist locale changes through settings API

Selecting a language here only calls setLocale, which updates the reactive UI state and localStorage; it never saves /api/settings. The backend still uses settings.language to hot-reload adapter prompt language in save_settings, so after a user changes this control the UI appears switched while injected prompts/backend behavior and config-backed startup language remain at the old value.

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