Skip to content

Commit

Permalink
feat: Visual debugger (excalidraw#8344)
Browse files Browse the repository at this point in the history
Add visual debugger to the Excalidraw app (only).
  • Loading branch information
mtolmacs authored Aug 27, 2024
1 parent 26d2296 commit ea7c702
Show file tree
Hide file tree
Showing 7 changed files with 555 additions and 21 deletions.
39 changes: 38 additions & 1 deletion excalidraw-app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ import {
import { appThemeAtom, useHandleAppTheme } from "./useHandleAppTheme";
import { getPreferredLanguage } from "./app-language/language-detector";
import { useAppLangCode } from "./app-language/language-state";
import DebugCanvas, {
debugRenderer,
isVisualDebuggerEnabled,
loadSavedDebugState,
} from "./components/DebugCanvas";
import { AIComponents } from "./components/AI";

polyfill();
Expand Down Expand Up @@ -337,6 +342,8 @@ const ExcalidrawWrapper = () => {
resolvablePromise<ExcalidrawInitialDataState | null>();
}

const debugCanvasRef = useRef<HTMLCanvasElement>(null);

useEffect(() => {
trackEvent("load", "frame", getFrame());
// Delayed so that the app has a time to load the latest SW
Expand All @@ -362,6 +369,23 @@ const ExcalidrawWrapper = () => {
migrationAdapter: LibraryLocalStorageMigrationAdapter,
});

const [, forceRefresh] = useState(false);

useEffect(() => {
if (import.meta.env.DEV) {
const debugState = loadSavedDebugState();

if (debugState.enabled && !window.visualDebug) {
window.visualDebug = {
data: [],
};
} else {
delete window.visualDebug;
}
forceRefresh((prev) => !prev);
}
}, [excalidrawAPI]);

useEffect(() => {
if (!excalidrawAPI || (!isCollabDisabled && !collabAPI)) {
return;
Expand Down Expand Up @@ -622,6 +646,11 @@ const ExcalidrawWrapper = () => {
}
});
}

// Render the debug scene if the debug canvas is available
if (debugCanvasRef.current && excalidrawAPI) {
debugRenderer(debugCanvasRef.current, appState, window.devicePixelRatio);
}
};

const [latestShareableLink, setLatestShareableLink] = useState<string | null>(
Expand Down Expand Up @@ -820,6 +849,7 @@ const ExcalidrawWrapper = () => {
isCollabEnabled={!isCollabDisabled}
theme={appTheme}
setTheme={(theme) => setAppTheme(theme)}
refresh={() => forceRefresh((prev) => !prev)}
/>
<AppWelcomeScreen
onCollabDialogOpen={onCollabDialogOpen}
Expand All @@ -845,7 +875,7 @@ const ExcalidrawWrapper = () => {
</OverwriteConfirmDialog.Action>
)}
</OverwriteConfirmDialog>
<AppFooter />
<AppFooter onChange={() => excalidrawAPI?.refresh()} />
{excalidrawAPI && <AIComponents excalidrawAPI={excalidrawAPI} />}

<TTDDialogTrigger />
Expand Down Expand Up @@ -1077,6 +1107,13 @@ const ExcalidrawWrapper = () => {
},
]}
/>
{isVisualDebuggerEnabled() && excalidrawAPI && (
<DebugCanvas
appState={excalidrawAPI.getAppState()}
scale={window.devicePixelRatio}
ref={debugCanvasRef}
/>
)}
</Excalidraw>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions excalidraw-app/app_constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const STORAGE_KEYS = {
LOCAL_STORAGE_APP_STATE: "excalidraw-state",
LOCAL_STORAGE_COLLAB: "excalidraw-collab",
LOCAL_STORAGE_THEME: "excalidraw-theme",
LOCAL_STORAGE_DEBUG: "excalidraw-debug",
VERSION_DATA_STATE: "version-dataState",
VERSION_FILES: "version-files",

Expand Down
42 changes: 23 additions & 19 deletions excalidraw-app/components/AppFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@ import { Footer } from "../../packages/excalidraw/index";
import { EncryptedIcon } from "./EncryptedIcon";
import { ExcalidrawPlusAppLink } from "./ExcalidrawPlusAppLink";
import { isExcalidrawPlusSignedUser } from "../app_constants";
import { DebugFooter, isVisualDebuggerEnabled } from "./DebugCanvas";

export const AppFooter = React.memo(() => {
return (
<Footer>
<div
style={{
display: "flex",
gap: ".5rem",
alignItems: "center",
}}
>
{isExcalidrawPlusSignedUser ? (
<ExcalidrawPlusAppLink />
) : (
<EncryptedIcon />
)}
</div>
</Footer>
);
});
export const AppFooter = React.memo(
({ onChange }: { onChange: () => void }) => {
return (
<Footer>
<div
style={{
display: "flex",
gap: ".5rem",
alignItems: "center",
}}
>
{isVisualDebuggerEnabled() && <DebugFooter onChange={onChange} />}
{isExcalidrawPlusSignedUser ? (
<ExcalidrawPlusAppLink />
) : (
<EncryptedIcon />
)}
</div>
</Footer>
);
},
);
20 changes: 20 additions & 0 deletions excalidraw-app/components/AppMainMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import React from "react";
import {
loginIcon,
ExcalLogo,
eyeIcon,
} from "../../packages/excalidraw/components/icons";
import type { Theme } from "../../packages/excalidraw/element/types";
import { MainMenu } from "../../packages/excalidraw/index";
import { isExcalidrawPlusSignedUser } from "../app_constants";
import { LanguageList } from "../app-language/LanguageList";
import { saveDebugState } from "./DebugCanvas";

export const AppMainMenu: React.FC<{
onCollabDialogOpen: () => any;
isCollaborating: boolean;
isCollabEnabled: boolean;
theme: Theme | "system";
setTheme: (theme: Theme | "system") => void;
refresh: () => void;
}> = React.memo((props) => {
return (
<MainMenu>
Expand Down Expand Up @@ -50,6 +53,23 @@ export const AppMainMenu: React.FC<{
>
{isExcalidrawPlusSignedUser ? "Sign in" : "Sign up"}
</MainMenu.ItemLink>
{import.meta.env.DEV && (
<MainMenu.Item
icon={eyeIcon}
onClick={() => {
if (window.visualDebug) {
delete window.visualDebug;
saveDebugState({ enabled: false });
} else {
window.visualDebug = { data: [] };
saveDebugState({ enabled: true });
}
props?.refresh();
}}
>
Visual Debug
</MainMenu.Item>
)}
<MainMenu.Separator />
<MainMenu.DefaultItems.ToggleTheme
allowSystemTheme
Expand Down
Loading

0 comments on commit ea7c702

Please sign in to comment.