fix(capsule): 终止态后 2 秒自动隐藏 — 覆盖 Done / Cancelled / Error 全部路径 (#77)
之前只有 Done 路径有 700ms 自动隐藏,cancel / 各种 error 都让胶囊一直挂着。 用户反馈:不论点 ✕ / ✓ / 中途出错 / 按 Esc,2 秒后底部胶囊都应自动消失。 修改: - 新增 CAPSULE_AUTO_HIDE_DELAY_MS = 2000 + schedule_capsule_idle(inner, ms) helper 延迟后再次检查 phase==Idle 才 emit Idle,避免覆盖期间用户重新触发的 Recording - Done 路径:原 700ms inline schedule 替换为 helper 调用 (2s) - Cancelled 路径:cancel_session 末尾追加 schedule_capsule_idle - Error 路径 5 处:mic 权限失败 / ASR 连接失败 / 录音启动失败 / await_final 失败 / Whisper transcribe 失败,全部追加 schedule_capsule_idle Co-authored-by: baiqing <lbx12309@icloud.com>
This commit is contained in:
1 parent
1e101a3147
commit
e99fe6cfbd
1 file changed
+23
-6
@@ -332,6 +332,7 @@ async fn begin_session(inner: &Arc<Inner>) -> Result<(), String> {
|
||||
None,
|
||||
);
|
||||
inner.state.lock().phase = SessionPhase::Idle;
|
||||
schedule_capsule_idle(inner, CAPSULE_AUTO_HIDE_DELAY_MS);
|
||||
return Err(message);
|
||||
}
|
||||
|
||||
@@ -360,6 +361,7 @@ async fn begin_session(inner: &Arc<Inner>) -> Result<(), String> {
|
||||
None,
|
||||
);
|
||||
inner.state.lock().phase = SessionPhase::Idle;
|
||||
schedule_capsule_idle(inner, CAPSULE_AUTO_HIDE_DELAY_MS);
|
||||
return Err(e.to_string());
|
||||
}
|
||||
let c: Arc<dyn crate::recorder::AudioConsumer> = Arc::new(AsrBridge {
|
||||
@@ -439,6 +441,7 @@ async fn begin_session(inner: &Arc<Inner>) -> Result<(), String> {
|
||||
None,
|
||||
);
|
||||
inner.state.lock().phase = SessionPhase::Idle;
|
||||
schedule_capsule_idle(inner, CAPSULE_AUTO_HIDE_DELAY_MS);
|
||||
return Err(e.to_string());
|
||||
}
|
||||
}
|
||||
@@ -489,6 +492,7 @@ async fn end_session(inner: &Arc<Inner>) -> Result<(), String> {
|
||||
None,
|
||||
);
|
||||
inner.state.lock().phase = SessionPhase::Idle;
|
||||
schedule_capsule_idle(inner, CAPSULE_AUTO_HIDE_DELAY_MS);
|
||||
return Err(e.to_string());
|
||||
}
|
||||
}
|
||||
@@ -506,6 +510,7 @@ async fn end_session(inner: &Arc<Inner>) -> Result<(), String> {
|
||||
None,
|
||||
);
|
||||
inner.state.lock().phase = SessionPhase::Idle;
|
||||
schedule_capsule_idle(inner, CAPSULE_AUTO_HIDE_DELAY_MS);
|
||||
return Err(e.to_string());
|
||||
}
|
||||
},
|
||||
@@ -591,12 +596,7 @@ async fn end_session(inner: &Arc<Inner>) -> Result<(), String> {
|
||||
);
|
||||
|
||||
inner.state.lock().phase = SessionPhase::Idle;
|
||||
|
||||
let inner_clone = Arc::clone(inner);
|
||||
async_runtime::spawn(async move {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(700)).await;
|
||||
emit_capsule(&inner_clone, CapsuleState::Idle, 0.0, 0, None, None);
|
||||
});
|
||||
schedule_capsule_idle(inner, CAPSULE_AUTO_HIDE_DELAY_MS);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -626,6 +626,7 @@ fn cancel_session(inner: &Arc<Inner>) {
|
||||
}
|
||||
emit_capsule(inner, CapsuleState::Cancelled, 0.0, 0, None, None);
|
||||
log::info!("[coord] session cancelled (was {phase:?})");
|
||||
schedule_capsule_idle(inner, CAPSULE_AUTO_HIDE_DELAY_MS);
|
||||
}
|
||||
|
||||
// ─────────────────────────── helpers ───────────────────────────
|
||||
@@ -781,6 +782,22 @@ fn enabled_phrases(inner: &Arc<Inner>) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// 终止态(Done / Cancelled / Error)后延迟 N ms 把胶囊改回 Idle,让浮窗自动消失。
|
||||
/// 用户点 ✕ / ✓ / 中途出错 / 按 Esc 都走这里,统一 2 秒。
|
||||
const CAPSULE_AUTO_HIDE_DELAY_MS: u64 = 2000;
|
||||
|
||||
fn schedule_capsule_idle(inner: &Arc<Inner>, delay_ms: u64) {
|
||||
let inner_clone = Arc::clone(inner);
|
||||
async_runtime::spawn(async move {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(delay_ms)).await;
|
||||
// 仅在仍然 Idle 时(即用户没在这 2s 内重新触发)才 hide。
|
||||
// 否则可能把新启动的 Recording 状态意外覆盖回 Idle。
|
||||
if inner_clone.state.lock().phase == SessionPhase::Idle {
|
||||
emit_capsule(&inner_clone, CapsuleState::Idle, 0.0, 0, None, None);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn emit_capsule(
|
||||
inner: &Arc<Inner>,
|
||||
state: CapsuleState,
|
||||
|
||||
Reference in new issue
Block a user