import type { ScopedThreadRef } from "@t3tools/contracts"; import { type ReactNode, useState } from "react"; import { useFaviconForThreadUrl } from "~/browserFaviconStore"; import { cn } from "~/lib/utils"; import { BrowserMockup } from "./BrowserMockup"; export function FaviconImage(props: { sources: ReadonlyArray; fallback: ReactNode; className?: string | undefined; }) { const sources = props.sources.filter((source): source is string => Boolean(source)); return ( ); } function FaviconImageAttempt(props: { sources: ReadonlyArray; fallback: ReactNode; className?: string | undefined; }) { const [failed, setFailed] = useState>(() => new Set()); const source = props.sources.find((candidate) => !failed.has(candidate)); if (!source) return props.fallback; return ( setFailed((current) => new Set(current).add(source))} /> ); } export function PreviewFaviconIcon(props: { threadRef: ScopedThreadRef; url: string; className?: string | undefined; }) { const source = useFaviconForThreadUrl(props.threadRef, props.url); const fallback = ; return ( ); }