mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-11 20:19:51 +08:00
refactor(canvas): decouple the canvas from the chat engine
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.
This commit is contained in:
+10
-1
@@ -30,7 +30,13 @@ interface CanvasState {
|
||||
isFreehand: boolean
|
||||
/** One of draw.io's menus or dialogs is open over the canvas */
|
||||
isDrawioPopupOpen: boolean
|
||||
set: (partial: Partial<Omit<CanvasState, "set">>) => void
|
||||
/** Something is changing the canvas (an answer streams in, a sync
|
||||
* runs): version actions and "ask AI" wait */
|
||||
isBusy: boolean
|
||||
/** Who set the busy flag ("chat", "sync"); null when not busy */
|
||||
busyReason: string | null
|
||||
set: (partial: Partial<Omit<CanvasState, "set" | "setBusy">>) => void
|
||||
setBusy: (reason: string | null) => void
|
||||
}
|
||||
|
||||
export const useCanvasStore = create<CanvasState>((set) => ({
|
||||
@@ -41,5 +47,8 @@ export const useCanvasStore = create<CanvasState>((set) => ({
|
||||
selectionRect: null,
|
||||
isFreehand: false,
|
||||
isDrawioPopupOpen: false,
|
||||
isBusy: false,
|
||||
busyReason: null,
|
||||
set: (partial) => set(partial),
|
||||
setBusy: (reason) => set({ isBusy: reason !== null, busyReason: reason }),
|
||||
}))
|
||||
|
||||
@@ -1,27 +1,19 @@
|
||||
import { nanoid } from "nanoid"
|
||||
import { create } from "zustand"
|
||||
import type { ChangeSummary } from "@/lib/diagram-diff"
|
||||
import type { VersionItem } from "@/components/canvas/versions-context"
|
||||
import { EMPTY_SUMMARY } from "@/lib/diagram-diff"
|
||||
|
||||
/** One diagram state produced by an AI change, shown as a card in the chat */
|
||||
export interface DiagramVersion {
|
||||
id: string
|
||||
/** Shown as v{number}; it stays when older versions are dropped */
|
||||
number: number
|
||||
/** Full multi-page document after the change */
|
||||
xml: string
|
||||
/** The page the change was made on; older sessions have none (the first page) */
|
||||
pageId?: string
|
||||
/** Diagram before the change; kept only on the latest version */
|
||||
beforeXml?: string
|
||||
/** SVG data URL thumbnail; "" when none could be made */
|
||||
svg?: string
|
||||
/**
|
||||
* One diagram state produced by an AI change, shown as a card in the chat.
|
||||
* What the card displays is the VersionItem part; the rest ties the version
|
||||
* to its chat turn. The number stays when older versions are dropped; the
|
||||
* "before" document is kept only on the latest version; older sessions
|
||||
* have no pageId (the first page).
|
||||
*/
|
||||
export interface DiagramVersion extends VersionItem {
|
||||
/** Index of the user message that started this turn */
|
||||
turnIndex: number
|
||||
toolCallId?: string
|
||||
summary: ChangeSummary
|
||||
/** Drawn on an empty canvas (the card shows totals, not changes) */
|
||||
fromScratch?: boolean
|
||||
/** Saved with the session: this version is what the canvas shows */
|
||||
onCanvas?: boolean
|
||||
/** Saved with the session: this version's change was undone */
|
||||
|
||||
Reference in New Issue
Block a user