Skip to content

Commit

Permalink
feat(SessionApi): Send save request via sendBeacon at beforeunload
Browse files Browse the repository at this point in the history
This will send a final save request on unsaved changes via the browsers
native `navigator.sendBeacon()` function when navigating away from the
website or the tab/browser is closed.

Fixes: #6606

Signed-off-by: Jonas <jonas@freesources.org>
  • Loading branch information
mejo- authored and max-nextcloud committed Feb 5, 2025
1 parent df80b6e commit 2fa0402
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
10 changes: 10 additions & 0 deletions src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,10 @@ export default {
) {
this.dirty = state.dirty
if (this.dirty) {
window.addEventListener('beforeunload', this.saveBeforeUnload)

Check warning on line 681 in src/components/Editor.vue

View check run for this annotation

Codecov / codecov/patch

src/components/Editor.vue#L681

Added line #L681 was not covered by tests
this.$syncService.autosave()
} else {
window.removeEventListener('beforeunload', this.saveBeforeUnload)

Check warning on line 684 in src/components/Editor.vue

View check run for this annotation

Codecov / codecov/patch

src/components/Editor.vue#L683-L684

Added lines #L683 - L684 were not covered by tests
}
}
}
Expand Down Expand Up @@ -887,6 +890,13 @@ export default {
updateEditorWidth(newWidth) {
document.documentElement.style.setProperty('--text-editor-max-width', newWidth)
},

async saveBeforeUnload(event) {
if (!this.dirty && !this.document.hasUnsavedChanges) {
return
}
await this.$syncService.saveNoWait()
},

Check warning on line 899 in src/components/Editor.vue

View check run for this annotation

Codecov / codecov/patch

src/components/Editor.vue#L894-L899

Added lines #L894 - L899 were not covered by tests
},
}
</script>
Expand Down
15 changes: 12 additions & 3 deletions src/services/SessionApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import axios from '@nextcloud/axios'
import { getRequestToken } from '@nextcloud/auth'
import { generateUrl } from '@nextcloud/router'

export class ConnectionClosedError extends Error {
Expand Down Expand Up @@ -110,8 +111,9 @@ export class Connection {
})
}

save({ version, autosaveContent, documentState, force, manualSave }) {
return this.#post(this.#url(`session/${this.#document.id}/save`), {
save({ version, autosaveContent, documentState, force, manualSave, useSendBeacon = false }) {
const url = this.#url(`session/${this.#document.id}/save`)
const data = {

Check warning on line 116 in src/services/SessionApi.js

View check run for this annotation

Codecov / codecov/patch

src/services/SessionApi.js#L114-L116

Added lines #L114 - L116 were not covered by tests
...this.#defaultParams,
filePath: this.#options.filePath,
baseVersionEtag: this.#document.baseVersionEtag,
Expand All @@ -120,7 +122,14 @@ export class Connection {
documentState,
force,
manualSave,
})
}

Check warning on line 125 in src/services/SessionApi.js

View check run for this annotation

Codecov / codecov/patch

src/services/SessionApi.js#L125

Added line #L125 was not covered by tests

if (useSendBeacon) {
data.requesttoken = getRequestToken() ?? ''
const blob = new Blob([JSON.stringify(data)], { type: 'application/json' })
return navigator.sendBeacon(url, blob)
}
return this.#post(url, data)

Check warning on line 132 in src/services/SessionApi.js

View check run for this annotation

Codecov / codecov/patch

src/services/SessionApi.js#L127-L132

Added lines #L127 - L132 were not covered by tests
}

push({ steps, version, awareness }) {
Expand Down
12 changes: 12 additions & 0 deletions src/services/SyncService.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,18 @@ class SyncService {
}
}

async saveNoWait() {
await this.#connection.save({
version: this.version,
autosaveContent: this._getContent(),
documentState: this.getDocumentState(),
force: false,
manualSave: true,
useSendBeacon: true,
})
logger.debug('[SyncService] saved using sendBeacon (nowait)')
}

Check warning on line 312 in src/services/SyncService.js

View check run for this annotation

Codecov / codecov/patch

src/services/SyncService.js#L302-L312

Added lines #L302 - L312 were not covered by tests

forceSave() {
return this.save({ force: true })
}
Expand Down

0 comments on commit 2fa0402

Please sign in to comment.