import { useState, useEffect } from "preact/hooks"; import type { Trip } from "../lib/types"; import { downloadTripOffline, isOfflineReady, clearOfflineData, type DownloadProgress } from "../lib/offline"; export function OfflineButton({ trip }: { trip: Trip }) { const [ready, setReady] = useState(null); const [online, setOnline] = useState(navigator.onLine); const [downloading, setDownloading] = useState(false); const [progress, setProgress] = useState(null); const [result, setResult] = useState(null); useEffect(() => { isOfflineReady(trip.id).then(setReady); const goOnline = () => setOnline(true); const goOffline = () => setOnline(false); window.addEventListener("online", goOnline); window.addEventListener("offline", goOffline); return () => { window.removeEventListener("online", goOnline); window.removeEventListener("offline", goOffline); }; }, [trip.id]); const download = async () => { setDownloading(true); setResult(null); try { const r = await downloadTripOffline(trip, setProgress); setReady(true); setResult(`Cached ${r.tileCount} map tiles. Ready for offline.`); } catch (e: any) { setResult(`Error: ${e.message}`); } setDownloading(false); setProgress(null); }; const clear = async () => { await clearOfflineData(); setReady(false); setResult(null); }; if (ready === null) return null; return (
{downloading && progress ? (
{progress.phase === "data" ? "Saving trip data..." : progress.phase === "assets" ? `Caching page assets (${progress.done}/${progress.total})` : `Caching map tiles (${progress.done}/${progress.total})`}
) : (
{ready ? ( <> {online ? "Offline ready" : "Offline mode"} {online && } {online && } ) : online ? ( ) : null}
)} {result &&
{result}
}
); }