fileHandle refactor & fixes (#2252)

This commit is contained in:
David Luzar 2020-10-19 10:53:37 +02:00 committed by GitHub
parent 4a26845395
commit 1484c5a63b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 163 additions and 41 deletions

6
package-lock.json generated
View File

@ -4686,9 +4686,9 @@
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
},
"browser-nativefs": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/browser-nativefs/-/browser-nativefs-0.10.3.tgz",
"integrity": "sha512-WGcoR1aR+bxLlilaJ9fIzVOgSC4MaV+6phCTDGXV1sm+RElFuQFnJXR4BebBf2wEnjCsmGmTDNDTBE5KvVm2UQ=="
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/browser-nativefs/-/browser-nativefs-0.11.0.tgz",
"integrity": "sha512-JsCiw8DeZ5gB59i81e0O0pFSDK124hRoaYR7teNnuvIFVZRXa7vYJStwZxZAJS1tlmVdu5uuC6eIARskyG/IuQ=="
},
"browser-process-hrtime": {
"version": "1.0.0",

View File

@ -28,7 +28,7 @@
"@types/react": "16.9.52",
"@types/react-dom": "16.9.8",
"@types/socket.io-client": "1.4.34",
"browser-nativefs": "0.10.3",
"browser-nativefs": "0.11.0",
"firebase": "7.23.0",
"i18next-browser-languagedetector": "6.0.1",
"lodash.throttle": "4.1.1",

View File

@ -59,8 +59,6 @@ export const actionClearCanvas = register({
showAriaLabel={useIsMobile()}
onClick={() => {
if (window.confirm(t("alerts.clearReset"))) {
// TODO: Make this part of `AppState`.
(window as any).handle = null;
updateData(null);
}
}}

View File

@ -85,12 +85,16 @@ export const actionChangeShouldAddWatermark = register({
export const actionSaveScene = register({
name: "saveScene",
perform: (elements, appState, value) => {
// TODO: Make this part of `AppState`.
saveAsJSON(elements, appState, (window as any).handle)
.catch(muteFSAbortError)
.catch((error) => console.error(error));
return { commitToHistory: false };
perform: async (elements, appState, value) => {
try {
const { fileHandle } = await saveAsJSON(elements, appState);
return { commitToHistory: false, appState: { ...appState, fileHandle } };
} catch (error) {
if (error?.name !== "AbortError") {
console.error(error);
}
return { commitToHistory: false };
}
},
keyTest: (event) => {
return event.key === "s" && event[KEYS.CTRL_OR_CMD] && !event.shiftKey;
@ -109,11 +113,19 @@ export const actionSaveScene = register({
export const actionSaveAsScene = register({
name: "saveAsScene",
perform: (elements, appState, value) => {
saveAsJSON(elements, appState, null)
.catch(muteFSAbortError)
.catch((error) => console.error(error));
return { commitToHistory: false };
perform: async (elements, appState, value) => {
try {
const { fileHandle } = await saveAsJSON(elements, {
...appState,
fileHandle: null,
});
return { commitToHistory: false, appState: { ...appState, fileHandle } };
} catch (error) {
if (error?.name !== "AbortError") {
console.error(error);
}
return { commitToHistory: false };
}
},
keyTest: (event) => {
return event.key === "s" && event.shiftKey && event[KEYS.CTRL_OR_CMD];

View File

@ -5,6 +5,7 @@ import {
UpdaterFn,
ActionFilterFn,
ActionName,
ActionResult,
} from "./types";
import { ExcalidrawElement } from "../element/types";
import { AppState } from "../types";
@ -13,7 +14,7 @@ import { t } from "../i18n";
export class ActionManager implements ActionsManagerInterface {
actions = {} as ActionsManagerInterface["actions"];
updater: UpdaterFn;
updater: (actionResult: ActionResult | Promise<ActionResult>) => void;
getAppState: () => Readonly<AppState>;
@ -24,7 +25,15 @@ export class ActionManager implements ActionsManagerInterface {
getAppState: () => AppState,
getElementsIncludingDeleted: () => readonly ExcalidrawElement[],
) {
this.updater = updater;
this.updater = (actionResult) => {
if (actionResult && "then" in actionResult) {
actionResult.then((actionResult) => {
return updater(actionResult);
});
} else {
return updater(actionResult);
}
};
this.getAppState = getAppState;
this.getElementsIncludingDeleted = getElementsIncludingDeleted;
}

View File

@ -16,9 +16,9 @@ type ActionFn = (
elements: readonly ExcalidrawElement[],
appState: Readonly<AppState>,
formData: any,
) => ActionResult;
) => ActionResult | Promise<ActionResult>;
export type UpdaterFn = (res: ActionResult, commitToHistory?: boolean) => void;
export type UpdaterFn = (res: ActionResult) => void;
export type ActionFilterFn = (action: Action) => void;
export type ActionName =

View File

@ -69,6 +69,7 @@ export const getDefaultAppState = (): Omit<
width: window.innerWidth,
height: window.innerHeight,
isLibraryOpen: false,
fileHandle: null,
};
};
@ -145,6 +146,7 @@ const APP_STATE_STORAGE_CONF = (<
zoom: { browser: true, export: false },
offsetTop: { browser: false, export: false },
offsetLeft: { browser: false, export: false },
fileHandle: { browser: false, export: false },
});
const _clearAppStateForStorage = <ExportType extends "export" | "browser">(

View File

@ -160,7 +160,7 @@ export const parseClipboard = async (
export const copyCanvasToClipboardAsPng = async (canvas: HTMLCanvasElement) =>
new Promise((resolve, reject) => {
try {
canvas.toBlob(async (blob: any) => {
canvas.toBlob(async (blob) => {
try {
await navigator.clipboard.write([
new window.ClipboardItem({ "image/png": blob }),

View File

@ -558,7 +558,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
return;
}
const fileHandle = launchParams.files[0];
const blob = await fileHandle.getFile();
const blob: Blob = await fileHandle.getFile();
blob.handle = fileHandle;
loadFromBlob(blob, this.state)
.then(({ elements, appState }) =>
@ -3845,7 +3845,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
// but can be safely ignored on older releases.
const item = event.dataTransfer.items[0];
// TODO: Make this part of `AppState`.
(window as any).handle = await (item as any).getAsFileSystemHandle();
(file as any).handle = await (item as any).getAsFileSystemHandle();
} catch (error) {
console.warn(error.name, error.message);
}

View File

@ -4,6 +4,7 @@ import { t } from "../i18n";
import { AppState } from "../types";
import { LibraryData, ImportedDataState } from "./types";
import { calculateScrollCenter } from "../scene";
import { MIME_TYPES } from "../constants";
export const parseFileContents = async (blob: Blob | File) => {
let contents: string;
@ -53,16 +54,22 @@ export const parseFileContents = async (blob: Blob | File) => {
return contents;
};
const getMimeType = (blob: Blob): string => {
if (blob.type) {
return blob.type;
}
const name = blob.name || "";
if (/\.(excalidraw|json)$/.test(name)) {
return "application/json";
}
return "";
};
export const loadFromBlob = async (
blob: any,
blob: Blob,
/** @see restore.localAppState */
localAppState: AppState | null,
) => {
if (blob.handle) {
// TODO: Make this part of `AppState`.
(window as any).handle = blob.handle;
}
const contents = await parseFileContents(blob);
try {
const data: ImportedDataState = JSON.parse(contents);
@ -74,6 +81,13 @@ export const loadFromBlob = async (
elements: data.elements,
appState: {
appearance: localAppState?.appearance,
fileHandle:
blob.handle &&
["application/json", MIME_TYPES.excalidraw].includes(
getMimeType(blob),
)
? blob.handle
: null,
...cleanAppStateForExport(data.appState || {}),
...(localAppState
? calculateScrollCenter(data.elements || [], localAppState, null)

View File

@ -66,9 +66,6 @@ export type SocketUpdateDataIncoming =
type: "INVALID_RESPONSE";
};
// TODO: Make this part of `AppState`.
(window as any).handle = null;
const byteToHex = (byte: number): string => `0${byte.toString(16)}`.slice(-2);
const generateRandomID = async () => {

View File

@ -27,23 +27,23 @@ export const serializeAsJSON = (
export const saveAsJSON = async (
elements: readonly ExcalidrawElement[],
appState: AppState,
fileHandle: any,
) => {
const serialized = serializeAsJSON(elements, appState);
const blob = new Blob([serialized], {
type: "application/json",
});
const name = `${appState.name}.excalidraw`;
// TODO: Make this part of `AppState`.
(window as any).handle = await fileSave(
const fileHandle = await fileSave(
blob,
{
fileName: name,
fileName: appState.name,
description: "Excalidraw file",
extensions: [".excalidraw"],
},
fileHandle || null,
appState.fileHandle,
);
return { fileHandle };
};
export const loadFromJSON = async (localAppState: AppState) => {

View File

@ -4,7 +4,7 @@ import { loadLibrary, saveLibrary } from "./localStorage";
export class Library {
/** imports library (currently merges, removing duplicates) */
static async importLibrary(blob: any) {
static async importLibrary(blob: Blob) {
const libraryFile = await loadLibraryFromBlob(blob);
if (!libraryFile || !libraryFile.library) {
return;

7
src/global.d.ts vendored
View File

@ -76,3 +76,10 @@ type CallableType<T extends (...args: any[]) => any> = (
type ForwardRef<T, P = any> = Parameters<
CallableType<React.ForwardRefRenderFunction<T, P>>
>[1];
// --------------------------------------------------------------------------—
interface Blob {
handle?: import("browser-nativefs").FileSystemHandle;
name?: string;
}

View File

@ -1 +0,0 @@
declare module "browser-nativefs";

View File

@ -28,6 +28,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -475,6 +476,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -928,6 +930,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": false,
@ -1690,6 +1693,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -1880,6 +1884,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -2324,6 +2329,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -2563,6 +2569,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -2713,6 +2720,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -3176,6 +3184,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -3470,6 +3479,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -3660,6 +3670,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -3890,6 +3901,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -4128,6 +4140,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -4497,6 +4510,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -4778,6 +4792,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -5071,6 +5086,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -5265,6 +5281,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -5415,6 +5432,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -5854,6 +5872,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -6158,6 +6177,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -8124,6 +8144,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -8472,6 +8493,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -8713,6 +8735,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -8952,6 +8975,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -9253,6 +9277,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -9403,6 +9428,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -9553,6 +9579,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -9703,6 +9730,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -9879,6 +9907,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -10055,6 +10084,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -10231,6 +10261,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -10407,6 +10438,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -10557,6 +10589,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -10707,6 +10740,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -10883,6 +10917,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -11033,6 +11068,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -11209,6 +11245,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -11911,6 +11948,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -12150,6 +12188,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -12238,6 +12277,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -12324,6 +12364,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -13202,6 +13243,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -13639,6 +13681,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -13989,6 +14032,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -14256,6 +14300,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -14444,6 +14489,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -15269,6 +15315,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -15991,6 +16038,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -16614,6 +16662,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -17142,6 +17191,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -17624,6 +17674,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -18017,6 +18068,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -18325,6 +18377,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -18552,6 +18605,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -19430,6 +19484,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -20203,6 +20258,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -20875,6 +20931,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -21450,6 +21507,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -21600,6 +21658,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -21894,6 +21953,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -22188,6 +22248,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -22338,6 +22399,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -22520,6 +22582,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -22755,6 +22818,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -23065,6 +23129,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -23890,6 +23955,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -24184,6 +24250,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -24478,6 +24545,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -24843,6 +24911,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -24996,6 +25065,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -25303,6 +25373,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -25544,6 +25615,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -25857,6 +25929,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -25943,6 +26016,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -26093,6 +26167,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -26900,6 +26975,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -26986,6 +27062,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -27724,6 +27801,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -28115,6 +28193,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -28374,6 +28453,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -28462,6 +28542,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -28940,6 +29021,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,
@ -29026,6 +29108,7 @@ Object {
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"fileHandle": null,
"gridSize": null,
"height": 768,
"isBindingEnabled": true,

View File

@ -96,6 +96,7 @@ export type AppState = {
offsetLeft: number;
isLibraryOpen: boolean;
fileHandle: import("browser-nativefs").FileSystemHandle | null;
};
export type PointerCoords = Readonly<{