mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Custom room, various fixes
This commit is contained in:
parent
e72d83541a
commit
c57249481e
3 changed files with 44 additions and 38 deletions
|
@ -856,7 +856,7 @@ const ExcalidrawWrapper = () => {
|
||||||
excalidrawAPI?.updateScene({
|
excalidrawAPI?.updateScene({
|
||||||
appState: {
|
appState: {
|
||||||
...excalidrawAPI?.getAppState(),
|
...excalidrawAPI?.getAppState(),
|
||||||
viewModeEnabled: value !== acknowledgedIncrements.length,
|
viewModeEnabled: value !== -1,
|
||||||
},
|
},
|
||||||
elements: Array.from(elements.values()),
|
elements: Array.from(elements.values()),
|
||||||
storeAction: StoreAction.UPDATE,
|
storeAction: StoreAction.UPDATE,
|
||||||
|
@ -865,7 +865,7 @@ const ExcalidrawWrapper = () => {
|
||||||
currentVersion.current = value;
|
currentVersion.current = value;
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
const latestVersion = acknowledgedIncrements.length - 1;
|
const latestVersion = acknowledgedIncrements.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -885,24 +885,24 @@ const ExcalidrawWrapper = () => {
|
||||||
step={1}
|
step={1}
|
||||||
min={0}
|
min={0}
|
||||||
max={latestVersion}
|
max={latestVersion}
|
||||||
value={
|
value={nextVersion === -1 ? latestVersion : nextVersion}
|
||||||
nextVersion === -1 || nextVersion === latestVersion
|
|
||||||
? latestVersion
|
|
||||||
: nextVersion
|
|
||||||
}
|
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
|
let nextValue: number;
|
||||||
|
|
||||||
// CFDO: should be disabled when offline! (later we could have speculative changes in the versioning log as well)
|
// CFDO: should be disabled when offline! (later we could have speculative changes in the versioning log as well)
|
||||||
// CFDO: in safari the whole canvas gets selected when dragging
|
// CFDO: in safari the whole canvas gets selected when dragging
|
||||||
if (value !== acknowledgedIncrements.length) {
|
if (value !== acknowledgedIncrements.length) {
|
||||||
// don't listen to updates in the detached mode
|
// don't listen to updates in the detached mode
|
||||||
syncAPI?.disconnect();
|
syncAPI?.disconnect();
|
||||||
|
nextValue = value as number;
|
||||||
} else {
|
} else {
|
||||||
// reconnect once we're back to the latest version
|
// reconnect once we're back to the latest version
|
||||||
syncAPI?.connect();
|
syncAPI?.connect();
|
||||||
|
nextValue = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
setNextVersion(value as number);
|
setNextVersion(nextValue);
|
||||||
debouncedTimeTravel(value as number);
|
debouncedTimeTravel(nextValue);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Excalidraw
|
<Excalidraw
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import throttle from "lodash.throttle";
|
import throttle from "lodash.throttle";
|
||||||
import ReconnectingWebSocket, { type Event } from "reconnecting-websocket";
|
import ReconnectingWebSocket, {
|
||||||
|
type Event,
|
||||||
|
type CloseEvent,
|
||||||
|
} from "reconnecting-websocket";
|
||||||
import { Utils } from "./utils";
|
import { Utils } from "./utils";
|
||||||
import {
|
import {
|
||||||
SyncQueue,
|
SyncQueue,
|
||||||
|
@ -76,7 +79,7 @@ class SocketClient {
|
||||||
window.addEventListener("online", this.onOnline);
|
window.addEventListener("online", this.onOnline);
|
||||||
window.addEventListener("offline", this.onOffline);
|
window.addEventListener("offline", this.onOffline);
|
||||||
|
|
||||||
console.debug("Connecting to the sync server...");
|
console.debug(`Connecting to the room "${this.roomId}"...`);
|
||||||
this.socket = new ReconnectingWebSocket(
|
this.socket = new ReconnectingWebSocket(
|
||||||
`${this.host}/connect?roomId=${this.roomId}`,
|
`${this.host}/connect?roomId=${this.roomId}`,
|
||||||
[],
|
[],
|
||||||
|
@ -95,16 +98,15 @@ class SocketClient {
|
||||||
);
|
);
|
||||||
this.socket.addEventListener("message", this.onMessage);
|
this.socket.addEventListener("message", this.onMessage);
|
||||||
this.socket.addEventListener("open", this.onOpen);
|
this.socket.addEventListener("open", this.onOpen);
|
||||||
|
this.socket.addEventListener("close", this.onClose);
|
||||||
|
this.socket.addEventListener("error", this.onError);
|
||||||
},
|
},
|
||||||
1000,
|
1000,
|
||||||
{ leading: true, trailing: false },
|
{ leading: true, trailing: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
// CFDO: the connections seem to keep hanging for some reason
|
// CFDO: the connections seem to keep hanging for some reason
|
||||||
public disconnect(
|
public disconnect() {
|
||||||
code: number = SocketClient.NORMAL_CLOSURE_CODE,
|
|
||||||
reason?: string,
|
|
||||||
) {
|
|
||||||
if (this.isDisconnected) {
|
if (this.isDisconnected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -113,25 +115,13 @@ class SocketClient {
|
||||||
window.removeEventListener("online", this.onOnline);
|
window.removeEventListener("online", this.onOnline);
|
||||||
window.removeEventListener("offline", this.onOffline);
|
window.removeEventListener("offline", this.onOffline);
|
||||||
|
|
||||||
console.debug(
|
|
||||||
`Disconnecting from the sync server with code "${code}"${
|
|
||||||
reason ? ` and reason "${reason}".` : "."
|
|
||||||
}`,
|
|
||||||
);
|
|
||||||
this.socket?.removeEventListener("message", this.onMessage);
|
this.socket?.removeEventListener("message", this.onMessage);
|
||||||
this.socket?.removeEventListener("open", this.onOpen);
|
this.socket?.removeEventListener("open", this.onOpen);
|
||||||
|
this.socket?.removeEventListener("close", this.onClose);
|
||||||
|
this.socket?.removeEventListener("error", this.onError);
|
||||||
|
this.socket?.close();
|
||||||
|
|
||||||
let remappedCode = code;
|
console.debug(`Disconnected from the room "${this.roomId}".`);
|
||||||
|
|
||||||
switch (code) {
|
|
||||||
case 1009: {
|
|
||||||
// remapping the code, otherwise getting "The close code must be either 1000, or between 3000 and 4999. 1009 is neither."
|
|
||||||
remappedCode = SocketClient.MESSAGE_IS_TOO_LARGE_ERROR_CODE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.socket?.close(remappedCode, reason);
|
|
||||||
} finally {
|
} finally {
|
||||||
this.socket = null;
|
this.socket = null;
|
||||||
}
|
}
|
||||||
|
@ -186,9 +176,21 @@ class SocketClient {
|
||||||
};
|
};
|
||||||
|
|
||||||
private onOpen = (event: Event) => {
|
private onOpen = (event: Event) => {
|
||||||
|
console.debug(`Connection to the room "${this.roomId}" opened.`);
|
||||||
this.isOffline = false;
|
this.isOffline = false;
|
||||||
this.handlers.onOpen(event);
|
this.handlers.onOpen(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onClose = (event: CloseEvent) => {
|
||||||
|
console.debug(`Connection to the room "${this.roomId}" closed.`, event);
|
||||||
|
};
|
||||||
|
|
||||||
|
private onError = (event: Event) => {
|
||||||
|
console.debug(
|
||||||
|
`Connection to the room "${this.roomId}" returned an error.`,
|
||||||
|
event,
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AcknowledgedIncrement {
|
interface AcknowledgedIncrement {
|
||||||
|
@ -258,9 +260,12 @@ export class SyncClient {
|
||||||
repository: IncrementsRepository & MetadataRepository,
|
repository: IncrementsRepository & MetadataRepository,
|
||||||
) {
|
) {
|
||||||
const queue = await SyncQueue.create(repository);
|
const queue = await SyncQueue.create(repository);
|
||||||
|
// CFDO: temporary for custom roomId (though E+ will be similar)
|
||||||
|
const roomId = window.location.pathname.split("/").at(-1);
|
||||||
|
|
||||||
return new SyncClient(api, repository, queue, {
|
return new SyncClient(api, repository, queue, {
|
||||||
host: SyncClient.HOST_URL,
|
host: SyncClient.HOST_URL,
|
||||||
roomId: SyncClient.ROOM_ID,
|
roomId: roomId ?? SyncClient.ROOM_ID,
|
||||||
// CFDO: temporary, so that all increments are loaded and applied on init
|
// CFDO: temporary, so that all increments are loaded and applied on init
|
||||||
lastAcknowledgedVersion: 0,
|
lastAcknowledgedVersion: 0,
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,6 +64,12 @@ const checkpoint = (name: string) => {
|
||||||
...strippedAppState
|
...strippedAppState
|
||||||
} = h.state;
|
} = h.state;
|
||||||
expect(strippedAppState).toMatchSnapshot(`[${name}] appState`);
|
expect(strippedAppState).toMatchSnapshot(`[${name}] appState`);
|
||||||
|
expect(h.elements.length).toMatchSnapshot(`[${name}] number of elements`);
|
||||||
|
h.elements
|
||||||
|
.map(({ seed, versionNonce, ...strippedElement }) => strippedElement)
|
||||||
|
.forEach((element, i) =>
|
||||||
|
expect(element).toMatchSnapshot(`[${name}] element ${i}`),
|
||||||
|
);
|
||||||
|
|
||||||
const stripSeed = (deltas: Record<string, { deleted: any; inserted: any }>) =>
|
const stripSeed = (deltas: Record<string, { deleted: any; inserted: any }>) =>
|
||||||
Object.entries(deltas).reduce((acc, curr) => {
|
Object.entries(deltas).reduce((acc, curr) => {
|
||||||
|
@ -92,6 +98,7 @@ const checkpoint = (name: string) => {
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
).toMatchSnapshot(`[${name}] undo stack`);
|
).toMatchSnapshot(`[${name}] undo stack`);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
h.history.redoStack.map((x) => ({
|
h.history.redoStack.map((x) => ({
|
||||||
...x,
|
...x,
|
||||||
|
@ -103,12 +110,6 @@ const checkpoint = (name: string) => {
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
).toMatchSnapshot(`[${name}] redo stack`);
|
).toMatchSnapshot(`[${name}] redo stack`);
|
||||||
expect(h.elements.length).toMatchSnapshot(`[${name}] number of elements`);
|
|
||||||
h.elements
|
|
||||||
.map(({ seed, versionNonce, ...strippedElement }) => strippedElement)
|
|
||||||
.forEach((element, i) =>
|
|
||||||
expect(element).toMatchSnapshot(`[${name}] element ${i}`),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderStaticScene = vi.spyOn(StaticScene, "renderStaticScene");
|
const renderStaticScene = vi.spyOn(StaticScene, "renderStaticScene");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue