import { FolderIcon } from "lucide-react";import { useState } from "react"; function getServerHttpOrigin(): string { const bridgeUrl = window.desktopBridge?.getWsUrl(); const envUrl = import.meta.env.VITE_WS_URL as string | undefined; const wsUrl = bridgeUrl && bridgeUrl.length > 0 ? bridgeUrl : envUrl && envUrl.length > 0 ? envUrl : `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.hostname}:${window.location.port}`; // Parse to extract just the origin, dropping path/query (e.g. ?token=…) const httpUrl = wsUrl.replace(/^wss:/, "https:").replace(/^ws:/, "http:"); try { return new URL(httpUrl).origin; } catch { return httpUrl; }} const serverHttpOrigin = getServerHttpOrigin(); const loadedProjectFaviconSrcs = new Set<string>(); export function ProjectFavicon({ cwd, className }: { cwd: string; className?: string }) { const src = `${serverHttpOrigin}/api/project-favicon?cwd=${encodeURIComponent(cwd)}`; const [status, setStatus] = useState<"loading" | "loaded" | "error">(() => loadedProjectFaviconSrcs.has(src) ? "loaded" : "loading", ); return ( <> {status !== "loaded" ? ( <FolderIcon className={`size-3.5 shrink-0 text-muted-foreground/50 ${className ?? ""}`} /> ) : null} <img src={src} alt="" className={`size-3.5 shrink-0 rounded-sm object-contain ${status === "loaded" ? "" : "hidden"} ${className ?? ""}`} onLoad={() => { loadedProjectFaviconSrcs.add(src); setStatus("loaded"); }} onError={() => setStatus("error")} /> </> );}
import { FolderIcon } from "lucide-react";
import { useState } from "react";
function getServerHttpOrigin(): string {
const bridgeUrl = window.desktopBridge?.getWsUrl();
const envUrl = import.meta.env.VITE_WS_URL as string | undefined;
const wsUrl =
bridgeUrl && bridgeUrl.length > 0
? bridgeUrl
: envUrl && envUrl.length > 0
? envUrl
: `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.hostname}:${window.location.port}`;
// Parse to extract just the origin, dropping path/query (e.g. ?token=…)
const httpUrl = wsUrl.replace(/^wss:/, "https:").replace(/^ws:/, "http:");
try {
return new URL(httpUrl).origin;
} catch {
return httpUrl;
}
}
const serverHttpOrigin = getServerHttpOrigin();
const loadedProjectFaviconSrcs = new Set<string>();
export function ProjectFavicon({ cwd, className }: { cwd: string; className?: string }) {
const src = `${serverHttpOrigin}/api/project-favicon?cwd=${encodeURIComponent(cwd)}`;
const [status, setStatus] = useState<"loading" | "loaded" | "error">(() =>
loadedProjectFaviconSrcs.has(src) ? "loaded" : "loading",
);
return (
<>
{status !== "loaded" ? (
<FolderIcon className={`size-3.5 shrink-0 text-muted-foreground/50 ${className ?? ""}`} />
) : null}
<img
src={src}
alt=""
className={`size-3.5 shrink-0 rounded-sm object-contain ${status === "loaded" ? "" : "hidden"} ${className ?? ""}`}
onLoad={() => {
loadedProjectFaviconSrcs.add(src);
setStatus("loaded");
}}
onError={() => setStatus("error")}
/>
</>
);
}