From 62f8d4c09a25d158ea67a281e7577f05a2febb14 Mon Sep 17 00:00:00 2001 From: ciregenz Date: Mon, 3 Aug 2026 16:23:59 -0700 Subject: [PATCH] [eric] updater: restart affordance becomes a quiet Claude-style card, icon chip + version subtitle + arrow --- .../app/components/Layout/UpdateReadyPill.tsx | 92 +++++++++++++------ 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/frontend/src/app/components/Layout/UpdateReadyPill.tsx b/frontend/src/app/components/Layout/UpdateReadyPill.tsx index a9ad459f..8466b3d3 100644 --- a/frontend/src/app/components/Layout/UpdateReadyPill.tsx +++ b/frontend/src/app/components/Layout/UpdateReadyPill.tsx @@ -4,19 +4,19 @@ import Grow from '@mui/material/Grow'; import Typography from '@mui/material/Typography'; import CircularProgress from '@mui/material/CircularProgress'; import RestartAltIcon from '@mui/icons-material/RestartAlt'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; import CloseIcon from '@mui/icons-material/Close'; import { useAppDispatch, useAppSelector } from '@/shared/hooks'; import { setInstalling } from '@/shared/state/updateSlice'; -import { useClaudeTokens, useThemeMode } from '@/shared/styles/ThemeContext'; +import { useClaudeTokens } from '@/shared/styles/ThemeContext'; const UPDATE_DISMISS_KEY = 'openswarm-update-dismissed'; -// Chrome/Claude-style: the download already ran silently (autoDownload in main.js), so the only -// state worth pixels is "ready". One pill, top-right, above the frameless-window drag strip that -// used to swallow the old banner button's clicks. +// Claude-desktop-style quiet card, not a colored capsule: the download already ran silently +// (autoDownload in main.js), so the only state worth pixels is "ready". Top-right, above the +// frameless-window drag strip that used to swallow the old banner button's clicks. const UpdateReadyPill: React.FC = () => { const c = useClaudeTokens(); - const { mode } = useThemeMode(); const dispatch = useAppDispatch(); const updateStatus = useAppSelector((s) => s.update.status); const availableVersion = useAppSelector((s) => s.update.availableVersion); @@ -54,7 +54,6 @@ const UpdateReadyPill: React.FC = () => { onClick={handleInstall} role="button" aria-label={availableVersion ? `Restart to update to ${availableVersion}` : 'Restart to update'} - title={availableVersion ? `OpenSwarm ${availableVersion} downloaded` : 'Update downloaded'} sx={{ position: 'fixed', top: 34, @@ -64,44 +63,79 @@ const UpdateReadyPill: React.FC = () => { WebkitAppRegion: 'no-drag', display: 'flex', alignItems: 'center', - gap: 0.75, - height: 30, + gap: 1.25, pl: 1.25, - pr: 1, - borderRadius: 999, - // Success green, NOT the accent: every other pill on the shell is accent-colored, and an update call-to-action that matches New-dashboard reads as furniture (Chrome's update pill is green for the same reason). Dark mode's lighter green needs dark text. - bgcolor: c.status.success, - color: mode === 'dark' ? 'rgba(0,0,0,0.85)' : '#fff', - boxShadow: `0 0 0 3px ${c.status.success}40, 0 8px 24px rgba(0,0,0,0.35)`, + pr: 1.5, + py: 1, + borderRadius: '12px', + bgcolor: c.bg.surface, + border: `1px solid ${hovered ? c.border.strong : c.border.medium}`, + boxShadow: hovered ? c.shadow.lg : c.shadow.md, cursor: installing ? 'default' : 'pointer', userSelect: 'none', - transition: 'filter 0.2s ease, transform 0.15s ease', - '&:hover': { filter: installing ? 'none' : 'brightness(1.12)' }, - '&:active': { transform: installing ? 'none' : 'scale(0.97)' }, + transition: 'box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease', + transform: hovered && !installing ? 'translateY(-1px)' : 'none', }} > + + + + + + {installing ? 'Restarting…' : 'Restart to update'} + + + {availableVersion ? `v${availableVersion} ready` : 'New version ready'} + + {installing - ? - : } - - {installing ? 'Restarting…' : 'Restart to update'} - + ? + : ( + + )} {!installing && (