diff --git a/app/assets/javascripts/discourse/controllers/composer.js.es6 b/app/assets/javascripts/discourse/controllers/composer.js.es6 index 1ae4cfffd68..9b250b122b0 100644 --- a/app/assets/javascripts/discourse/controllers/composer.js.es6 +++ b/app/assets/javascripts/discourse/controllers/composer.js.es6 @@ -16,6 +16,7 @@ import { } from "discourse/lib/utilities"; import { emojiUnescape } from "discourse/lib/text"; import { shortDate } from "discourse/lib/formatter"; +import { SAVE_LABELS, SAVE_ICONS } from "discourse/models/composer"; function loadDraft(store, opts) { opts = opts || {}; @@ -101,7 +102,7 @@ export default Ember.Controller.extend({ linkLookup: null, showPreview: true, forcePreview: Ember.computed.and("site.mobileView", "showPreview"), - whisperOrUnlistTopic: Ember.computed.or("model.whisper", "model.unlistTopic"), + whisperOrUnlistTopic: Ember.computed.or("isWhispering", "model.unlistTopic"), categories: Ember.computed.alias("site.categoriesList"), @on("init") @@ -200,15 +201,42 @@ export default Ember.Controller.extend({ canUnlistTopic: Ember.computed.and("model.creatingTopic", "isStaffUser"), - @computed("canWhisper", "model.post") - showWhisperToggle(canWhisper, repliedToPost) { - const replyingToWhisper = - repliedToPost && - repliedToPost.get("post_type") === this.site.post_types.whisper; - + @computed("canWhisper", "replyingToWhisper") + showWhisperToggle(canWhisper, replyingToWhisper) { return canWhisper && !replyingToWhisper; }, + @computed("model.post") + replyingToWhisper(repliedToPost) { + return ( + repliedToPost && + repliedToPost.get("post_type") === this.site.post_types.whisper + ); + }, + + @computed("replyingToWhisper", "model.whisper") + isWhispering(replyingToWhisper, whisper) { + return replyingToWhisper || whisper; + }, + + @computed("model.action", "isWhispering") + saveIcon(action, isWhispering) { + if (isWhispering) { + return "eye-slash"; + } + return SAVE_ICONS[action]; + }, + + @computed("model.action", "isWhispering", "model.editConflict") + saveLabel(action, isWhispering, editConflict) { + if (editConflict) { + return "composer.overwrite_edit"; + } else if (isWhispering) { + return "composer.create_whisper"; + } + return SAVE_LABELS[action]; + }, + @computed("isStaffUser", "model.action") canWhisper(isStaffUser, action) { return ( diff --git a/app/assets/javascripts/discourse/models/composer.js.es6 b/app/assets/javascripts/discourse/models/composer.js.es6 index 69a40d35f9e..e67e10515ff 100644 --- a/app/assets/javascripts/discourse/models/composer.js.es6 +++ b/app/assets/javascripts/discourse/models/composer.js.es6 @@ -52,7 +52,7 @@ const CLOSED = "closed", featuredLink: "topic.featured_link" }; -const SAVE_LABELS = { +export const SAVE_LABELS = { [EDIT]: "composer.save_edit", [REPLY]: "composer.reply", [CREATE_TOPIC]: "composer.create_topic", @@ -61,7 +61,7 @@ const SAVE_LABELS = { [EDIT_SHARED_DRAFT]: "composer.save_edit" }; -const SAVE_ICONS = { +export const SAVE_ICONS = { [EDIT]: "pencil", [EDIT_SHARED_DRAFT]: "clipboard", [REPLY]: "reply", @@ -385,24 +385,6 @@ const Composer = RestModel.extend({ return this.get("titleLength") <= this.siteSettings.max_topic_title_length; }.property("minimumTitleLength", "titleLength", "post.static_doc"), - @computed("action", "whisper") - saveIcon(action, whisper) { - if (whisper) { - return "eye-slash"; - } - return SAVE_ICONS[action]; - }, - - @computed("action", "whisper", "editConflict") - saveLabel(action, whisper, editConflict) { - if (editConflict) { - return "composer.overwrite_edit"; - } else if (whisper) { - return "composer.create_whisper"; - } - return SAVE_LABELS[action]; - }, - hasMetaData: function() { const metaData = this.get("metaData"); return metaData ? Ember.isEmpty(Ember.keys(this.get("metaData"))) : false; diff --git a/app/assets/javascripts/discourse/templates/composer.hbs b/app/assets/javascripts/discourse/templates/composer.hbs index a9c12751885..c991f58c214 100644 --- a/app/assets/javascripts/discourse/templates/composer.hbs +++ b/app/assets/javascripts/discourse/templates/composer.hbs @@ -25,7 +25,7 @@ {{plugin-outlet name="composer-action-after" noTags=true args=(hash model=model)}} {{#unless site.mobileView}} - {{#if model.whisper}} + {{#if isWhispering}} <span class='whisper'>{{d-icon 'eye-slash'}}</span> {{/if}} {{#if model.unlistTopic}} @@ -119,8 +119,8 @@ <div class='save-or-cancel'> {{#unless model.viewFullscreen}} {{composer-save-button action=(action "save") - icon=model.saveIcon - label=model.saveLabel + icon=saveIcon + label=saveLabel disableSubmit=disableSubmit}} {{#if site.mobileView}} diff --git a/test/javascripts/acceptance/composer-test.js.es6 b/test/javascripts/acceptance/composer-test.js.es6 index 2362f263448..4f80d96cd61 100644 --- a/test/javascripts/acceptance/composer-test.js.es6 +++ b/test/javascripts/acceptance/composer-test.js.es6 @@ -407,6 +407,44 @@ QUnit.test("Composer can toggle whispers", async assert => { ); }); +QUnit.test("Switching composer whisper state", async assert => { + const menu = selectKit(".toolbar-popup-menu-options"); + + await visit("/t/this-is-a-test-topic/9"); + await click(".topic-post:eq(0) button.reply"); + + await menu.expand(); + await menu.selectRowByValue("toggleWhisper"); + + await fillIn(".d-editor-input", "this is the content of my reply"); + await click("#reply-control button.create"); + + assert.ok(find(".topic-post:last").hasClass("whisper")); + + await click("#topic-footer-buttons .btn.create"); + + assert.ok( + find(".composer-fields .whisper .d-icon-eye-slash").length === 0, + "doesn’t set topic reply as whisper" + ); + + await click(".topic-post:last button.reply"); + + assert.ok(find(".topic-post:last").hasClass("whisper")); + assert.ok( + find(".composer-fields .whisper .d-icon-eye-slash").length === 1, + "sets post reply as a whisper" + ); + + await click(".topic-post:nth-last-child(2) button.reply"); + + assert.notOk(find(".topic-post:nth-last-child(2)").hasClass("whisper")); + assert.ok( + find(".composer-fields .whisper .d-icon-eye-slash").length === 0, + "doesn’t set post reply as a whisper" + ); +}); + QUnit.test( "Composer can toggle layouts (open, fullscreen and draft)", async assert => {