Skip to content

feat(settings): cross-platform parity for local ASR#403

Open
appergb wants to merge 5 commits intobetafrom
feat/advanced-cross-platform-parity
Open

feat(settings): cross-platform parity for local ASR#403
appergb wants to merge 5 commits intobetafrom
feat/advanced-cross-platform-parity

Conversation

@appergb
Copy link
Copy Markdown
Collaborator

@appergb appergb commented May 10, 2026

User description

Summary

  • Fixes feat(settings): hide local ASR behind new Advanced tab + confirm dialog #400 cross-platform bug: Qwen3 row was rendered on Windows in Settings → Advanced, but qwen_engine / local_provider / cache are all #[cfg(target_os = "macos")] → Enable on Windows always errors. New layout: macOS shows Qwen3 enabled + Foundry hidden; Windows shows Foundry enabled + Qwen3 disabled with notSupportedHere desc.
  • Centered + blurred enable-confirm modal: replaces the page-top amber popup card; position: fixed, backdropFilter: blur(8px), click-outside-to-cancel (busy-guarded).
  • Inline warning: amber warning Card collapses to an 11px badge in the title row's top-right.
  • Providers ASR Card takeover UX: plain-text localAsrActiveNotice branch removed. Dropdown now always renders, including the platform-native local engine (macOS=Qwen3, Windows=Foundry) as a disabled option with a takeover hint. Entire dropdown locks while a local engine is active, so it can only be released via Advanced.
  • Missing emitSaved on provider switch: onLlmProviderChange / onAsrProviderChange now emit saving → saved via emitSaved. Data was already being persisted; only the right-corner toast was missing — that's why "切换 Ark / OpenAI 没保存提示".
  • LocalAsr embedded: Qwen3 model management (mirror source / model list / engine status) hidden on Windows — dead UI without the Qwen3 backend. Shared error Card kept unconditional since Foundry handlers also call setError.
  • i18n × 5: shorten localAsrWarningShort; rewrite qwen3Desc / foundryDesc to "启动之后,ASR 提供商将被接管"; add notSupportedHere, localAsrTakeoverHint.

Test plan

macOS (verified locally with ./scripts/build-mac.sh install):

  • npm run build — tsc + vite build green
  • Settings → 高级: warning is single 11px line in title's top-right; Qwen3 row desc is "启动之后..."
  • 点 Qwen3 [启用] → 屏幕中央 backdrop-blur modal; 遮罩 / 取消 关闭; 确认完成切换
  • Settings → 提供商 → ASR Card: 下拉最后一项 Qwen3-ASR 灰禁,下方"启动 Qwen3-ASR 后..."提示
  • 切 LLM 下拉 (Ark→DeepSeek): saving → saved toast 闪过
  • 启用 Qwen3 后 ASR 下拉锁定;Advanced 点禁用后才能切回云端

Windows (static — needs separate test box):

  • 高级: Qwen3 行 disabled "本平台暂不支持,未集成推理模块"; Foundry 行可启用
  • 提供商 → ASR 下拉最后一项 Foundry Local Whisper 灰禁
  • LocalAsr embedded: 不显示 Qwen3 镜像源/模型列表,只 Foundry block

Notes

  • Foundry block 内部 layout 没动 — Foundry 有 runtime source 切换 / language hint / prepare progress 这些 Qwen3 没有的控件,机械同构会丢功能。如需更深的 Foundry UI 重排,单独再提一轮。
  • PR Add Codex OAuth LLM provider #401 (Codex OAuth) 仍是 Draft;本 PR 跟它没改同样的 i18n/Settings.tsx 行,理论上互不冲突,但合并次序看维护者裁决。

PR Type

Enhancement, Bug fix


