"use client"; import { useEffect, useState } from "react"; import { useDesktopPreferences } from "@/hooks/useDesktopPreferences"; import { UPDATE_REMINDER_SNOOZE_MS, readUpdateReminderSnooze, updateReminderSnoozeRemaining, writeUpdateReminderSnooze, type UpdateReminderSnooze, } from "@/lib/desktop/update-reminder"; import { applySystemUpdateRequest } from "@/modules/settings/hooks/backend/api"; import { persistPowerActionState } from "@/modules/settings/hooks/useUpdateRecoveryState"; import { useSystemUpdateStatus } from "@/modules/system/hooks/useSystemUpdateStatus"; function browserStorage(): Storage | null { try { return window.localStorage; } catch { return null; } } /** * Drives the update bar above the dock: it shows while an update is available, * "Later" hides it for an hour per version, and it respects the existing * "Update notifications" preference. */ export function useUpdateReminder({ enabled }: { enabled: boolean }) { const { data: status } = useSystemUpdateStatus(); const { notificationPreferences, isHydrated } = useDesktopPreferences(); const [snooze, setSnooze] = useState(null); const [isSnoozeLoaded, setIsSnoozeLoaded] = useState(false); const [now, setNow] = useState(() => Date.now()); const [isApplying, setIsApplying] = useState(false); const [error, setError] = useState(null); useEffect(() => { const storage = browserStorage(); setSnooze(storage ? readUpdateReminderSnooze(storage) : null); setIsSnoozeLoaded(true); }, []); const latestVersion = status?.updateAvailable ? status.latestVersion : null; const snoozeRemaining = latestVersion ? updateReminderSnoozeRemaining(snooze, latestVersion, now) : 0; // Wake up when the snooze runs out, so the reminder comes back without a reload. useEffect(() => { if (snoozeRemaining <= 0) return; const timer = window.setTimeout(() => setNow(Date.now()), snoozeRemaining); return () => window.clearTimeout(timer); }, [snoozeRemaining]); const visible = enabled && isHydrated && isSnoozeLoaded && notificationPreferences.updateNotificationsEnabled && latestVersion !== null && snoozeRemaining === 0; function later() { if (!latestVersion) return; const timestamp = Date.now(); const storage = browserStorage(); setSnooze( storage ? writeUpdateReminderSnooze(storage, latestVersion, timestamp) : { version: latestVersion, snoozedUntil: timestamp + UPDATE_REMINDER_SNOOZE_MS }, ); setNow(timestamp); setError(null); } async function update() { if (isApplying) return; setIsApplying(true); setError(null); try { await applySystemUpdateRequest(); } catch (err) { setError(err instanceof Error ? err.message : "Failed to start the update"); setIsApplying(false); return; } // Same hand-off as Settings → Updates: the /updating page follows the restart. persistPowerActionState("update", { requestDispatchedAt: new Date().toISOString(), }); window.location.replace("/updating"); } return { visible, currentVersion: status?.currentVersion ?? null, latestVersion, canSelfUpdate: status?.canSelfUpdate !== false, isApplying, error, later, update, }; }