mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 04:29:51 +08:00
The canvas components will be reused by the MCP server's browser shell, which has no chat and no Next.js. They now read everything they need from small contexts and the canvas store instead of the chat engine: - components/canvas/versions-context.tsx: VersionsProvider and useVersionsContext give the version cards, the strip and the compare dialog a VersionsSource (versions, onCanvasId, undoneId, isBusy, canUndo, canRedo, restore, undo, redo). The chat fills it from the versions store and the engine in components/chat/chat-versions.tsx. - stores/canvas-store.ts: isBusy and busyReason; the chat engine sets them while a turn runs, SelectionAsk and the version UI read them. - components/canvas/version-card.tsx: the visual version card and the thumbnail, out of tool-activity.tsx; the chat's card composes it and adds its "Show XML" link and code panel. - compare-dialog.tsx and version-strip.tsx move to components/canvas; the strip takes the minimum number of versions to show as a prop, the chat panel computes it from the cards it has. - components/canvas/locale-context.tsx: LocaleProvider and useLocale, fed by the [lang] layout; CanvasStage no longer uses next/navigation. The overlay (SelectionAsk) is a slot and the wait for the saved language is a prop, so the shell can leave both out. - lib/version-text.ts: describeChanges is now describeChangeSummary, so it can be imported next to the MCP core's describeChanges.
73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
"use client"
|
|
|
|
import { createContext, useContext } from "react"
|
|
import type { ChangeSummary } from "@/lib/diagram-diff"
|
|
|
|
/** One saved state of the diagram, as the version card and the compare
|
|
* dialog show it */
|
|
export interface VersionItem {
|
|
id: string
|
|
/** Shown as v{number} */
|
|
number: number
|
|
/** Full multi-page document */
|
|
xml: string
|
|
/** The page the change was made on; none: the first page */
|
|
pageId?: string
|
|
/** Document before the change, when it is known */
|
|
beforeXml?: string
|
|
/** SVG data URL thumbnail; undefined: still being made; "": none could
|
|
* be made */
|
|
svg?: string
|
|
summary: ChangeSummary
|
|
/** Drawn on an empty canvas (the card shows totals, not changes) */
|
|
fromScratch?: boolean
|
|
}
|
|
|
|
/**
|
|
* Where the versions come from and what can be done with them. The web app
|
|
* fills it from the chat's version store; the MCP shell from the server's
|
|
* history.
|
|
*/
|
|
export interface VersionsSource {
|
|
versions: VersionItem[]
|
|
/** The version the canvas shows now, or null (hand edits, undone) */
|
|
onCanvasId: string | null
|
|
/** The latest version, when its change was undone */
|
|
undoneId: string | null
|
|
/** Something is changing the canvas: version actions wait */
|
|
isBusy: boolean
|
|
/** The latest version's change can be undone */
|
|
canUndo: boolean
|
|
/** The latest version's change was undone and can be put back */
|
|
canRedo: boolean
|
|
restore: (id: string) => void
|
|
undo: () => void
|
|
redo: () => void
|
|
}
|
|
|
|
const VersionsContext = createContext<VersionsSource | null>(null)
|
|
|
|
export function VersionsProvider({
|
|
value,
|
|
children,
|
|
}: {
|
|
value: VersionsSource
|
|
children: React.ReactNode
|
|
}) {
|
|
return (
|
|
<VersionsContext.Provider value={value}>
|
|
{children}
|
|
</VersionsContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useVersionsContext(): VersionsSource {
|
|
const source = useContext(VersionsContext)
|
|
if (!source) {
|
|
throw new Error(
|
|
"useVersionsContext must be used within a VersionsProvider",
|
|
)
|
|
}
|
|
return source
|
|
}
|