Skip to content

Commit

Permalink
support tool locking
Browse files Browse the repository at this point in the history
  • Loading branch information
dwelle committed May 18, 2023
1 parent 34ba3e4 commit b39f4a9
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 8 deletions.
7 changes: 5 additions & 2 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2468,8 +2468,11 @@ class App extends React.Component<AppProps, AppState> {

private setActiveTool = (
tool:
| { type: typeof SHAPES[number]["value"] | "eraser" | "hand" }
| { type: "custom"; customType: string },
| {
type: typeof SHAPES[number]["value"] | "eraser" | "hand";
locked?: boolean;
}
| { type: "custom"; customType: string; locked?: boolean },
) => {
const nextActiveTool = updateActiveTool(this.state, tool);
if (nextActiveTool.type === "hand") {
Expand Down
95 changes: 91 additions & 4 deletions src/excalidraw-app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import polyfill from "../polyfill";
import LanguageDetector from "i18next-browser-languagedetector";
import { useEffect, useRef, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { trackEvent } from "../analytics";
import { getDefaultAppState } from "../appState";
import { ErrorDialog } from "../components/ErrorDialog";
Expand All @@ -21,7 +21,13 @@ import {
} from "../element/types";
import { useCallbackRefState } from "../hooks/useCallbackRefState";
import { t } from "../i18n";
import { Excalidraw, defaultLang } from "../packages/excalidraw/index";
import {
Excalidraw,
defaultLang,
Footer,
Button,
Sidebar,
} from "../packages/excalidraw/index";
import {
AppState,
LibraryItems,
Expand Down Expand Up @@ -76,7 +82,6 @@ import { reconcileElements } from "./collab/reconciliation";
import { parseLibraryTokensFromUrl, useHandleLibrary } from "../data/library";
import { AppMainMenu } from "./components/AppMainMenu";
import { AppWelcomeScreen } from "./components/AppWelcomeScreen";
import { AppFooter } from "./components/AppFooter";
import { atom, Provider, useAtom, useAtomValue } from "jotai";
import { useAtomWithInitialValue } from "../jotai";
import { appJotaiStore } from "./app-jotai";
Expand Down Expand Up @@ -600,6 +605,70 @@ const ExcalidrawWrapper = () => {

const isOffline = useAtomValue(isOfflineAtom);

const [activeToolType, setActiveToolType] = useState<string | null>(null);
const prevActiveTool = useRef<{
type: string;
locked?: boolean;
prevLockState?: boolean;
}>();

const toggleCommentTool = useCallback(() => {
const nextType =
excalidrawAPI?.getAppState().activeTool?.customType === "comment"
? "selection"
: "comment";
excalidrawAPI?.setActiveTool(
nextType === "comment"
? {
type: "custom",
customType: "comment",
locked: true,
}
: { type: "selection" },
);
}, [excalidrawAPI]);

useEffect(() => {
if (excalidrawAPI) {
const unsubOnChange = excalidrawAPI.onChange((_, appState) => {
const type = appState.activeTool.customType || appState.activeTool.type;
if (
prevActiveTool.current?.type === "comment" &&
type !== "comment" &&
!prevActiveTool.current?.prevLockState
) {
excalidrawAPI.setActiveTool({
...appState.activeTool,
locked: false,
});
}
setActiveToolType(type);
prevActiveTool.current = {
type,
locked: appState.activeTool.locked,
prevLockState:
prevActiveTool.current?.type !== "comment"
? prevActiveTool.current?.locked
: prevActiveTool.current?.prevLockState,
};
});

// on C keypress
const onKeyDown = (event: KeyboardEvent) => {
if (event.code === "KeyC") {
toggleCommentTool();
}
};

window.addEventListener("keydown", onKeyDown);

return () => {
window.removeEventListener("keydown", onKeyDown);
unsubOnChange();
};
}
}, [excalidrawAPI, toggleCommentTool]);

return (
<div
style={{ height: "100%" }}
Expand Down Expand Up @@ -651,7 +720,25 @@ const ExcalidrawWrapper = () => {
isCollaborating={isCollaborating}
/>
<AppWelcomeScreen setCollabDialogShown={setCollabDialogShown} />
<AppFooter />
<Sidebar name="custom">test</Sidebar>
<Footer>
<div
style={{
display: "flex",
gap: ".5rem",
alignItems: "center",
marginRight: "auto",
}}
>
<Sidebar.Trigger name="custom">sidebar</Sidebar.Trigger>
<Button
onSelect={toggleCommentTool}
className={clsx({ active: activeToolType === "comment" })}
>
💬
</Button>
</div>
</Footer>
{isCollaborating && isOffline && (
<div className="collab-offline-warning">
{t("alerts.collabOfflineWarning")}
Expand Down
9 changes: 7 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,15 +292,19 @@ export const distance = (x: number, y: number) => Math.abs(x - y);
export const updateActiveTool = (
appState: Pick<AppState, "activeTool">,
data: (
| { type: typeof SHAPES[number]["value"] | "eraser" | "hand" }
| { type: "custom"; customType: string }
| {
type: typeof SHAPES[number]["value"] | "eraser" | "hand";
locked?: boolean;
}
| { type: "custom"; customType: string; locked?: boolean }
) & { lastActiveToolBeforeEraser?: LastActiveTool },
): AppState["activeTool"] => {
if (data.type === "custom") {
return {
...appState.activeTool,
type: "custom",
customType: data.customType,
locked: data.locked ?? appState.activeTool.locked,
};
}

Expand All @@ -312,6 +316,7 @@ export const updateActiveTool = (
: data.lastActiveToolBeforeEraser,
type: data.type,
customType: null,
locked: data.locked ?? appState.activeTool.locked,
};
};

Expand Down

0 comments on commit b39f4a9

Please sign in to comment.