feat(updater): self-update via GitHub Releases with launch check and settings UI
Phase 3 of the 0.1.0 release prep: - tauri-plugin-updater + tauri-plugin-process wired into the builder, with updater:default / process:allow-restart capabilities - bundle.createUpdaterArtifacts: true; endpoint points at the GitHub releases latest.json, pubkey baked into tauri.conf.json - store: update status state machine (check / download progress / install) with a quiet launch check (prod only) that stays silent on network errors - UI: dismissible update toast with download progress, plus an Updates group in Settings > General showing current version and manual check/install
This commit is contained in:
@@ -178,6 +178,12 @@ export function SettingsModal() {
|
||||
const vacuumDatabase = useGalleryStore((state) => state.vacuumDatabase);
|
||||
const getOrphanedThumbnailsInfo = useGalleryStore((state) => state.getOrphanedThumbnailsInfo);
|
||||
const cleanupOrphanedThumbnails = useGalleryStore((state) => state.cleanupOrphanedThumbnails);
|
||||
const appVersion = useGalleryStore((state) => state.appVersion);
|
||||
const updateStatus = useGalleryStore((state) => state.updateStatus);
|
||||
const updateVersion = useGalleryStore((state) => state.updateVersion);
|
||||
const updateError = useGalleryStore((state) => state.updateError);
|
||||
const checkForUpdates = useGalleryStore((state) => state.checkForUpdates);
|
||||
const installUpdate = useGalleryStore((state) => state.installUpdate);
|
||||
|
||||
useEffect(() => {
|
||||
if (!settingsOpen) return;
|
||||
@@ -578,6 +584,47 @@ export function SettingsModal() {
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-8 space-y-9">
|
||||
<SettingsGroup title="Updates">
|
||||
<SettingsItem
|
||||
label={
|
||||
<span className="inline-flex items-center gap-2.5">
|
||||
<span>Phokus {appVersion ? `v${appVersion}` : "—"}</span>
|
||||
{updateStatus === "available" || updateStatus === "downloading" || updateStatus === "installing" ? (
|
||||
<StatusPill tone="busy">v{updateVersion} available</StatusPill>
|
||||
) : updateStatus === "upToDate" ? (
|
||||
<StatusPill tone="ready">Up to date</StatusPill>
|
||||
) : null}
|
||||
</span>
|
||||
}
|
||||
description={
|
||||
updateStatus === "error" ? (
|
||||
<span className="text-amber-300/90">Update check failed: {updateError}</span>
|
||||
) : updateStatus === "downloading" || updateStatus === "installing" ? (
|
||||
"Downloading update — the app will restart when it finishes."
|
||||
) : (
|
||||
"Updates are checked quietly at launch and installed only when you choose."
|
||||
)
|
||||
}
|
||||
>
|
||||
{updateStatus === "available" ? (
|
||||
<button
|
||||
className="rounded-md border border-emerald-400/35 bg-emerald-500/15 px-3 py-1.5 text-xs text-emerald-200 transition-colors hover:bg-emerald-500/25"
|
||||
onClick={() => void installUpdate()}
|
||||
>
|
||||
Install & restart
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
className="rounded-md border border-white/10 bg-white/[0.055] px-3 py-1.5 text-xs text-gray-300 transition-colors hover:bg-white/10 hover:text-white disabled:cursor-not-allowed disabled:opacity-45"
|
||||
onClick={() => void checkForUpdates()}
|
||||
disabled={updateStatus === "checking" || updateStatus === "downloading" || updateStatus === "installing"}
|
||||
>
|
||||
{updateStatus === "checking" ? "Checking..." : "Check for updates"}
|
||||
</button>
|
||||
)}
|
||||
</SettingsItem>
|
||||
</SettingsGroup>
|
||||
|
||||
<SettingsGroup title="Storage & notifications">
|
||||
<SettingsItem
|
||||
label="App data folder"
|
||||
|
||||
Reference in New Issue
Block a user