diff --git a/app/assets/javascripts/discourse/app/controllers/composer.js b/app/assets/javascripts/discourse/app/controllers/composer.js index e9fa6a2c80f..5f0f114b095 100644 --- a/app/assets/javascripts/discourse/app/controllers/composer.js +++ b/app/assets/javascripts/discourse/app/controllers/composer.js @@ -1189,9 +1189,6 @@ export default Controller.extend({ }, onSaveDraft: () => { this._saveDraft(); - if (this.model.draftKey === Composer.NEW_TOPIC_KEY) { - this.currentUser.set("has_topic_draft", true); - } this.model.clearState(); this.close(); resolve(); @@ -1242,10 +1239,12 @@ export default Controller.extend({ ); } } else { - this._saveDraftPromise = model.saveDraft().finally(() => { - this._lastDraftSaved = Date.now(); - this._saveDraftPromise = null; - }); + this._saveDraftPromise = model + .saveDraft(this.currentUser) + .finally(() => { + this._lastDraftSaved = Date.now(); + this._saveDraftPromise = null; + }); } } }, diff --git a/app/assets/javascripts/discourse/app/models/composer.js b/app/assets/javascripts/discourse/app/models/composer.js index 36349ed1210..b93ab8c6e8a 100644 --- a/app/assets/javascripts/discourse/app/models/composer.js +++ b/app/assets/javascripts/discourse/app/models/composer.js @@ -1165,38 +1165,56 @@ const Composer = RestModel.extend({ return ""; }, - saveDraft() { + @discourseComputed( + "draftSaving", + "disableDrafts", + "canEditTitle", + "title", + "reply", + "titleLengthValid", + "replyLength", + "minimumPostLength" + ) + canSaveDraft() { if (this.draftSaving) { - return Promise.resolve(); + return false; } // Do not save when drafts are disabled if (this.disableDrafts) { - return Promise.resolve(); + return false; } if (this.canEditTitle) { // Save title and/or post body if (isEmpty(this.title) && isEmpty(this.reply)) { - return Promise.resolve(); + return false; } // Do not save when both title and reply's length are too small if (!this.titleLengthValid && this.replyLength < this.minimumPostLength) { - return Promise.resolve(); + return false; } } else { // Do not save when there is no reply if (isEmpty(this.reply)) { - return Promise.resolve(); + return false; } // Do not save when the reply's length is too small if (this.replyLength < this.minimumPostLength) { - return Promise.resolve(); + return false; } } + return true; + }, + + saveDraft(user) { + if (!this.canSaveDraft) { + return Promise.resolve(); + } + this.setProperties({ draftSaving: true, draftConflictUser: null, @@ -1225,6 +1243,10 @@ const Composer = RestModel.extend({ draftConflictUser: result.conflict_user, }); } else { + if (this.draftKey === NEW_TOPIC_KEY && user) { + user.set("has_topic_draft", true); + } + this.setProperties({ draftStatus: null, draftConflictUser: null, diff --git a/app/assets/javascripts/discourse/app/templates/modal/discard-draft.hbs b/app/assets/javascripts/discourse/app/templates/modal/discard-draft.hbs index 46c706cbc48..207cf43ccc7 100644 --- a/app/assets/javascripts/discourse/app/templates/modal/discard-draft.hbs +++ b/app/assets/javascripts/discourse/app/templates/modal/discard-draft.hbs @@ -6,6 +6,8 @@ diff --git a/app/assets/javascripts/discourse/tests/acceptance/composer-test.js b/app/assets/javascripts/discourse/tests/acceptance/composer-test.js index 4f8aee38cf6..5cbdf0bc912 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/composer-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/composer-test.js @@ -999,4 +999,15 @@ acceptance("Composer", function (needs) { await fillIn(".d-editor-input", "@staff"); assert.ok(exists(".composer-popup"), "Shows the 'group_mentioned' notice"); }); + + test("Does not save invalid draft", async function (assert) { + this.siteSettings.min_first_post_length = 20; + + await visit("/"); + await click("#create-topic"); + await fillIn("#reply-title", "Something"); + await fillIn(".d-editor-input", "Something"); + await click(".save-or-cancel .cancel"); + assert.notOk(exists(".discard-draft-modal .save-draft")); + }); });