import { AppTheme, useGalleryStore } from "../../store"; import { FakeProgressBar, formatBytes } from "./fakes"; const THEME_OPTIONS: { value: AppTheme; name: string; colors: { background: string; surface: string; text: string; muted: string; accent: string; }; }[] = [ { value: "phokus", name: "Phokus", colors: { background: "#030712", surface: "#111827", text: "#f9fafb", muted: "#6b7280", accent: "#10b981", }, }, { value: "conventional-dark", name: "Conventional Dark", colors: { background: "#1f1f1f", surface: "#303030", text: "#a3a3a3", muted: "#666666", accent: "#10b981", }, }, { value: "subtle-light", name: "Subtle Light", colors: { background: "#e9e7e2", surface: "#dedbd4", text: "#18202c", muted: "#817b72", accent: "#059669", }, }, ]; export function FfmpegStatusRow() { const ffmpegStatus = useGalleryStore((s) => s.ffmpegStatus); const ffmpegProgress = useGalleryStore((s) => s.ffmpegProgress); const ffmpegError = useGalleryStore((s) => s.ffmpegError); const retryFfmpegDownload = useGalleryStore((s) => s.retryFfmpegDownload); if (ffmpegStatus === "installed") { return (

Media engine ready

FFmpeg is installed — video thumbnails and metadata are available.

); } if (ffmpegStatus === "error") { return (

Media engine download failed

{ffmpegError}

You can keep going — photos work without it. Video thumbnails and metadata will start automatically once the download succeeds.

); } const fraction = ffmpegStatus === "downloading" && ffmpegProgress && ffmpegProgress.total_bytes > 0 ? ffmpegProgress.downloaded_bytes / ffmpegProgress.total_bytes : null; return (

{ffmpegStatus === "unpacking" ? "Unpacking media engine..." : "Downloading media engine (FFmpeg)..."}

{ffmpegProgress ? ( {formatBytes(ffmpegProgress.downloaded_bytes)} / {formatBytes(ffmpegProgress.total_bytes)} ) : null}

FFmpeg powers video thumbnails and metadata. It downloads once in the background — you can keep using the tour and the app while it finishes.

); } export function StepWelcome() { const theme = useGalleryStore((s) => s.theme); const setTheme = useGalleryStore((s) => s.setTheme); return (

Phokus is a local-first media library: point it at your folders and it builds a fast, searchable gallery with thumbnails, AI tags, and visual search. Everything is processed on this machine — your photos and videos never leave it.

This short tour shows what to expect. Every step is skippable, and you can re-run it any time from Settings.

Choose your look

{THEME_OPTIONS.map((option) => { const selected = option.value === theme; return ( ); })}

First-time setup

); }