From 11c6a37ce030f8e64de5c810da07ec7fab3b0615 Mon Sep 17 00:00:00 2001 From: qer Date: Tue, 7 Jul 2026 20:47:56 +0800 Subject: [PATCH] fix(web): dismiss stale connection error toast after ws reconnect (#1474) --- .changeset/fix-web-ws-reconnect-toast.md | 5 +++++ .../src/composables/useKimiWebClient.ts | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 .changeset/fix-web-ws-reconnect-toast.md diff --git a/.changeset/fix-web-ws-reconnect-toast.md b/.changeset/fix-web-ws-reconnect-toast.md new file mode 100644 index 000000000..dbf190b92 --- /dev/null +++ b/.changeset/fix-web-ws-reconnect-toast.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +web: Fix the connection error toast lingering after the WebSocket reconnects when returning from the background. diff --git a/apps/kimi-web/src/composables/useKimiWebClient.ts b/apps/kimi-web/src/composables/useKimiWebClient.ts index 475345b4b..2f7e822fc 100644 --- a/apps/kimi-web/src/composables/useKimiWebClient.ts +++ b/apps/kimi-web/src/composables/useKimiWebClient.ts @@ -929,6 +929,12 @@ function connectEventsIfNeeded(): void { onConnectionChange(connected: boolean) { rawState.connected = connected; rawState.connection = connected ? 'connected' : 'disconnected'; + // The data channel is healthy again (server_hello received). Clear any + // stale "Realtime connection error" toast instead of relying on its + // auto-dismiss timer: iOS Safari freezes timers while a tab is + // backgrounded, so the toast would otherwise linger until a manual + // refresh even though the reconnect already succeeded. + if (connected) dismissWsError(); }, }); } @@ -1095,6 +1101,19 @@ function pushWarning(warning: AppWarning): void { rawState.warnings = [...rawState.warnings, warning]; } +// Drop every "Realtime connection error" notice pushed by the WS onError +// handler. Matched by severity + the localized wsTitle (the same i18n instance +// used to push it), so other errors are left untouched. +function dismissWsError(): void { + const title = i18n.global.t('warnings.wsTitle'); + const next = rawState.warnings.filter( + (w) => !(typeof w === 'object' && w !== null && w.severity === 'error' && w.title === title), + ); + if (next.length !== rawState.warnings.length) { + rawState.warnings = next; + } +} + function pushOperationFailure( operation: string, err: unknown,