save room to firebase on unload or portal close (#2207)

* save on unload or portal close

* align naming
This commit is contained in:
David Luzar 2020-10-06 04:34:40 +02:00 committed by GitHub
parent ae1ab1ab37
commit d18a72c879
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 24 deletions

View file

@ -176,7 +176,11 @@ import {
import { MaybeTransformHandleType } from "../element/transformHandles";
import { renderSpreadsheet } from "../charts";
import { isValidLibrary } from "../data/json";
import { loadFromFirebase, saveToFirebase } from "../data/firebase";
import {
loadFromFirebase,
saveToFirebase,
isSavedToFirebase,
} from "../data/firebase";
/**
* @param func handler taking at most single parameter (event).
@ -469,7 +473,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
return false;
}
const roomId = roomMatch[1];
const roomID = roomMatch[1];
let collabForceLoadFlag;
try {
@ -488,7 +492,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
);
// if loading same room as the one previously unloaded within 15sec
// force reload without prompting
if (previousRoom === roomId && Date.now() - timestamp < 15000) {
if (previousRoom === roomID && Date.now() - timestamp < 15000) {
return true;
}
} catch {}
@ -784,7 +788,17 @@ class App extends React.Component<ExcalidrawProps, AppState> {
);
} catch {}
}
if (this.state.isCollaborating && this.scene.getElements().length > 0) {
const syncableElements = getSyncableElements(
this.scene.getElementsIncludingDeleted(),
);
if (
this.state.isCollaborating &&
!isSavedToFirebase(this.portal, syncableElements)
) {
// this won't run in time if user decides to leave the site, but
// the purpose is to run in immediately after user decides to stay
this.saveCollabRoomToFirebase(syncableElements);
event.preventDefault();
// NOTE: modern browsers no longer allow showing a custom message here
event.returnValue = "";
@ -1182,6 +1196,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
};
closePortal = () => {
this.saveCollabRoomToFirebase();
window.history.pushState({}, "Excalidraw", window.location.origin);
this.destroySocketClient();
};
@ -1227,8 +1242,8 @@ class App extends React.Component<ExcalidrawProps, AppState> {
}
const roomMatch = getCollaborationLinkData(window.location.href);
if (roomMatch) {
const roomId = roomMatch[1];
const roomSecret = roomMatch[2];
const roomID = roomMatch[1];
const roomKey = roomMatch[2];
const initialize = () => {
this.portal.socketInitialized = true;
@ -1358,7 +1373,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
/* webpackChunkName: "socketIoClient" */ "socket.io-client"
);
this.portal.open(socketIOClient(SOCKET_SERVER), roomId, roomSecret);
this.portal.open(socketIOClient(SOCKET_SERVER), roomID, roomKey);
// All socket listeners are moving to Portal
this.portal.socket!.on(
@ -1430,7 +1445,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
});
try {
const elements = await loadFromFirebase(roomId, roomSecret);
const elements = await loadFromFirebase(roomID, roomKey);
if (elements) {
updateScene(
{ type: "SCENE_UPDATE", payload: { elements } },
@ -1484,6 +1499,18 @@ class App extends React.Component<ExcalidrawProps, AppState> {
}
};
saveCollabRoomToFirebase = async (
syncableElements: ExcalidrawElement[] = getSyncableElements(
this.scene.getElementsIncludingDeleted(),
),
) => {
try {
await saveToFirebase(this.portal, syncableElements);
} catch (error) {
console.error(error);
}
};
// maybe should move to Portal
broadcastScene = async (
sceneType: SCENE.INIT | SCENE.UPDATE,
@ -1530,16 +1557,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
data as SocketUpdateData,
);
if (syncAll && this.portal.roomID && this.portal.roomKey) {
if (syncAll && this.state.isCollaborating) {
await Promise.all([
broadcastPromise,
saveToFirebase(
this.portal.roomID,
this.portal.roomKey,
syncableElements,
).catch((e) => {
console.error(e);
}),
this.saveCollabRoomToFirebase(syncableElements),
]);
} else {
await broadcastPromise;