|
@@ -13,6 +13,7 @@ import { ExcalidrawImperativeAPI } from "../components/App";
|
|
|
import { ErrorDialog } from "../components/ErrorDialog";
|
|
|
import { TopErrorBoundary } from "../components/TopErrorBoundary";
|
|
|
import { APP_NAME, EVENT, TITLE_TIMEOUT, VERSION_TIMEOUT } from "../constants";
|
|
|
+import { loadFromBlob } from "../data/blob";
|
|
|
import { DataState, ImportedDataState } from "../data/types";
|
|
|
import {
|
|
|
ExcalidrawElement,
|
|
@@ -69,9 +70,10 @@ const initializeScene = async (opts: {
|
|
|
}): Promise<ImportedDataState | null> => {
|
|
|
const searchParams = new URLSearchParams(window.location.search);
|
|
|
const id = searchParams.get("id");
|
|
|
- const jsonMatch = window.location.hash.match(
|
|
|
+ const jsonBackendMatch = window.location.hash.match(
|
|
|
/^#json=([0-9]+),([a-zA-Z0-9_-]+)$/,
|
|
|
);
|
|
|
+ const externalUrlMatch = window.location.hash.match(/^#url=(.*)$/);
|
|
|
|
|
|
const initialData = importFromLocalStorage();
|
|
|
|
|
@@ -82,7 +84,7 @@ const initializeScene = async (opts: {
|
|
|
);
|
|
|
|
|
|
let roomLinkData = getCollaborationLinkData(window.location.href);
|
|
|
- const isExternalScene = !!(id || jsonMatch || roomLinkData);
|
|
|
+ const isExternalScene = !!(id || jsonBackendMatch || roomLinkData);
|
|
|
if (isExternalScene) {
|
|
|
if (
|
|
|
// don't prompt if scene is empty
|
|
@@ -95,8 +97,12 @@ const initializeScene = async (opts: {
|
|
|
// Backwards compatibility with legacy url format
|
|
|
if (id) {
|
|
|
scene = await loadScene(id, null, initialData);
|
|
|
- } else if (jsonMatch) {
|
|
|
- scene = await loadScene(jsonMatch[1], jsonMatch[2], initialData);
|
|
|
+ } else if (jsonBackendMatch) {
|
|
|
+ scene = await loadScene(
|
|
|
+ jsonBackendMatch[1],
|
|
|
+ jsonBackendMatch[2],
|
|
|
+ initialData,
|
|
|
+ );
|
|
|
}
|
|
|
scene.scrollToCenter = true;
|
|
|
if (!roomLinkData) {
|
|
@@ -119,7 +125,28 @@ const initializeScene = async (opts: {
|
|
|
roomLinkData = null;
|
|
|
window.history.replaceState({}, APP_NAME, window.location.origin);
|
|
|
}
|
|
|
+ } else if (externalUrlMatch) {
|
|
|
+ window.history.replaceState({}, APP_NAME, window.location.origin);
|
|
|
+
|
|
|
+ const url = externalUrlMatch[1];
|
|
|
+ try {
|
|
|
+ const request = await fetch(window.decodeURIComponent(url));
|
|
|
+ const data = await loadFromBlob(await request.blob(), null);
|
|
|
+ if (
|
|
|
+ !scene.elements.length ||
|
|
|
+ window.confirm(t("alerts.loadSceneOverridePrompt"))
|
|
|
+ ) {
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ return {
|
|
|
+ appState: {
|
|
|
+ errorMessage: t("alerts.invalidSceneUrl"),
|
|
|
+ },
|
|
|
+ };
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
if (roomLinkData) {
|
|
|
return opts.collabAPI.initializeSocketClient(roomLinkData);
|
|
|
} else if (scene) {
|