From 1cf2d1f9f217a4abf342b3c8dca640fd766baefe Mon Sep 17 00:00:00 2001 From: Sam Saffron Date: Wed, 27 May 2020 18:46:19 +1000 Subject: [PATCH] FIX: when destroying a draft always ensure saving is done There was a race condition where drafts could be either saving or queued to be saved and a user canceled draft leading to destroying it. This cancels debounce save and waits for save in the pipeline to be over prior to firing off a DELETE on the draft --- .../discourse/app/controllers/composer.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/discourse/app/controllers/composer.js b/app/assets/javascripts/discourse/app/controllers/composer.js index 41fb94c9103..d030c88c3a9 100644 --- a/app/assets/javascripts/discourse/app/controllers/composer.js +++ b/app/assets/javascripts/discourse/app/controllers/composer.js @@ -1,7 +1,7 @@ import I18n from "I18n"; import { isEmpty } from "@ember/utils"; import { and, or, alias, reads } from "@ember/object/computed"; -import { debounce } from "@ember/runloop"; +import { cancel, debounce } from "@ember/runloop"; import { inject as service } from "@ember/service"; import { inject } from "@ember/controller"; import Controller from "@ember/controller"; @@ -982,6 +982,10 @@ export default Controller.extend({ this.send("clearTopicDraft"); } + if (this._saveDraftPromise) { + return this._saveDraftPromise.then(() => this.destroyDraft()); + } + return Draft.clear(key, this.get("model.draftSequence")).then(() => this.appEvents.trigger("draft:destroyed", key) ); @@ -1028,6 +1032,10 @@ export default Controller.extend({ cancelComposer(differentDraft = false) { this.skipAutoSave = true; + if (this._saveDraftDebounce) { + cancel(this._saveDraftDebounce); + } + const keyPrefix = this.model.action === "edit" ? "post.abandon_edit" : "post.abandon"; @@ -1102,11 +1110,12 @@ export default Controller.extend({ // in test debounce is Ember.run, this will cause // an infinite loop if (ENV.environment !== "test") { - debounce(this, this._saveDraft, 2000); + this._saveDraftDebounce = debounce(this, this._saveDraft, 2000); } } else { - model.saveDraft().finally(() => { + this._saveDraftPromise = model.saveDraft().finally(() => { this._lastDraftSaved = Date.now(); + this._saveDraftPromise = null; }); } } @@ -1127,7 +1136,7 @@ export default Controller.extend({ if (Date.now() - this._lastDraftSaved > 15000) { this._saveDraft(); } else { - debounce(this, this._saveDraft, 2000); + this._saveDraftDebounce = debounce(this, this._saveDraft, 2000); } } },