Skip to content

Commit c080f44

Browse files
committed
refactor & make safer
1 parent afaf86e commit c080f44

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+143
-125
lines changed

.eslintrc.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33
"rules": {
44
"import/no-anonymous-default-export": "off",
55
"no-restricted-globals": "off",
6-
"@typescript-eslint/consistent-type-imports": ["error", { "prefer": "type-imports", "disallowTypeAnnotations": false, "fixStyle": "separate-type-imports" }]
6+
"@typescript-eslint/consistent-type-imports": [
7+
"error",
8+
{
9+
"prefer": "type-imports",
10+
"disallowTypeAnnotations": false,
11+
"fixStyle": "separate-type-imports"
12+
}
13+
],
14+
"no-restricted-imports": [
15+
"error",
16+
{
17+
"name": "jotai",
18+
"message": "Do not import from \"jotai\" directly. Use our app-specific modules (\"editor-jotai\" or \"app-jotai\")."
19+
}
20+
]
721
}
822
}

excalidraw-app/App.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,13 @@ import {
9090
import { AppMainMenu } from "./components/AppMainMenu";
9191
import { AppWelcomeScreen } from "./components/AppWelcomeScreen";
9292
import { AppFooter } from "./components/AppFooter";
93-
import { Provider, useAtom, useAtomValue } from "jotai";
94-
import { useAtomWithInitialValue } from "../packages/excalidraw/jotai";
95-
import { appJotaiStore } from "./app-jotai";
93+
import {
94+
Provider,
95+
useAtom,
96+
useAtomValue,
97+
useAtomWithInitialValue,
98+
appJotaiStore,
99+
} from "./app-jotai";
96100

97101
import "./index.scss";
98102
import type { ResolutionType } from "../packages/excalidraw/utility-types";
@@ -117,7 +121,7 @@ import {
117121
share,
118122
youtubeIcon,
119123
} from "../packages/excalidraw/components/icons";
120-
import { appThemeAtom, useHandleAppTheme } from "./useHandleAppTheme";
124+
import { useHandleAppTheme } from "./useHandleAppTheme";
121125
import { getPreferredLanguage } from "./app-language/language-detector";
122126
import { useAppLangCode } from "./app-language/language-state";
123127
import DebugCanvas, {
@@ -328,8 +332,7 @@ const ExcalidrawWrapper = () => {
328332
const [errorMessage, setErrorMessage] = useState("");
329333
const isCollabDisabled = isRunningInIframe();
330334

331-
const [appTheme, setAppTheme] = useAtom(appThemeAtom);
332-
const { editorTheme } = useHandleAppTheme();
335+
const { editorTheme, appTheme, setAppTheme } = useHandleAppTheme();
333336

334337
const [langCode, setLangCode] = useAppLangCode();
335338

excalidraw-app/app-jotai.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1-
import { createStore } from "jotai";
1+
// eslint-disable-next-line no-restricted-imports
2+
import {
3+
atom,
4+
Provider,
5+
useAtom,
6+
useAtomValue,
7+
useSetAtom,
8+
createStore,
9+
type PrimitiveAtom,
10+
} from "jotai";
11+
import { useLayoutEffect } from "react";
212

313
export const appJotaiStore = createStore();
14+
15+
export { atom, Provider, useAtom, useAtomValue, useSetAtom };
16+
17+
export const useAtomWithInitialValue = <
18+
T extends unknown,
19+
A extends PrimitiveAtom<T>,
20+
>(
21+
atom: A,
22+
initialValue: T | (() => T),
23+
) => {
24+
const [value, setValue] = useAtom(atom);
25+
26+
useLayoutEffect(() => {
27+
if (typeof initialValue === "function") {
28+
// @ts-ignore
29+
setValue(initialValue());
30+
} else {
31+
setValue(initialValue);
32+
}
33+
// eslint-disable-next-line react-hooks/exhaustive-deps
34+
}, []);
35+
36+
return [value, setValue] as const;
37+
};

excalidraw-app/app-language/LanguageList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { useSetAtom } from "jotai";
21
import React from "react";
32
import { useI18n, languages } from "../../packages/excalidraw/i18n";
3+
import { useSetAtom } from "../app-jotai";
44
import { appLangCodeAtom } from "./language-state";
55

66
export const LanguageList = ({ style }: { style?: React.CSSProperties }) => {

excalidraw-app/app-language/language-state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { atom, useAtom } from "jotai";
21
import { useEffect } from "react";
2+
import { atom, useAtom } from "../app-jotai";
33
import { getPreferredLanguage, languageDetector } from "./language-detector";
44

55
export const appLangCodeAtom = atom(getPreferredLanguage());

excalidraw-app/collab/Collab.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ import { newElementWith } from "../../packages/excalidraw/element/mutateElement"
7979
import { decryptData } from "../../packages/excalidraw/data/encryption";
8080
import { resetBrowserStateVersions } from "../data/tabSync";
8181
import { LocalData } from "../data/LocalData";
82-
import { atom } from "jotai";
83-
import { appJotaiStore } from "../app-jotai";
82+
import { appJotaiStore, atom } from "../app-jotai";
8483
import type { Mutable, ValueOf } from "../../packages/excalidraw/utility-types";
8584
import { getVisibleSceneBounds } from "../../packages/excalidraw/element/bounds";
8685
import { withBatchedUpdates } from "../../packages/excalidraw/reactUtils";

excalidraw-app/collab/CollabError.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { Tooltip } from "../../packages/excalidraw/components/Tooltip";
22
import { warning } from "../../packages/excalidraw/components/icons";
33
import clsx from "clsx";
44
import { useEffect, useRef, useState } from "react";
5+
import { atom } from "../app-jotai";
56

67
import "./CollabError.scss";
7-
import { atom } from "jotai";
88

99
type ErrorIndicator = {
1010
message: string | null;

excalidraw-app/share/ShareDialog.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import { TextField } from "../../packages/excalidraw/components/TextField";
1818
import { FilledButton } from "../../packages/excalidraw/components/FilledButton";
1919
import type { CollabAPI } from "../collab/Collab";
2020
import { activeRoomLinkAtom } from "../collab/Collab";
21-
import { atom, useAtom, useAtomValue } from "jotai";
22-
23-
import "./ShareDialog.scss";
2421
import { useUIAppState } from "../../packages/excalidraw/context/ui-appState";
2522
import { useCopyStatus } from "../../packages/excalidraw/hooks/useCopiedIndicator";
23+
import { atom, useAtom, useAtomValue } from "../app-jotai";
24+
25+
import "./ShareDialog.scss";
2626

2727
type OnExportToBackend = () => void;
2828
type ShareDialogType = "share" | "collaborationOnly";

excalidraw-app/useHandleAppTheme.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
import { atom, useAtom } from "jotai";
21
import { useEffect, useLayoutEffect, useState } from "react";
32
import { THEME } from "../packages/excalidraw";
43
import { EVENT } from "../packages/excalidraw/constants";
54
import type { Theme } from "../packages/excalidraw/element/types";
65
import { CODES, KEYS } from "../packages/excalidraw/keys";
76
import { STORAGE_KEYS } from "./app_constants";
87

9-
export const appThemeAtom = atom<Theme | "system">(
10-
(localStorage.getItem(STORAGE_KEYS.LOCAL_STORAGE_THEME) as
11-
| Theme
12-
| "system"
13-
| null) || THEME.LIGHT,
14-
);
15-
168
const getDarkThemeMediaQuery = (): MediaQueryList | undefined =>
179
window.matchMedia?.("(prefers-color-scheme: dark)");
1810

1911
export const useHandleAppTheme = () => {
20-
const [appTheme, setAppTheme] = useAtom(appThemeAtom);
12+
const [appTheme, setAppTheme] = useState<Theme | "system">(() => {
13+
return (
14+
(localStorage.getItem(STORAGE_KEYS.LOCAL_STORAGE_THEME) as
15+
| Theme
16+
| "system"
17+
| null) || THEME.LIGHT
18+
);
19+
});
2120
const [editorTheme, setEditorTheme] = useState<Theme>(THEME.LIGHT);
2221

2322
useEffect(() => {
@@ -66,5 +65,5 @@ export const useHandleAppTheme = () => {
6665
}
6766
}, [appTheme]);
6867

69-
return { editorTheme };
68+
return { editorTheme, appTheme, setAppTheme };
7069
};

packages/excalidraw/components/ActiveConfirmDialog.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { atom } from "jotai";
21
import { actionClearCanvas } from "../actions";
32
import { t } from "../i18n";
4-
import { useAtom } from "../jotai";
3+
import { atom, useAtom } from "../editor-jotai";
54
import { useExcalidrawActionManager } from "./App";
65
import ConfirmDialog from "./ConfirmDialog";
76

0 commit comments

Comments
 (0)