Skip to content

fix(overview): 凭据保存后状态不刷新仍显示「未配置」 (#573)#590

Open
appergb wants to merge 1 commit into
betafrom
fix/issue-573-overview-credentials-refresh
Open

fix(overview): 凭据保存后状态不刷新仍显示「未配置」 (#573)#590
appergb wants to merge 1 commit into
betafrom
fix/issue-573-overview-credentials-refresh

Conversation

@appergb
Copy link
Copy Markdown
Collaborator

@appergb appergb commented Jun 4, 2026

User description

问题

Closes #573 (亦覆盖 #532 在 beta 上的复现)

用户(如 Ubuntu 24.04)配好火山引擎 ASR 后,概览页仍显示「未配置」。

根因

在 Settings 中填写/更新凭据但不切换提供商时,Overview 原有的两个刷新触发点都不会触发:

  • 首次挂载的 useEffect
  • 依赖 prefs?.activeAsrProvider / activeLlmProvideruseEffect(保存凭据不会改 active provider)

所以 asrConfigured 状态卡在初始的「未配置」,直到手动切换 provider 或重启 App。

这个修复曾随 #538 合入 main,但随后被 beta → main 合并覆盖,开发主分支 beta 上完全缺失git grep credentials:changed origin/beta 为空)。维护者此前在 issue 回复「更新最新版应该已修了」其实对 beta 用户不成立。

改动(单一职责,2 文件 ~35 行)

  • commands.rsset_credential 保存/删除成功后 emit("credentials:changed")
  • Overview.tsx:新增 useEffect 监听该事件并调用 refreshCredentials()

相比 #538 原版的改进:监听回调复用既有的 refreshCredentials()(带 credentialsRequestSeq 防竞态),而非裸 getCredentials().then(...),避免并发刷新乱序。

验证

  • tsc --noEmit 通过
  • cargo check 通过
  • 真机:火山引擎填三件套不切 provider,Overview 立即变「已配置」

备注

⚠️ 提醒:下次 Merge branch beta into main 时请确保 set_credential 的 emit 不再被丢,否则会第三次回退此修复。

@claude 请审核。


PR Type

Bug fix


Description

  • Emit "credentials:changed" event from backend on credential save/remove

  • Listen for credential updates in Overview to refresh ASR status

  • Fixes ASR status not updating after saving credentials without switching provider


Diagram Walkthrough

flowchart LR
  A["Backend: set_credential saves/removes credentials"] -- "emit `credentials:changed`" --> B["Frontend: Overview listens for event"]
  B -- "calls refreshCredentials()" --> C["ASR configured status updated"]
Loading

File Walkthrough

Relevant files
Bug fix
commands.rs
Emit credential change event from backend                               

openless-all/app/src-tauri/src/commands.rs

+7/-2     
Overview.tsx
Listen for credential updates in Overview                               

openless-all/app/src/pages/Overview.tsx

  • Added useEffect to listen for "credentials:changed" event
  • On event, call refreshCredentials() with existing abort-controller
    safety
  • Clean up listener on unmount
+28/-0   

issue #532/#573:在 Settings 填写/更新凭据但不切换提供商时,Overview 页
原有的 useEffect 不会重跑,asrConfigured 仍停留在「未配置」。

该修复曾随 #538 合入 main,但被 beta→main 合并覆盖,beta(开发主分支)上缺失,
导致用户(如 Ubuntu 24.04)配好火山引擎 ASR 后界面仍显示「未配置」。

- commands.rs: set_credential 保存/删除成功后 emit "credentials:changed"
- Overview.tsx: 监听该事件调用 refreshCredentials()(复用 credentialsRequestSeq 防竞态,
  比 #538 原版裸 getCredentials() 更稳)
@appergb
Copy link
Copy Markdown
Collaborator Author

appergb commented Jun 4, 2026

@claude 请审核这个 PR:把 #538 的「保存凭据后 Overview 不刷新」修复 port 到 beta。重点看:(1) Overview.tsx 新增的 credentials:changed 监听是否正确清理 unlisten 防泄漏;(2) 复用 refreshCredentials() 是否比 #538 原版裸 getCredentials() 更稳;(3) commands.rs emit 时机(保存/删除两条路径)是否都覆盖。

@claude
Copy link
Copy Markdown

claude Bot commented Jun 4, 2026

Claude finished @appergb's task in 1m 29s —— View job


代码审核:PR #590

  • 读取变更文件
  • 检查 Overview.tsx 的 unlisten 清理(防内存泄漏)
  • 检查 refreshCredentials() 复用稳定性
  • 检查 commands.rs 的 emit 时机覆盖(保存/删除两条路径)
  • 综合给出审核结论

(1) unlisten 清理 — ✅ 正确,竞态已完全覆盖

Overview.tsx:107-130 的异步清理模式处理了"cleanup 在 await listen() 完成之前触发"的 TOCTOU 竞态:

// 清理时 listen 还没 resolve → cancelled=true 先设
// listen resolve 之后 → if (cancelled) { handle(); } 立即解注册
if (cancelled) {
  handle();
} else {
  unlisten = handle;
}

两条路径(cleanup 先 / listen 先)都能正确调用 unlisten,不存在泄漏窗口。这是该类异步 Tauri 监听的标准写法,审核通过。


(2) 复用 refreshCredentials() — ✅ 比 #538 原版更稳

refreshCredentialsOverview.tsx:79-94)内部维护了 credentialsRequestSeq

const requestSeq = credentialsRequestSeq.current + 1;
credentialsRequestSeq.current = requestSeq;
// …
if (requestSeq !== credentialsRequestSeq.current) return; // 丢弃过期响应

相比裸 getCredentials().then(setCreds),好处明确:若用户连续保存多个凭据字段,多个并发请求飞出,只有最后一个响应会被采用,前几个被丢弃——避免旧响应覆盖新状态。

另外 refreshCredentialsuseCallback(fn, []) 包裹,引用稳定,所以新 useEffect 的依赖数组 [refreshCredentials] 实际上只触发一次(mount),这正是期望行为:只注册一个监听器。✅


(3) commands.rs emit 时机 — ✅ 两条路径均覆盖,仅成功时触发

// commands.rs:785-794
if value.is_empty() {
    CredentialsVault::remove(acc).map_err(|e| e.to_string())?;  // 失败 → 提前 return Err
} else {
    CredentialsVault::set(acc, &value).map_err(|e| e.to_string())?;  // 失败 → 提前 return Err
}
let _ = window.emit("credentials:changed", ());  // 只有成功时才到达这里
Ok(())

? 运算符确保 vault 操作失败时提前返回,不会发出虚假刷新事件。保存和删除两条路径都覆盖,时机正确。✅


小问题(不阻碍合并,供参考)

window.emit 错误被静默忽略commands.rs:793

let _ = window.emit("credentials:changed", ());

窗口关闭时 emit 失败是正常且无害的,静默忽略合理。但若想在调试阶段有可见性,可改为:

if let Err(e) = window.emit("credentials:changed", ()) {
    log::debug!("[set_credential] emit credentials:changed failed: {e}");
}

这纯属锦上添花,不影响正确性。

commands.rs 注释较长,包含了问题历史背景(#532/#573/#538 的来龙去脉)。这些内容放在 PR description 里更合适,代码注释只保留"为什么要 emit"的一句话即可。同样不阻碍合并。


总结

三个关注点全部审核通过:

关注点 结论
unlisten 清理 ✅ 竞态覆盖完整,无泄漏
refreshCredentials() 复用 ✅ 比原版裸 getCredentials 更稳健
commands.rs emit 时机 ✅ 保存/删除两路均覆盖,仅成功时触发

建议:Approve and merge to beta。 真机验证(填三件套不切 provider,Overview 立即变已配置)是最后一道关,但逻辑上此修复是完整且正确的。

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 4, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

573 - Partially compliant

Compliant requirements:

  • After configuring ASR provider, overview should show "已配置".

Non-compliant requirements:

None

Requires further human verification:

None

532 - Partially compliant

Compliant requirements:

  • After configuring current active ASR provider and saving, overview shows "已配置".
  • Status consistent with backend.
  • Switching providers updates correctly.
  • LLM status unaffected.

Non-compliant requirements:

None

Requires further human verification:

None

⏱️ Estimated effort to review: 1 🔵⚪⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ No major issues detected

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.

配置好火山引擎的asr 为什么界面显示 未配置

1 participant