import { ChevronLeft, ChevronRight, RotateCcw } from "lucide-react" import { useEffect, useMemo, useState } from "react" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { useDiagram } from "@/contexts/diagram-context" import { useDictionary } from "@/hooks/use-dictionary" import { diffDiagrams, isSameDocument } from "@/lib/diagram-diff" import { formatMessage } from "@/lib/i18n/utils" import { describeChanges } from "@/lib/version-text" import { useUiStore } from "@/stores/ui-store" import { useVersionsStore } from "@/stores/versions-store" import { useChatEngine } from "./chat-engine" import { VersionThumb } from "./tool-activity" function Sheet({ label, svg, }: { label: string svg: string | null | undefined }) { return (
{label}
) } /** A saved version next to the current canvas, with restore */ export function CompareDialog() { const dict = useDictionary() const t = dict.versions const engine = useChatEngine() const { getVersionSvg, chartXML } = useDiagram() const versionId = useUiStore((s) => s.compareVersionId) const openCompare = useUiStore((s) => s.openCompare) const closeCompare = useUiStore((s) => s.closeCompare) const versions = useVersionsStore((s) => s.versions) const [currentSvg, setCurrentSvg] = useState(null) const index = versions.findIndex((v) => v.id === versionId) const version = index >= 0 ? versions[index] : null // Whether the canvas is this version, on every page const same = useMemo( () => !version || isSameDocument(version.xml, chartXML), [version, chartXML], ) // What the canvas has changed since this version on the first page // (null: nothing there) const changes = useMemo(() => { if (!version || same) return null const { summary } = diffDiagrams(version.xml, chartXML) return Object.values(summary).some((n) => n > 0) ? summary : null }, [version, chartXML, same]) // The version went away (dropped as the oldest, another chat): the // dialog closes, and nothing waits for its Escape useEffect(() => { if (versionId && !version) closeCompare() }, [versionId, version, closeCompare]) // Picture of the canvas as it is now, taken again once an answer that // was running is done ("" when none could be made) useEffect(() => { if (!versionId) return let cancelled = false setCurrentSvg(null) getVersionSvg().then((svg) => { if (!cancelled) setCurrentSvg(svg ?? "") }) return () => { cancelled = true } }, [versionId, engine.isBusy]) return ( !open && closeCompare()} > {t.compareTitle} {!version ? "" : same ? t.isOnCanvas : changes ? `${formatMessage(t.compareSince, { n: version.number })} ${describeChanges(changes, t)}` : formatMessage(t.differsElsewhere, { n: version.number, })} {version && (
)}
{index + 1} / {versions.length}
) }