From d7fd6ae811b9054ee50098889fd43e22fc1e96f2 Mon Sep 17 00:00:00 2001 From: Vukasin Date: Sat, 19 Jul 2025 16:30:41 +0200 Subject: [PATCH] fix: snack stream re rendering other component and closing issue --- .../[projectId]/thread/[threadId]/page.tsx | 5 ++++- .../components/thread/chat-input/chat-input.tsx | 7 ++++--- .../components/thread/chat-input/chat-snack.tsx | 16 ++++++++++------ .../thread/chat-input/usage-preview.tsx | 6 +++--- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx b/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx index daf92adb..42eb85fd 100644 --- a/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx +++ b/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx @@ -509,8 +509,11 @@ export default function ThreadPage({ setDebugMode(debugParam === 'true'); }, [searchParams]); + const hasCheckedUpgradeDialog = useRef(false); + useEffect(() => { - if (initialLoadCompleted && subscriptionData) { + if (initialLoadCompleted && subscriptionData && !hasCheckedUpgradeDialog.current) { + hasCheckedUpgradeDialog.current = true; const hasSeenUpgradeDialog = localStorage.getItem('suna_upgrade_dialog_displayed'); const isFreeTier = subscriptionStatus === 'no_subscription'; if (!hasSeenUpgradeDialog && isFreeTier && !isLocalMode()) { diff --git a/frontend/src/components/thread/chat-input/chat-input.tsx b/frontend/src/components/thread/chat-input/chat-input.tsx index 25d7ecb0..67ab40a2 100644 --- a/frontend/src/components/thread/chat-input/chat-input.tsx +++ b/frontend/src/components/thread/chat-input/chat-input.tsx @@ -125,6 +125,7 @@ export const ChatInput = forwardRef( const [configModalTab, setConfigModalTab] = useState('integrations'); const [registryDialogOpen, setRegistryDialogOpen] = useState(false); const [showSnackbar, setShowSnackbar] = useState(defaultShowSnackbar); + const [userDismissedUsage, setUserDismissedUsage] = useState(false); const [billingModalOpen, setBillingModalOpen] = useState(false); const { @@ -161,12 +162,12 @@ export const ChatInput = forwardRef( // Auto-show usage preview when we have subscription data useEffect(() => { - if (shouldShowUsage && defaultShowSnackbar !== false && (showSnackbar === false || showSnackbar === defaultShowSnackbar)) { + if (shouldShowUsage && defaultShowSnackbar !== false && !userDismissedUsage && (showSnackbar === false || showSnackbar === defaultShowSnackbar)) { setShowSnackbar('upgrade'); } else if (!shouldShowUsage && showSnackbar !== false) { setShowSnackbar(false); } - }, [subscriptionData, showSnackbar, defaultShowSnackbar, shouldShowUsage, subscriptionStatus, showToLowCreditUsers]); + }, [subscriptionData, showSnackbar, defaultShowSnackbar, shouldShowUsage, subscriptionStatus, showToLowCreditUsers, userDismissedUsage]); const textareaRef = useRef(null); const fileInputRef = useRef(null); @@ -340,7 +341,7 @@ export const ChatInput = forwardRef( showToolPreview={showToolPreview} showUsagePreview={showSnackbar} subscriptionData={subscriptionData} - onCloseUsage={() => setShowSnackbar(false)} + onCloseUsage={() => { setShowSnackbar(false); setUserDismissedUsage(true); }} onOpenUpgrade={() => setBillingModalOpen(true)} isVisible={showToolPreview || !!showSnackbar} /> diff --git a/frontend/src/components/thread/chat-input/chat-snack.tsx b/frontend/src/components/thread/chat-input/chat-snack.tsx index 77c78a84..b7153481 100644 --- a/frontend/src/components/thread/chat-input/chat-snack.tsx +++ b/frontend/src/components/thread/chat-input/chat-snack.tsx @@ -56,6 +56,8 @@ export const ChatSnack: React.FC = ({ notifications.push('usage'); } + + const totalNotifications = notifications.length; const hasMultiple = totalNotifications > 1; @@ -136,13 +138,15 @@ export const ChatSnack: React.FC = ({ type={showUsagePreview} subscriptionData={subscriptionData} onClose={() => { + // First close the usage notification if (onCloseUsage) onCloseUsage(); - // If there are other notifications, switch to them - if (totalNotifications > 1) { - const remainingNotifications = notifications.filter(n => n !== 'usage'); - if (remainingNotifications.length > 0) { - setCurrentView(0); // Switch to first remaining notification - } + + // Check what notifications will remain after closing usage + const willHaveToolNotification = showToolPreview && toolCalls.length > 0; + + // If there will be other notifications, switch to them + if (willHaveToolNotification) { + setCurrentView(0); // Switch to tool notification } }} hasMultiple={hasMultiple} diff --git a/frontend/src/components/thread/chat-input/usage-preview.tsx b/frontend/src/components/thread/chat-input/usage-preview.tsx index ddf5e300..f42ec199 100644 --- a/frontend/src/components/thread/chat-input/usage-preview.tsx +++ b/frontend/src/components/thread/chat-input/usage-preview.tsx @@ -84,7 +84,7 @@ export const UsagePreview: React.FC = ({

- Upgrade for more usage + Upgrade for more usage & better AI Models

@@ -124,8 +124,8 @@ export const UsagePreview: React.FC = ({ )} -
);