fix: Don't save deleted ExcalidrawElements to Firebase (#5108)

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
DanielJGeiger 2022-05-09 08:38:44 -05:00 committed by GitHub
parent a524eeb66e
commit 0d70690ec8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 31 deletions

View file

@ -13,6 +13,7 @@ import { decompressData } from "../../data/encode";
import { encryptData, decryptData } from "../../data/encryption";
import { MIME_TYPES } from "../../constants";
import { reconcileElements } from "../collab/reconciliation";
import { getSyncableElements, SyncableExcalidrawElement } from ".";
// private
// -----------------------------------------------------------------------------
@ -127,7 +128,18 @@ const decryptElements = async (
return JSON.parse(decodedData);
};
const firebaseSceneVersionCache = new WeakMap<SocketIOClient.Socket, number>();
class FirebaseSceneVersionCache {
private static cache = new WeakMap<SocketIOClient.Socket, number>();
static get = (socket: SocketIOClient.Socket) => {
return FirebaseSceneVersionCache.cache.get(socket);
};
static set = (
socket: SocketIOClient.Socket,
elements: readonly SyncableExcalidrawElement[],
) => {
FirebaseSceneVersionCache.cache.set(socket, getSceneVersion(elements));
};
}
export const isSavedToFirebase = (
portal: Portal,
@ -136,7 +148,7 @@ export const isSavedToFirebase = (
if (portal.socket && portal.roomId && portal.roomKey) {
const sceneVersion = getSceneVersion(elements);
return firebaseSceneVersionCache.get(portal.socket) === sceneVersion;
return FirebaseSceneVersionCache.get(portal.socket) === sceneVersion;
}
// if no room exists, consider the room saved so that we don't unnecessarily
// prevent unload (there's nothing we could do at that point anyway)
@ -181,7 +193,7 @@ export const saveFilesToFirebase = async ({
const createFirebaseSceneDocument = async (
firebase: ResolutionType<typeof loadFirestore>,
elements: readonly ExcalidrawElement[],
elements: readonly SyncableExcalidrawElement[],
roomKey: string,
) => {
const sceneVersion = getSceneVersion(elements);
@ -197,7 +209,7 @@ const createFirebaseSceneDocument = async (
export const saveToFirebase = async (
portal: Portal,
elements: readonly ExcalidrawElement[],
elements: readonly SyncableExcalidrawElement[],
appState: AppState,
) => {
const { roomId, roomKey, socket } = portal;
@ -229,18 +241,18 @@ export const saveToFirebase = async (
transaction.set(docRef, sceneDocument);
return {
sceneVersion: sceneDocument.sceneVersion,
elements,
reconciledElements: null,
};
}
const prevDocData = snapshot.data() as FirebaseStoredScene;
const prevElements = await decryptElements(prevDocData, roomKey);
const prevElements = getSyncableElements(
await decryptElements(prevDocData, roomKey),
);
const reconciledElements = reconcileElements(
elements,
prevElements,
appState,
const reconciledElements = getSyncableElements(
reconcileElements(elements, prevElements, appState),
);
const sceneDocument = await createFirebaseSceneDocument(
@ -251,14 +263,14 @@ export const saveToFirebase = async (
transaction.update(docRef, sceneDocument);
return {
elements,
reconciledElements,
sceneVersion: sceneDocument.sceneVersion,
};
});
firebaseSceneVersionCache.set(socket, savedData.sceneVersion);
FirebaseSceneVersionCache.set(socket, savedData.elements);
return savedData;
return { reconciledElements: savedData.reconciledElements };
};
export const loadFromFirebase = async (
@ -275,10 +287,12 @@ export const loadFromFirebase = async (
return null;
}
const storedScene = doc.data() as FirebaseStoredScene;
const elements = await decryptElements(storedScene, roomKey);
const elements = getSyncableElements(
await decryptElements(storedScene, roomKey),
);
if (socket) {
firebaseSceneVersionCache.set(socket, getSceneVersion(elements));
FirebaseSceneVersionCache.set(socket, elements);
}
return restoreElements(elements, null);