authorgravatar for maria@kuuro.netmaria <maria@kuuro.net> 2026-09-04 00:47:09-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-04 00:47:09-04:00
log07891e9569c88457516b44c08c820471762969e8
tree47e6851906c4f4b3f01334f4f0e5d2f84448a0f6
parentb34ff8f56469afa8f3f85d89894e1b4cf49b5213
signature Signed by PGP key B5690EEEBB952194

fix(web): bound disconnected send toasts (#9592)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

1 files changed, 10 insertions(+), 3 deletions(-)

apps/web/src/components/ChatView.tsx+10-3
...@@ -1335,6 +1335,8 @@ function chatActionErrorMessage(error: unknown): string {...@@ -1335,6 +1335,8 @@ function chatActionErrorMessage(error: unknown): string {
1335 return error instanceof Error ? error.message : "An error occurred.";1335 return error instanceof Error ? error.message : "An error occurred.";
1336}1336}
13371337
1338const ENVIRONMENT_UNAVAILABLE_SEND_TOAST_TRAIL_SIZE = 3;
1339
1338/**1340/**
1339 * Drops the send-time anchored end space. That space is what holds a sent1341 * Drops the send-time anchored end space. That space is what holds a sent
1340 * message near the top while its turn streams, and it keeps LegendList's1342 * message near the top while its turn streams, and it keeps LegendList's
...@@ -1641,6 +1643,7 @@ function ChatViewContent(props: ChatViewProps) {...@@ -1641,6 +1643,7 @@ function ChatViewContent(props: ChatViewProps) {
1641 const attachmentPreviewHandoffByMessageIdRef = useRef<Record<string, string[]>>({});1643 const attachmentPreviewHandoffByMessageIdRef = useRef<Record<string, string[]>>({});
1642 const attachmentPreviewPromotionInFlightByMessageIdRef = useRef<Record<string, true>>({});1644 const attachmentPreviewPromotionInFlightByMessageIdRef = useRef<Record<string, true>>({});
1643 const sendInFlightRef = useRef(false);1645 const sendInFlightRef = useRef(false);
1646 const environmentUnavailableSendToastSlotRef = useRef(0);
1644 const feedbackUploadsInFlightRef = useRef(new Set<string>());1647 const feedbackUploadsInFlightRef = useRef(new Set<string>());
1645 const terminalUiOpenByThreadRef = useRef<Record<string, boolean>>({});1648 const terminalUiOpenByThreadRef = useRef<Record<string, boolean>>({});
16461649
...@@ -6073,13 +6076,17 @@ function ChatViewContent(props: ChatViewProps) {...@@ -6073,13 +6076,17 @@ function ChatViewContent(props: ChatViewProps) {
6073 return;6076 return;
6074 }6077 }
6075 if (activeEnvironmentUnavailable) {6078 if (activeEnvironmentUnavailable) {
6076 toastManager.add(6079 const toastSlot = environmentUnavailableSendToastSlotRef.current;
6077 stackedThreadToast({6080 environmentUnavailableSendToastSlotRef.current =
6081 (toastSlot + 1) % ENVIRONMENT_UNAVAILABLE_SEND_TOAST_TRAIL_SIZE;
6082 toastManager.add({
6083 ...stackedThreadToast({
6078 type: "warning",6084 type: "warning",
6079 title: "Not connected: message not sent",6085 title: "Not connected: message not sent",
6080 description: "Reconnecting to the environment. Try again once it is connected.",6086 description: "Reconnecting to the environment. Try again once it is connected.",
6081 }),6087 }),
6082 );6088 id: `chat-send-environment-unavailable:${toastSlot}`,
6089 });
6083 return;6090 return;
6084 }6091 }
6085 if (activePendingProgress) {6092 if (activePendingProgress) {