Description

  • Add toast notifications for provider switch success/failure

    • emitSaved('saving'/'saved'/'failed') now wraps LLM/ASR changes
    • Stale seq guards prevent wrong toast on retries
  • Replace local ASR enable popup with centered blurred modal

    • Fixed overlay, backdrop blur, click‑outside‑to‑cancel
    • Busy state blocks dismissal during switch
  • Achieve cross‑platform parity for local ASR rows

    • macOS: Qwen3 toggle; Windows: Foundry toggle
    • Non‑native engine shows “not supported” desc instead of hidden
    • Anomalous cross‑machine configs get a disabled dropdown escape
  • Simplify ASR provider dropdown into always‑rendered locked selector

    • Local option always visible but disabled until enabled
    • Takeover hint explains provider takeover behaviour
  • Restrict Qwen3 model management UI to macOS only

    • Prevents dead UI on Windows/Linux (backend is macOS‑only)

Diagram Walkthrough

flowchart LR
  A["Settings UI"] --> B["Provider switch toasts"]
  A --> C["Centered confirm modal"]
  A --> D["Platform‑aware local ASR rows"]
  A --> E["ASR dropdown with lock & hint"]
  A --> F["Qwen3 management restricted to macOS"]
Loading

File Walkthrough

Relevant files
Enhancement
6 files
en.ts
Add takeover hint and simplify warning strings                     
+5/-3     
ja.ts
Add takeover hint and simplify warning strings                     
+5/-3     
ko.ts
Add takeover hint and simplify warning strings                     
+5/-3     
zh-CN.ts
Add takeover hint and simplify warning strings                     
+5/-3     
zh-TW.ts
Add takeover hint and simplify warning strings                     
+5/-3     
Settings.tsx
Provider toasts, modal, cross‑platform rows, dropdown lock
+254/-151
Bug fix
1 files
LocalAsr.tsx
Restrict Qwen3 model management to macOS only                       
+14/-0   
Configuration changes
1 files
default.json
Add dialog permission for native confirm popup                     
+2/-1     

- AdvancedSection: warning collapses to inline 11px amber badge in
  the title row's top-right; the enable-confirm popup is now a
  centered fixed modal with backdrop blur(8px) and click-outside-
  to-cancel (busy-guarded).
- Symmetric rows by platform — fixes the #400 bug where the Qwen3
  row was rendered on Windows even though all qwen_engine /
  local_provider / cache modules are #[cfg(target_os = "macos")],
  so Enable on Windows would always error:
    macOS:   Qwen3 row enabled / Foundry row hidden
    Windows: Foundry row enabled / Qwen3 row disabled with
             notSupportedHere desc
- Providers ASR Card: replaces the plain-text localAsrActiveNotice
  branch with an always-rendered dropdown that includes the
  platform-native local engine (macOS=Qwen3, Windows=Foundry) as a
  disabled option, plus a takeover hint underneath. Entire
  dropdown locks when a local engine is active, so it can only be
  released via Advanced (matches "启动之后供应商将被接管" UX).
- onLlmProviderChange / onAsrProviderChange now emit saving →
  saved through emitSaved. Data was already being persisted; the
  saved-toast was missing.
- LocalAsr embedded: hide Qwen3 model management (mirror /
  engine-status / model list) on Windows — dead UI without the
  Qwen3 backend. The shared error Card is kept unconditional
  since Foundry handlers also call setError.
- i18n × 5 (zh-CN/zh-TW/en/ja/ko): shorten localAsrWarningShort;
  rewrite qwen3Desc and foundryDesc to '启动之后,ASR 提供商将被接管';
  add notSupportedHere and localAsrTakeoverHint.
@appergb
Copy link
Copy Markdown
Collaborator Author

appergb commented May 10, 2026

QAQ

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 10, 2026

PR Reviewer Guide 🔍

(Review updated until commit 7e23e3d)

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

400 - Partially compliant

Compliant requirements:

  • Added an Advanced settings tab with platform-specific local ASR controls.
  • Removed local ASR from the main Providers → ASR selection flow and keep it locked while active.
  • Added a centered warning modal before enabling local ASR.
  • Preserved a disable path back to cloud ASR.
  • Added locale updates for en, ja, ko, zh-CN, and zh-TW.

Non-compliant requirements:

  • Automated build/test verification results are not included in the diff.

