Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions src/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ body {
height: 100%;
}

/* Inline editor mode (no fullscreen available) */
.main.inline-editor {
overflow: hidden;
}

/* Hide library button in fullscreen editor */
.main.fullscreen .default-sidebar-trigger {
display: none !important;
Expand All @@ -101,6 +106,8 @@ body {
top: 8px;
right: 8px;
z-index: 100;
display: flex;
gap: 4px;
opacity: 0;
transition: opacity 0.2s ease;
}
Expand All @@ -109,8 +116,8 @@ body {
opacity: 1;
}

/* Fullscreen button */
.fullscreen-btn {
/* Toolbar button */
.toolbar-btn {
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -129,14 +136,14 @@ body {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

.fullscreen-btn:hover {
.toolbar-btn:hover {
color: rgba(0, 0, 0, 0.7);
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}

/* Hide fullscreen button in fullscreen mode (host provides exit UI) */
.main.fullscreen .fullscreen-btn {
/* Hide toolbar button in fullscreen mode (host provides exit UI) */
.main.fullscreen .toolbar-btn {
display: none !important;
}

Expand Down
36 changes: 27 additions & 9 deletions src/mcp-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -565,13 +565,16 @@ function ExcalidrawApp() {
const [elements, setElements] = useState<any[]>([]);
const [userEdits, setUserEdits] = useState<any[] | null>(null);
const [containerHeight, setContainerHeight] = useState<number | null>(null);
const [canFullscreen, setCanFullscreen] = useState(false);
const [containerMaxHeight, setContainerMaxHeight] = useState<number | null>(null);
const [editorReady, setEditorReady] = useState(false);
const [excalidrawApi, setExcalidrawApi] = useState<any>(null);
const [editorSettled, setEditorSettled] = useState(false);
const appRef = useRef<App | null>(null);
const svgViewportRef = useRef<ViewportRect | null>(null);
const elementsRef = useRef<any[]>([]);
const checkpointIdRef = useRef<string | null>(null);
const lastInputRef = useRef<string | null>(null);

const toggleFullscreen = useCallback(async () => {
if (!appRef.current) return;
Expand Down Expand Up @@ -627,9 +630,9 @@ function ExcalidrawApp() {
}
}, [displayMode, containerHeight]);

// Mount editor when entering fullscreen
// Mount editor when entering fullscreen or when host doesn't support fullscreen
useEffect(() => {
if (displayMode !== "fullscreen") {
if (displayMode !== "fullscreen" && canFullscreen) {
setEditorReady(false);
setExcalidrawApi(null);
setEditorSettled(false);
Expand All @@ -639,10 +642,10 @@ function ExcalidrawApp() {
await document.fonts.ready;
setTimeout(() => setEditorReady(true), 200);
})();
}, [displayMode]);
}, [displayMode, canFullscreen]);

// After editor mounts: refresh text dimensions, then reveal
const mountEditor = displayMode === "fullscreen" && inputIsFinal && elements.length > 0 && editorReady;
const mountEditor = (displayMode === "fullscreen" || !canFullscreen) && inputIsFinal && elements.length > 0 && editorReady;
useEffect(() => {
if (!mountEditor || !excalidrawApi) return;
if (editorSettled) return; // already revealed, don't redo
Expand Down Expand Up @@ -681,14 +684,25 @@ function ExcalidrawApp() {
appRef.current = app;
_logFn = (msg) => { try { app.sendLog({ level: "info", logger: "FS", data: msg }); } catch {} };

// Capture initial container dimensions
const initDims = app.getHostContext()?.containerDimensions as any;
// Capture initial container dimensions and host capabilities
const initCtx = app.getHostContext() as any;
const initDims = initCtx?.containerDimensions;
if (initDims?.height) setContainerHeight(initDims.height);
if (initDims?.maxHeight) setContainerMaxHeight(initDims.maxHeight);
if (initCtx?.availableDisplayModes) {
setCanFullscreen(initCtx.availableDisplayModes.includes("fullscreen"));
}

app.onhostcontextchanged = (ctx: any) => {
if (ctx.containerDimensions?.height) {
setContainerHeight(ctx.containerDimensions.height);
}
if (ctx.containerDimensions?.maxHeight) {
setContainerMaxHeight(ctx.containerDimensions.maxHeight);
}
if (ctx.availableDisplayModes) {
setCanFullscreen(ctx.availableDisplayModes.includes("fullscreen"));
}
if (ctx.displayMode) {
fsLog(`hostContextChanged: displayMode=${ctx.displayMode}`);
// Sync edited elements when host exits fullscreen
Expand All @@ -711,13 +725,17 @@ function ExcalidrawApp() {

app.ontoolinput = async (input) => {
const args = (input as any)?.arguments || input;
const sig = JSON.stringify(args);
if (lastInputRef.current === sig) return;
lastInputRef.current = sig;
setInputIsFinal(true);
setToolInput(args);
};

app.ontoolresult = (result: any) => {
const cpId = (result.structuredContent as { checkpointId?: string })?.checkpointId;
if (cpId) {
if (cpId === checkpointIdRef.current) return;
checkpointIdRef.current = cpId;
setCheckpointId(cpId);
// Use checkpointId as localStorage key for persisting user edits
Expand All @@ -741,11 +759,11 @@ function ExcalidrawApp() {
if (!app) return <div className="loading">Connecting...</div>;

return (
<main className={`main${displayMode === "fullscreen" ? " fullscreen" : ""}`} style={displayMode === "fullscreen" && containerHeight ? { height: containerHeight } : undefined}>
{displayMode === "inline" && (
<main className={`main${displayMode === "fullscreen" ? " fullscreen" : ""}${!canFullscreen && mountEditor ? " inline-editor" : ""}`} style={displayMode === "fullscreen" && containerHeight ? { height: containerHeight } : !canFullscreen && mountEditor ? { height: containerMaxHeight ?? 500 } : undefined}>
{displayMode === "inline" && canFullscreen && (
<div className="toolbar">
<button
className="fullscreen-btn"
className="toolbar-btn"
onClick={toggleFullscreen}
title="Enter fullscreen"
>
Expand Down