From ad800aac128b48379d4d61d25d857dac62299e4b Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 27 Jul 2023 16:19:02 +0200 Subject: [PATCH] fix(sync): prevent duplicate pushes Document changes trigger awareness updates. Wait 50ms before sending them in a push request so they can be combined. Signed-off-by: Max --- src/components/Editor.vue | 9 --------- src/extensions/CollaborationCursor.js | 19 +++++++++++-------- src/services/SyncService.js | 3 --- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/components/Editor.vue b/src/components/Editor.vue index d8a3cec0b1a..ca8c0fd7ca1 100644 --- a/src/components/Editor.vue +++ b/src/components/Editor.vue @@ -321,7 +321,6 @@ export default { }, created() { this.$ydoc = new Doc() - this.$ydoc.on('update', this.onYjsUpdate) this.$providers = [] this.$editor = null this.$syncService = null @@ -508,7 +507,6 @@ export default { : (session?.guestName || t('text', 'Guest')), color: session?.color, clientId: this.$ydoc.clientID, - lastUpdate: Date.now(), }, }), Keymap.configure({ @@ -644,13 +642,6 @@ export default { this.emit('delete-image-node', imageUrl) }, - onYjsUpdate(_update, origin) { - if (origin.key === 'y-sync$') { - // Update timestamp of own cursor - this.$editor.commands.updateSelf() - } - }, - async close() { if (this.currentSession && this.$syncService) { try { diff --git a/src/extensions/CollaborationCursor.js b/src/extensions/CollaborationCursor.js index 927e96074e6..632897d4d87 100644 --- a/src/extensions/CollaborationCursor.js +++ b/src/extensions/CollaborationCursor.js @@ -20,6 +20,10 @@ function showCursorLabel(clientId) { }, 50) } +function getTimestamp() { + return Math.floor(Date.now() / 1000) +} + const CollaborationCursor = TiptapCollaborationCursor.extend({ addOptions() { return { @@ -28,7 +32,7 @@ const CollaborationCursor = TiptapCollaborationCursor.extend({ name: null, clientId: null, color: null, - lastUpdate: null, + lastUpdate: getTimestamp(), }, render: user => { const cursor = document.createElement('span') @@ -61,13 +65,12 @@ const CollaborationCursor = TiptapCollaborationCursor.extend({ }) }, - addCommands() { - return { - ...this.parent(), - updateSelf: () => ({ editor }) => { - const attributes = { ...this.options.user, lastUpdate: Date.now() } - return editor.commands.updateUser(attributes) - }, + // Flag own cursor as active on undoable changes to the document state + onTransaction({ transaction }) { + const { updated, meta } = transaction + if (updated && (meta.addToHistory ?? true) && !meta.pointer) { + this.options.user.lastUpdate = getTimestamp() + this.options.provider.awareness.setLocalStateField('user', this.options.user) } }, }) diff --git a/src/services/SyncService.js b/src/services/SyncService.js index a2eb814012d..8bea78178be 100644 --- a/src/services/SyncService.js +++ b/src/services/SyncService.js @@ -154,9 +154,6 @@ class SyncService { if (this.#sendIntervalId) { return } - if (this.connection && !this.sending) { - return this._sendSteps(getSendable) - } // If already sending, retry every 200ms. return new Promise((resolve, reject) => { this.#sendIntervalId = setInterval(() => {