Skip to content

Commit 55e4679

Browse files
committed
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 <max@nextcloud.com>
1 parent b7baceb commit 55e4679

3 files changed

Lines changed: 15 additions & 22 deletions

File tree

src/components/Editor.vue

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,6 @@ export default {
321321
},
322322
created() {
323323
this.$ydoc = new Doc()
324-
this.$ydoc.on('update', this.onYjsUpdate)
325324
this.$providers = []
326325
this.$editor = null
327326
this.$syncService = null
@@ -508,7 +507,6 @@ export default {
508507
: (session?.guestName || t('text', 'Guest')),
509508
color: session?.color,
510509
clientId: this.$ydoc.clientID,
511-
lastUpdate: Date.now(),
512510
},
513511
}),
514512
Keymap.configure({
@@ -644,13 +642,6 @@ export default {
644642
this.emit('delete-image-node', imageUrl)
645643
},
646644
647-
onYjsUpdate(_update, origin) {
648-
if (origin.key === 'y-sync$') {
649-
// Update timestamp of own cursor
650-
this.$editor.commands.updateSelf()
651-
}
652-
},
653-
654645
async close() {
655646
if (this.currentSession && this.$syncService) {
656647
try {

src/extensions/CollaborationCursor.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ function showCursorLabel(clientId) {
2020
}, 50)
2121
}
2222

23+
/**
24+
* Unix timestamp in seconds.
25+
*/
26+
function getTimestamp() {
27+
return Math.floor(Date.now() / 1000)
28+
}
29+
2330
const CollaborationCursor = TiptapCollaborationCursor.extend({
2431
addOptions() {
2532
return {
@@ -28,7 +35,7 @@ const CollaborationCursor = TiptapCollaborationCursor.extend({
2835
name: null,
2936
clientId: null,
3037
color: null,
31-
lastUpdate: null,
38+
lastUpdate: getTimestamp(),
3239
},
3340
render: user => {
3441
const cursor = document.createElement('span')
@@ -61,13 +68,12 @@ const CollaborationCursor = TiptapCollaborationCursor.extend({
6168
})
6269
},
6370

64-
addCommands() {
65-
return {
66-
...this.parent(),
67-
updateSelf: () => ({ editor }) => {
68-
const attributes = { ...this.options.user, lastUpdate: Date.now() }
69-
return editor.commands.updateUser(attributes)
70-
},
71+
// Flag own cursor as active on undoable changes to the document state
72+
onTransaction({ transaction }) {
73+
const { updated, meta } = transaction
74+
if (updated && (meta.addToHistory ?? true) && !meta.pointer) {
75+
this.options.user.lastUpdate = getTimestamp()
76+
this.options.provider.awareness.setLocalStateField('user', this.options.user)
7177
}
7278
},
7379
})

src/services/SyncService.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,10 @@ class SyncService {
150150
}
151151

152152
sendSteps(getSendable) {
153-
// If already retrying, do nothing.
153+
// If already waiting to send, do nothing.
154154
if (this.#sendIntervalId) {
155155
return
156156
}
157-
if (this.connection && !this.sending) {
158-
return this._sendSteps(getSendable)
159-
}
160-
// If already sending, retry every 200ms.
161157
return new Promise((resolve, reject) => {
162158
this.#sendIntervalId = setInterval(() => {
163159
if (this.connection && !this.sending) {

0 commit comments

Comments
 (0)