import { SymbolView } from "expo-symbols"; import { useState } from "react"; import { Image, View } from "react-native"; import { useThemeColor } from "../lib/useThemeColor"; /* ─── Favicon cache (matches web pattern) ────────────────────────────── */ const loadedFaviconUrls = new Set(); /* ─── Component ──────────────────────────────────────────────────────── */ export function ProjectFavicon(props: { readonly size?: number; readonly projectTitle: string; readonly httpBaseUrl?: string | null; readonly workspaceRoot?: string | null; readonly bearerToken?: string | null; }) { const size = props.size ?? 42; const iconMuted = useThemeColor("--color-icon-subtle"); const faviconUrl = props.httpBaseUrl && props.workspaceRoot ? `${props.httpBaseUrl}/api/project-favicon?cwd=${encodeURIComponent(props.workspaceRoot)}` : null; const [status, setStatus] = useState<"loading" | "loaded" | "error">(() => faviconUrl && loadedFaviconUrls.has(faviconUrl) ? "loaded" : "loading", ); const showImage = faviconUrl && status === "loaded"; return ( {/* Folder icon fallback (matches web's FolderIcon) */} {!showImage ? ( ) : null} {/* Favicon image (hidden until loaded) */} {faviconUrl ? ( { if (faviconUrl) loadedFaviconUrls.add(faviconUrl); setStatus("loaded"); }} onError={() => setStatus("error")} /> ) : null} ); }