/ 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  }