prompt when loading external scene before overriding local one (#1862)

This commit is contained in:
David Luzar 2020-07-08 22:55:26 +02:00 committed by GitHub
parent 1b9b824c70
commit d5e7d08586
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 15 deletions

View File

@ -121,6 +121,7 @@ import {
CANVAS_ONLY_ACTIONS,
DEFAULT_VERTICAL_ALIGN,
GRID_SIZE,
LOCAL_STORAGE_KEY_COLLAB_FORCE_FLAG,
} from "../constants";
import {
INITAL_SCENE_UPDATE_TIMEOUT,
@ -356,6 +357,39 @@ class App extends React.Component<ExcalidrawProps, AppState> {
this.onSceneUpdated();
};
private shouldForceLoadScene(
scene: ResolutionType<typeof loadScene>,
): boolean {
if (!scene.elements.length) {
return true;
}
const roomMatch = getCollaborationLinkData(window.location.href);
if (!roomMatch) {
return false;
}
const collabForceLoadFlag = localStorage.getItem(
LOCAL_STORAGE_KEY_COLLAB_FORCE_FLAG,
);
if (collabForceLoadFlag) {
try {
const {
room: previousRoom,
timestamp,
}: { room: string; timestamp: number } = JSON.parse(
collabForceLoadFlag,
);
// if loading same room as the one previously unloaded within 15sec
// force reload without prompting
if (previousRoom === roomMatch[1] && Date.now() - timestamp < 15000) {
return true;
}
} catch {}
}
return false;
}
private initializeScene = async () => {
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id");
@ -363,20 +397,28 @@ class App extends React.Component<ExcalidrawProps, AppState> {
/^#json=([0-9]+),([a-zA-Z0-9_-]+)$/,
);
const isCollaborationScene = getCollaborationLinkData(window.location.href);
let scene = await loadScene(null);
if (!isCollaborationScene) {
let scene: ResolutionType<typeof loadScene> | undefined;
// Backwards compatibility with legacy url format
if (id) {
scene = await loadScene(id);
} else if (jsonMatch) {
scene = await loadScene(jsonMatch[1], jsonMatch[2]);
let isCollaborationScene = !!getCollaborationLinkData(window.location.href);
const isExternalScene = !!(id || jsonMatch || isCollaborationScene);
if (isExternalScene) {
if (
this.shouldForceLoadScene(scene) ||
window.confirm(t("alerts.loadSceneOverridePrompt"))
) {
// Backwards compatibility with legacy url format
if (id) {
scene = await loadScene(id);
} else if (jsonMatch) {
scene = await loadScene(jsonMatch[1], jsonMatch[2]);
}
if (!isCollaborationScene) {
window.history.replaceState({}, "Excalidraw", window.location.origin);
}
} else {
scene = await loadScene(null);
}
if (scene) {
this.syncActionResult(scene);
isCollaborationScene = false;
window.history.replaceState({}, "Excalidraw", window.location.origin);
}
}
@ -384,9 +426,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
this.setState({ isLoading: false });
}
// run this last else the `isLoading` state
if (isCollaborationScene) {
this.initializeSocketClient({ showLoadingState: true });
} else if (scene) {
this.syncActionResult(scene);
}
};
@ -515,6 +558,15 @@ class App extends React.Component<ExcalidrawProps, AppState> {
}
private beforeUnload = withBatchedUpdates((event: BeforeUnloadEvent) => {
if (this.state.isCollaborating && this.portal.roomID) {
localStorage.setItem(
LOCAL_STORAGE_KEY_COLLAB_FORCE_FLAG,
JSON.stringify({
timestamp: Date.now(),
room: this.portal.roomID,
}),
);
}
if (
this.state.isCollaborating &&
globalSceneState.getElements().length > 0

View File

@ -77,3 +77,5 @@ export const DEFAULT_VERTICAL_ALIGN = "top";
export const CANVAS_ONLY_ACTIONS = ["selectAll"];
export const GRID_SIZE = 20; // TODO make it configurable?
export const LOCAL_STORAGE_KEY_COLLAB_FORCE_FLAG = "collabLinkForceLoadFlag";

View File

@ -367,7 +367,6 @@ export const loadScene = async (id: string | null, privateKey?: string) => {
// the private key is used to decrypt the content from the server, take
// extra care not to leak it
data = await importFromBackend(id, privateKey);
window.history.replaceState({}, "Excalidraw", window.location.origin);
} else {
data = restoreFromLocalStorage();
}

View File

@ -103,7 +103,8 @@
"cannotExportEmptyCanvas": "Cannot export empty canvas.",
"couldNotCopyToClipboard": "Couldn't copy to clipboard. Try using Chrome browser.",
"decryptFailed": "Couldn't decrypt data.",
"uploadedSecurly": "The upload has been secured with end-to-end encryption, which means that Excalidraw server and third parties can't read the content."
"uploadedSecurly": "The upload has been secured with end-to-end encryption, which means that Excalidraw server and third parties can't read the content.",
"loadSceneOverridePrompt": "Loading external drawing will replace your existing content. Do you wish to continue?"
},
"toolBar": {
"selection": "Selection",