Skip to content

Commit d717e66

Browse files
committed
stop sending update on reload/temporary pad
1 parent 138fcec commit d717e66

File tree

1 file changed

+46
-12
lines changed

1 file changed

+46
-12
lines changed

src/frontend/src/lib/collab/Collab.tsx

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class Collab extends PureComponent<CollabProps, CollabState> {
7272
private unsubExcalidrawPointerUp: (() => void) | null = null;
7373
private unsubExcalidrawSceneChange: (() => void) | null = null;
7474
private lastBroadcastedSceneVersion: number = -1;
75+
private isInitialLoad: boolean = true;
7576

7677
props: any;
7778

@@ -82,7 +83,7 @@ class Collab extends PureComponent<CollabProps, CollabState> {
8283
connectionStatus: 'Uninstantiated',
8384
username: props.user?.username || props.user?.id || '',
8485
collaborators: new Map(),
85-
lastProcessedSceneVersion: -1, // Version of the scene after applying remote changes
86+
lastProcessedSceneVersion: -1,
8687
};
8788

8889
this.portal = new Portal(
@@ -131,7 +132,6 @@ class Collab extends PureComponent<CollabProps, CollabState> {
131132

132133
// Compare each field dynamically, but exclude collaborators field
133134
allKeys.forEach(field => {
134-
// Skip collaborators field - those are updates about other users, not changes by this user
135135
if (field === 'collaborators') return;
136136

137137
const oldValue = oldState[field as keyof AppState];
@@ -213,6 +213,8 @@ class Collab extends PureComponent<CollabProps, CollabState> {
213213
if (ENABLE_PERIODIC_FULL_SYNC) {
214214
this.startPeriodicFullSync();
215215
}
216+
217+
this.isInitialLoad = false;
216218
}
217219

218220
componentDidUpdate(prevProps: CollabProps, prevState: CollabState) {
@@ -229,22 +231,19 @@ class Collab extends PureComponent<CollabProps, CollabState> {
229231
// Portal's updatePadId will handle disconnection from old and connection to new
230232
this.debouncedBroadcastAppState.cancel(); // Cancel any pending app state updates for the old pad
231233
this.lastSentAppState = null; // Reset last sent app state for the new pad
234+
235+
// Reset versions immediately when switching pads
236+
this.lastBroadcastedSceneVersion = -1;
237+
// Mark as initial load for the new pad
238+
this.isInitialLoad = true;
239+
232240
this.portal.updatePadId(this.props.padId);
233241
this.setState({
234242
collaborators: new Map(),
235243
lastProcessedSceneVersion: -1,
236244
username: this.props.user?.username || this.props.user?.id || '',
237245
// connectionStatus will be updated by portal's callbacks
238246
});
239-
this.lastBroadcastedSceneVersion = -1;
240-
241-
// Listeners might need to be re-evaluated if excalidrawAPI instance changes with padId
242-
// For now, assuming excalidrawAPI is stable or re-bound by parent
243-
if (this.props.excalidrawAPI) {
244-
const initialElements = this.props.excalidrawAPI.getSceneElementsIncludingDeleted();
245-
this.lastBroadcastedSceneVersion = getSceneVersion(initialElements);
246-
this.setState({ lastProcessedSceneVersion: this.lastBroadcastedSceneVersion });
247-
}
248247
}
249248

250249
if (this.state.collaborators !== prevState.collaborators) {
@@ -366,6 +365,31 @@ class Collab extends PureComponent<CollabProps, CollabState> {
366365
const allCurrentElements = this.props.excalidrawAPI.getSceneElementsIncludingDeleted();
367366
const currentSceneVersion = getSceneVersion(allCurrentElements);
368367

368+
if (allCurrentElements.length === 0 && this.isInitialLoad) {
369+
// No elements in the scene is the temporary scene
370+
return;
371+
}
372+
373+
// Handle version initialization (either fresh pad or loading from backend)
374+
if (this.lastBroadcastedSceneVersion === -1 || this.state.lastProcessedSceneVersion === -1) {
375+
// Initialize versions
376+
this.lastBroadcastedSceneVersion = currentSceneVersion;
377+
this.setState({ lastProcessedSceneVersion: currentSceneVersion });
378+
379+
// Only broadcast if this is NOT an initial load (i.e., it's a genuinely fresh pad with user changes)
380+
// and there are elements to broadcast
381+
if (!this.isInitialLoad && allCurrentElements.length > 0) {
382+
this.portal.broadcastSceneUpdate('SCENE_UPDATE', allCurrentElements, false);
383+
}
384+
385+
// Mark initial load as complete if it was an initial load
386+
if (this.isInitialLoad) {
387+
this.isInitialLoad = false;
388+
}
389+
390+
return;
391+
}
392+
369393
// Avoid broadcasting if the scene version hasn't actually increased from what this client last broadcasted
370394
// and isn't newer than what this client last processed from a remote update (prevents echo).
371395
if (currentSceneVersion > this.lastBroadcastedSceneVersion && currentSceneVersion > this.state.lastProcessedSceneVersion) {
@@ -495,7 +519,17 @@ class Collab extends PureComponent<CollabProps, CollabState> {
495519
);
496520

497521
this.props.excalidrawAPI.updateScene({ elements: reconciled as ExcalidrawElementType[], commitToHistory: false });
498-
this.setState({ lastProcessedSceneVersion: getSceneVersion(reconciled) });
522+
523+
const reconciledVersion = getSceneVersion(reconciled);
524+
this.setState({ lastProcessedSceneVersion: reconciledVersion });
525+
526+
// If this is a fresh pad (lastBroadcastedSceneVersion is -1), initialize it
527+
if (this.lastBroadcastedSceneVersion === -1) {
528+
console.debug('[pad.ws] Initializing lastBroadcastedSceneVersion from remote scene update');
529+
this.lastBroadcastedSceneVersion = reconciledVersion;
530+
// Mark initial load as complete since we received remote data
531+
this.isInitialLoad = false;
532+
}
499533
}
500534
break;
501535
}

0 commit comments

Comments
 (0)