/ components / UpdateBanner.tsx
UpdateBanner.tsx
1 import { useState, useEffect } from 'react'; 2 import { ArrowUpCircle, X, Download } from 'lucide-react'; 3 import type { UpdateInfo } from '../lib/types'; 4 5 const supportsAutoUpdate = window.electronAPI.platform !== 'linux' && window.electronAPI.isPackaged; 6 7 export function UpdateBanner() { 8 const [update, setUpdate] = useState<UpdateInfo | null>(null); 9 const [readyVersion, setReadyVersion] = useState<string | null>(null); 10 11 useEffect(() => { 12 window.electronAPI.onUpdateAvailable((info) => setUpdate(info)); 13 window.electronAPI.onUpdateReady((version) => setReadyVersion(version)); 14 return () => { 15 window.electronAPI.offUpdateAvailable(); 16 window.electronAPI.offUpdateReady(); 17 }; 18 }, []); 19 20 // macOS/Windows: show banner when update has been downloaded and is ready to install 21 if (supportsAutoUpdate && readyVersion !== null) { 22 return ( 23 <div className="flex items-center justify-between gap-3 px-4 py-2 text-sm updateBanner"> 24 <div className="flex items-center gap-2"> 25 <ArrowUpCircle className="h-4 w-4 shrink-0" /> 26 <span> 27 Gnosis 28 {readyVersion ? ( 29 <> 30 {' '} 31 <strong>v{readyVersion}</strong> 32 </> 33 ) : ( 34 '' 35 )}{' '} 36 will install on next restart 37 </span> 38 </div> 39 <button onClick={() => setReadyVersion(null)} className="shrink-0 transition-opacity hover:opacity-80"> 40 <X className="h-3.5 w-3.5" /> 41 </button> 42 </div> 43 ); 44 } 45 46 // Linux: show banner when a new version is available for manual download 47 if (!update || supportsAutoUpdate) return null; 48 49 const { version, releaseUrl } = update; 50 51 function handleDismiss() { 52 void window.electronAPI.dismissUpdate(version); 53 setUpdate(null); 54 } 55 56 return ( 57 <div className="flex items-center justify-between gap-3 px-4 py-2 text-sm updateBanner"> 58 <div className="flex items-center gap-2"> 59 <ArrowUpCircle className="h-4 w-4 shrink-0" /> 60 <span> 61 Gnosis <strong>v{version}</strong> is available 62 </span> 63 <button 64 onClick={() => void window.electronAPI.openExternal(releaseUrl)} 65 className="ml-1 inline-flex items-center gap-1.5 rounded-md px-2.5 py-0.5 text-xs font-medium transition-colors updateBanner-btn" 66 > 67 <Download className="h-3 w-3" /> 68 Download 69 </button> 70 </div> 71 <button onClick={handleDismiss} className="shrink-0 transition-opacity hover:opacity-80"> 72 <X className="h-3.5 w-3.5" /> 73 </button> 74 </div> 75 ); 76 }