Skip to content

Commit 2fbe93e

Browse files
authored
feat: Revamped update banner (#1659)
## Problem Update notifications were easy to miss as ephemeral toasts and the "ready to install" state had no persistent UI. _The little gift icon animates / shakes periodically so they know something good is inside._ _This_ _is_ _the_ _most_ _important_ _part._ <!-- Who is this for and what problem does it solve? --> Closes #1640 ![CleanShot 2026-04-15 at 15.56.07@2x.png](https://app.graphite.com/user-attachments/assets/f3c4cb1a-5f5f-4615-8b77-1d9a63b40fba.png) ## Changes 1. Replace toast-based UpdatePrompt with persistent UpdateBanner in sidebar 2. Add updateStore (Zustand) to manage update lifecycle state via tRPC subscriptions 3. Animate banner transitions between downloading, ready and installing states 4. Add border separator above ProjectSwitcher for visual consistency <!-- What did you change and why? --> <!-- If there are frontend changes, include screenshots. --> ## How did you test this? Manually <!-- Describe what you tested -- manual steps, automated tests, or both. --> <!-- If you're an agent, only list tests you actually ran. -->
1 parent 5c2e519 commit 2fbe93e

5 files changed

Lines changed: 230 additions & 281 deletions

File tree

apps/code/src/renderer/App.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { ErrorBoundary } from "@components/ErrorBoundary";
22
import { LoginTransition } from "@components/LoginTransition";
33
import { MainLayout } from "@components/MainLayout";
44
import { ScopeReauthPrompt } from "@components/ScopeReauthPrompt";
5-
import { UpdatePrompt } from "@components/UpdatePrompt";
65
import { AuthScreen } from "@features/auth/components/AuthScreen";
76
import { InviteCodeScreen } from "@features/auth/components/InviteCodeScreen";
87
import { useAuthStateValue } from "@features/auth/hooks/authQueries";
@@ -13,6 +12,7 @@ import { Flex, Spinner, Text } from "@radix-ui/themes";
1312
import { initializeConnectivityStore } from "@renderer/stores/connectivityStore";
1413
import { useFocusStore } from "@renderer/stores/focusStore";
1514
import { useThemeStore } from "@renderer/stores/themeStore";
15+
import { initializeUpdateStore } from "@renderer/stores/updateStore";
1616
import { trpcClient, useTRPC } from "@renderer/trpc/client";
1717
import { ANALYTICS_EVENTS } from "@shared/types/analytics";
1818
import { useQueryClient } from "@tanstack/react-query";
@@ -49,6 +49,11 @@ function App() {
4949
return initializeConnectivityStore();
5050
}, []);
5151

52+
// Initialize update store
53+
useEffect(() => {
54+
return initializeUpdateStore();
55+
}, []);
56+
5257
// Dev-only inbox demo command for local QA from the renderer console.
5358
useEffect(() => {
5459
if (import.meta.env.PROD) {
@@ -218,7 +223,6 @@ function App() {
218223
onComplete={handleTransitionComplete}
219224
/>
220225
<ScopeReauthPrompt />
221-
<UpdatePrompt />
222226
<Toaster position="bottom-right" />
223227
</ErrorBoundary>
224228
);

apps/code/src/renderer/components/UpdatePrompt.tsx

Lines changed: 0 additions & 278 deletions
This file was deleted.

apps/code/src/renderer/features/sidebar/components/SidebarContent.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useNavigationStore } from "@stores/navigationStore";
55
import type React from "react";
66
import { ProjectSwitcher } from "./ProjectSwitcher";
77
import { SidebarMenu } from "./SidebarMenu";
8+
import { UpdateBanner } from "./UpdateBanner";
89

910
export const SidebarContent: React.FC = () => {
1011
const archivedTaskIds = useArchivedTaskIds();
@@ -17,6 +18,7 @@ export const SidebarContent: React.FC = () => {
1718
<Box flexGrow="1" overflow="hidden">
1819
<SidebarMenu />
1920
</Box>
21+
<UpdateBanner />
2022
{archivedTaskIds.size > 0 && (
2123
<Box className="shrink-0 border-gray-6 border-t">
2224
<button
@@ -31,7 +33,7 @@ export const SidebarContent: React.FC = () => {
3133
</button>
3234
</Box>
3335
)}
34-
<Box p="2" className="shrink-0">
36+
<Box p="2" className="shrink-0 border-gray-6 border-t">
3537
<ProjectSwitcher />
3638
</Box>
3739
</Flex>

0 commit comments

Comments
 (0)