Skip to content

Commit 68f9735

Browse files
committed
fix(toast): harden desktop voice ready notice
修复 Windows/mac 桌面端语音准备完成绿框仍可能不显示的问题。\n\n取消 /toast 页面 green ready toast 对 i18n 就绪的无谓等待,并为桌面端 session_started(audio) 增加仅在真实录音成功后触发的一次性 ready toast 兜底,避免主成功回调时序遗漏时绿框丢失。
1 parent 02bdf51 commit 68f9735

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

static/app-buttons.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,7 @@
15381538
window.hideVoicePreparingToast();
15391539

15401540
setTimeout(function () {
1541+
window.__nekoLastVoiceReadyToastAt = Date.now();
15411542
window.showReadyToSpeakToast();
15421543
window.startSilenceDetection();
15431544
window.monitorInputVolume();

static/app-websocket.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2560,6 +2560,26 @@
25602560
}
25612561
}, 500);
25622562

2563+
// 桌面端兜底:少数情况下语音会话已经成功启动并进入录音态,
2564+
// 但 app-buttons.js 那条成功回调里的 ready toast 没有实际显示。
2565+
// 仅在桌面端、audio 模式、且已经进入录音态时补发一次,网页端不受影响。
2566+
if (response.input_mode !== 'text' && window.__NEKO_DESKTOP_RUNTIME__) {
2567+
if (window.__nekoDesktopVoiceReadyFallbackTimer) {
2568+
clearTimeout(window.__nekoDesktopVoiceReadyFallbackTimer);
2569+
}
2570+
window.__nekoDesktopVoiceReadyFallbackTimer = setTimeout(function () {
2571+
window.__nekoDesktopVoiceReadyFallbackTimer = null;
2572+
if (!S.voiceChatActive) return;
2573+
if (!(S.isRecording || window.isRecording)) return;
2574+
var lastReadyToastAt = Number(window.__nekoLastVoiceReadyToastAt || 0);
2575+
if (Date.now() - lastReadyToastAt < 1200) return;
2576+
if (typeof window.showReadyToSpeakToast === 'function') {
2577+
window.__nekoLastVoiceReadyToastAt = Date.now();
2578+
window.showReadyToSpeakToast();
2579+
}
2580+
}, 1800);
2581+
}
2582+
25632583
// 语音模式:session 开始 5 秒内无 transcription,启动 proactive chat 计时器
25642584
if (response.input_mode !== 'text' && S.proactiveChatEnabled && !S.gameRouteActive) {
25652585
if (S._voiceSessionInitialTimer) {
@@ -2584,6 +2604,10 @@
25842604
clearTimeout(window.sessionTimeoutId);
25852605
window.sessionTimeoutId = null;
25862606
}
2607+
if (window.__nekoDesktopVoiceReadyFallbackTimer) {
2608+
clearTimeout(window.__nekoDesktopVoiceReadyFallbackTimer);
2609+
window.__nekoDesktopVoiceReadyFallbackTimer = null;
2610+
}
25872611
if (S.sessionStartedRejecter) {
25882612
S.sessionStartedRejecter(new Error(response.message || (window.t ? window.t('app.sessionFailed') : 'Session启动失败')));
25892613
} else {
@@ -2624,6 +2648,10 @@
26242648
clearTimeout(window.sessionTimeoutId);
26252649
window.sessionTimeoutId = null;
26262650
}
2651+
if (window.__nekoDesktopVoiceReadyFallbackTimer) {
2652+
clearTimeout(window.__nekoDesktopVoiceReadyFallbackTimer);
2653+
window.__nekoDesktopVoiceReadyFallbackTimer = null;
2654+
}
26272655

26282656
if (S.isRecording) {
26292657
if (typeof window.stopRecording === 'function') window.stopRecording();

templates/toast.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,10 +424,11 @@
424424
api.onHideVoicePreparing(function() {
425425
hideVoicePreparing();
426426
});
427-
// ready-to-speak / prominent notice:需要 window.t(),等待 i18n 就绪
427+
// ready toast 自带 fallback 文案,不应被 i18n 时序阻塞。
428428
api.onShowReadyToSpeak(function(data) {
429-
whenI18nReady(function() { showReadyToSpeak(data.message); });
429+
showReadyToSpeak(data.message);
430430
});
431+
// prominent notice:需要 window.t(),等待 i18n 就绪
431432
api.onShowProminentNotice(function(data) {
432433
whenI18nReady(function() { showProminentNotice(data); });
433434
});

0 commit comments

Comments
 (0)