Requires further human verification:

  • Confirm the modal placement, blur, and click-outside-to-cancel behavior on each supported platform.
  • Verify the per-platform visibility and enable/disable behavior in the actual macOS and Windows UI.
⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ No major issues detected

pr_agent #403 caught: emitSaved('saving') with no try/catch — if
setActiveLlmProvider / setActiveAsrProvider / any later credential
write throws, the right-corner toast stays stuck on saving forever.

Wrap both onLlmProviderChange and onAsrProviderChange bodies in
try/catch. On error, emit 'failed' (and re-throw) only if seq still
matches — stale calls superseded by a newer switch shouldn't
overwrite the newer call's own saving state.
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 7a65cee

… pr_agent #403

Fixes piled up in user feedback during local verify of the previous
commit; bundled into one commit to keep #403 small.

- capabilities/default.json: add `dialog:default` permission. The
  About → Export error log button always failed because the Tauri 2
  capabilities did not allow `tauri-plugin-dialog`'s `save()` command;
  the JS rejected before export_error_log was ever invoked.

- ProvidersSection ASR Card (pr_agent #403 'Wrong active label'):
  when committedAsrProvider is a local engine, selectedValue now
  reflects the actually-active engine instead of being forced to
  platformLocalAsr. Cross-machine config sync (macOS profile with
  foundry-local-whisper / Windows profile with local-qwen3) used to
  make the dropdown lie about which backend is running. Anomalous
  local engines are added as disabled <option>s so the controlled
  <select> still finds its value and doesn't fall back to the first
  option.

- ProvidersSection: drop verbose desc on LLM and ASR provider rows.
  '选择后将自动填入 Base URL 默认值。' is ~16 Chinese chars and
  always wraps inside the 180px label column, leaving a stranded
  second line on the left — the dropdown itself already conveys the
  semantic, the desc was redundant.

- AdvancedSection: replace the [启用] / [已启用] Btn with the
  shared Toggle component for Qwen3 and Foundry rows. Toggle off
  switches back to volcengine. The Qwen3 row's Toggle truthfully
  reflects committed state on Windows (so a cross-platform anomaly
  shows ON even though it is non-interactive there). The standalone
  '禁用本地 ASR' escape row is now only rendered when no inline
  Toggle can disable the active engine — i.e., Linux / unsupported
  platform, or anomaly where the row for the foreign engine is
  hidden / non-interactive.

- PermissionsSection: every status pill (microphone, accessibility,
  hotkey, Windows IME, network) now right-aligns inside its row via
  `justifyContent: flex-end` + `width: 100%`. Pill text moved to the
  right of inline messages so the green '已授权' / 'Authorized'
  reads as a right-edge badge — closer to macOS System Settings
  convention.
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 678a5fd

pr_agent 'Stale Windows state' caught: previous commit had `on=
{isOnLocalQwen3}` which truthfully reflected committed state, so a
profile synced from macOS with activeAsrProvider=local-qwen3 would
render Toggle ON next to a desc that says '本平台暂不支持'. The
visual contradiction was the concern.

Switch to `on={isMac && isOnLocalQwen3}` — Windows always renders
the row OFF + non-interactive, matching the unsupported desc. The
cross-platform anomaly state surfaces via the standalone '禁用本地
ASR' escape row, which is rendered exactly when no inline Toggle
can disable the active engine.

Comment updated to match the new behavior and document the
tradeoff.
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit be270eb

pr_agent 'Linux regression' caught: previous wrap was `!IS_WINDOWS`,
so a hypothetical Linux render path would still expose the Qwen3
mirror / model-list / engine-status UI even though Qwen3's backend
is `#[cfg(target_os = "macos")]`.

Swap the two wrappers to `IS_MAC` so the management cards only
materialize on macOS. Today's AdvancedSection guards LocalAsr
embedded with `platformSupported = isMac || isWin`, so Linux already
short-circuits before LocalAsr renders — but defense in depth here
costs nothing and keeps the comment accurate.
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 7e23e3d

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant