From a85b7feef4cfcf3d419e1f5abce8216b428b660f Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Fri, 10 May 2019 10:05:29 +0200 Subject: [PATCH] REFACTOR: composer controller (#7516) --- .../discourse/controllers/composer.js.es6 | 220 +++++++++--------- 1 file changed, 106 insertions(+), 114 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/composer.js.es6 b/app/assets/javascripts/discourse/controllers/composer.js.es6 index 9a370cee026..c6b1aba2ec7 100644 --- a/app/assets/javascripts/discourse/controllers/composer.js.es6 +++ b/app/assets/javascripts/discourse/controllers/composer.js.es6 @@ -116,7 +116,7 @@ export default Ember.Controller.extend({ }, @computed("showPreview") - toggleText: function(showPreview) { + toggleText(showPreview) { return showPreview ? I18n.t("composer.hide_preview") : I18n.t("composer.show_preview"); @@ -127,7 +127,7 @@ export default Ember.Controller.extend({ if (!this.site.mobileView) { this.keyValueStore.set({ key: "composer.showPreview", - value: this.get("showPreview") + value: this.showPreview }); } }, @@ -147,7 +147,7 @@ export default Ember.Controller.extend({ usernames = usernames || ""; if ( (creatingPM && usernames.length === 0) || - usernames === this.currentUser.get("username") + usernames === this.currentUser.username ) { return "usernames"; } @@ -172,7 +172,7 @@ export default Ember.Controller.extend({ // be default disabled. // That said we should remember the state this._toolbarEnabled = - $(window).width() > 370 && !this.capabilities.isAndroid; + window.innerWidth > 370 && !this.capabilities.isAndroid; } return this._toolbarEnabled || storedVal === "true"; }, @@ -192,11 +192,10 @@ export default Ember.Controller.extend({ @computed("model.canEditTitle", "model.creatingPrivateMessage") canEditTags(canEditTitle, creatingPrivateMessage) { return ( - this.site.get("can_tag_topics") && + this.site.can_tag_topics && canEditTitle && !creatingPrivateMessage && - (!this.get("model.topic.isPrivateMessage") || - this.site.get("can_tag_pms")) + (!this.get("model.topic.isPrivateMessage") || this.site.can_tag_pms) ); }, @@ -216,31 +215,24 @@ export default Ember.Controller.extend({ @computed("model.post") replyingToWhisper(repliedToPost) { return ( - repliedToPost && - repliedToPost.get("post_type") === this.site.post_types.whisper + repliedToPost && repliedToPost.post_type === this.site.post_types.whisper ); }, - @computed("replyingToWhisper", "model.whisper") - isWhispering(replyingToWhisper, whisper) { - return replyingToWhisper || whisper; - }, + isWhispering: Ember.computed.or("replyingToWhisper", "model.whisper"), @computed("model.action", "isWhispering") saveIcon(action, isWhispering) { - if (isWhispering) { - return "far-eye-slash"; - } + if (isWhispering) return "far-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"; - } + if (editConflict) return "composer.overwrite_edit"; + else if (isWhispering) return "composer.create_whisper"; + return SAVE_LABELS[action]; }, @@ -270,7 +262,7 @@ export default Ember.Controller.extend({ @computed("model.composeState", "model.creatingTopic", "model.post") popupMenuOptions(composeState) { if (composeState === "open" || composeState === "fullscreen") { - let options = []; + const options = []; options.push( this._setupPopupMenuOption(() => { @@ -295,9 +287,9 @@ export default Ember.Controller.extend({ ); return options.concat( - _popupMenuOptionsCallbacks.map(callback => { - return this._setupPopupMenuOption(callback); - }) + _popupMenuOptionsCallbacks.map(callback => + this._setupPopupMenuOption(callback) + ) ); } }, @@ -307,7 +299,9 @@ export default Ember.Controller.extend({ if (!Discourse.User.currentProp("staff")) { return false; } - var hasTargetGroups = this.get("model.hasTargetGroups"); + + const hasTargetGroups = this.get("model.hasTargetGroups"); + // We need exactly one user to issue a warning if ( Ember.isEmpty(usernames) || @@ -316,12 +310,13 @@ export default Ember.Controller.extend({ ) { return false; } + return creatingPrivateMessage; }, - @computed("model.topic") - draftTitle(topic) { - return emojiUnescape(escapeExpression(topic.get("title"))); + @computed("model.topic.title") + draftTitle(topicTitle) { + return emojiUnescape(escapeExpression(topicTitle)); }, @computed @@ -344,11 +339,11 @@ export default Ember.Controller.extend({ openComposer(options, post, topic) { this.open(options).then(() => { let url; - if (post) url = post.get("url"); - if (!post && topic) url = topic.get("url"); + if (post) url = post.url; + if (!post && topic) url = topic.url; let topicTitle; - if (topic) topicTitle = topic.get("title"); + if (topic) topicTitle = topic.title; if (!url || !topicTitle) return; @@ -360,7 +355,7 @@ export default Ember.Controller.extend({ const reply = this.get("model.reply"); if (!reply || !reply.includes(continueDiscussion)) { - this.get("model").prependText(continueDiscussion, { + this.model.prependText(continueDiscussion, { new_line: true }); } @@ -381,7 +376,7 @@ export default Ember.Controller.extend({ typed() { this.checkReplyLength(); - this.get("model").typing(); + this.model.typing(); }, cancelled() { @@ -394,13 +389,14 @@ export default Ember.Controller.extend({ afterRefresh($preview) { const topic = this.get("model.topic"); - const linkLookup = this.get("linkLookup"); + const linkLookup = this.linkLookup; + if (!topic || !linkLookup) { return; } // Don't check if there's only one post - if (topic.get("posts_count") === 1) { + if (topic.posts_count === 1) { return; } @@ -484,11 +480,13 @@ export default Ember.Controller.extend({ if (this.get("model.editingPost")) { const replyToPostNumber = this.get("model.post.reply_to_post_number"); if (replyToPostNumber) { - const replyPost = postStream - .get("posts") - .findBy("post_number", replyToPostNumber); + const replyPost = postStream.posts.findBy( + "post_number", + replyToPostNumber + ); + if (replyPost) { - postId = replyPost.get("id"); + postId = replyPost.id; } } } @@ -497,8 +495,8 @@ export default Ember.Controller.extend({ this.set("model.loading", true); const composer = this; - return this.store.find("post", postId).then(function(post) { - const quote = Quote.build(post, post.get("raw"), { + return this.store.find("post", postId).then(post => { + const quote = Quote.build(post, post.raw, { raw: true, full: true }); @@ -521,12 +519,14 @@ export default Ember.Controller.extend({ }, hitEsc() { - if (Ember.$(".emoji-picker-modal.fadeIn").length === 1) { + if ( + document.querySelectorAll(".emoji-picker-modal.fadeIn").length === 1 + ) { this.appEvents.trigger("emoji-picker:close"); return; } - if ((this.get("messageCount") || 0) > 0) { + if ((this.messageCount || 0) > 0) { this.appEvents.trigger("composer-messages:close"); return; } @@ -553,13 +553,13 @@ export default Ember.Controller.extend({ if (group.max_mentions < group.user_count) { body = I18n.t("composer.group_mentioned_limit", { - group: "@" + group.name, + group: `@${group.name}`, max: group.max_mentions, group_link: groupLink }); } else { body = I18n.t("composer.group_mentioned", { - group: "@" + group.name, + group: `@${group.name}`, count: group.user_count, group_link: groupLink }); @@ -580,7 +580,7 @@ export default Ember.Controller.extend({ ? "composer.cannot_see_mention.private" : "composer.cannot_see_mention.category"; const body = I18n.t(translation, { - username: "@" + mention.name + username: `@${mention.name}` }); this.appEvents.trigger("composer-messages:create", { extraClass: "custom-body", @@ -594,16 +594,16 @@ export default Ember.Controller.extend({ disableSubmit: Ember.computed.or("model.loading", "isUploading"), save(force) { - if (this.get("disableSubmit")) return; + if (this.disableSubmit) return; // Clear the warning state if we're not showing the checkbox anymore - if (!this.get("showWarning")) { + if (!this.showWarning) { this.set("model.isWarning", false); } - const composer = this.get("model"); + const composer = this.model; - if (composer.get("cantSubmitPost")) { + if (composer.cantSubmitPost) { this.set("lastValidatedAt", Date.now()); return; } @@ -612,15 +612,15 @@ export default Ember.Controller.extend({ // for now handle a very narrow use case // if we are replying to a topic AND not on the topic pop the window up - if (!force && composer.get("replyingToTopic")) { - const currentTopic = this.get("topicModel"); + if (!force && composer.replyingToTopic) { + const currentTopic = this.topicModel; if (!currentTopic) { this.save(true); return; } - if (currentTopic.get("id") !== composer.get("topic.id")) { + if (currentTopic.id !== composer.get("topic.id")) { const message = I18n.t("composer.posting_not_on_topic"); let buttons = [ @@ -639,8 +639,7 @@ export default Ember.Controller.extend({ "", class: "btn btn-reply-here", callback: () => { - composer.set("topic", currentTopic); - composer.set("post", null); + composer.setProperties({ topic: currentTopic, post: null }); this.save(true); } }); @@ -694,8 +693,8 @@ export default Ember.Controller.extend({ // If user "created a new topic/post" or "replied as a new topic" successfully, remove the draft. if ( result.responseJson.action === "create_post" || - this.get("replyAsNewTopicDraft") || - this.get("replyAsNewPrivateMessageDraft") + this.replyAsNewTopicDraft || + this.replyAsNewPrivateMessageDraft ) { this.destroyDraft(); } @@ -704,10 +703,7 @@ export default Ember.Controller.extend({ id: parseInt(result.responseJson.id) }); if (result.responseJson.post.post_number === 1) { - this.appEvents.trigger( - "header:update-topic", - composer.get("topic") - ); + this.appEvents.trigger("header:update-topic", composer.topic); } } else { this.appEvents.trigger("post-stream:refresh"); @@ -718,16 +714,16 @@ export default Ember.Controller.extend({ } this.close(); - const currentUser = Discourse.User.current(); - if (composer.get("creatingTopic")) { - currentUser.set("topic_count", currentUser.get("topic_count") + 1); + const currentUser = this.currentUser; + if (composer.creatingTopic) { + currentUser.set("topic_count", currentUser.topic_count + 1); } else { - currentUser.set("reply_count", currentUser.get("reply_count") + 1); + currentUser.set("reply_count", currentUser.reply_count + 1); } const post = result.target; if (post && !staged) { - DiscourseURL.routeTo(post.get("url")); + DiscourseURL.routeTo(post.url); } }) .catch(error => { @@ -775,8 +771,7 @@ export default Ember.Controller.extend({ throw new Error("composer opened without a proper draft key"); } - const self = this; - let composerModel = this.get("model"); + let composerModel = this.model; if ( opts.ignoreIfChanged && @@ -814,12 +809,12 @@ export default Ember.Controller.extend({ composerModel = null; } - return new Ember.RSVP.Promise(function(resolve, reject) { - if (composerModel && composerModel.get("replyDirty")) { + return new Ember.RSVP.Promise((resolve, reject) => { + if (composerModel && composerModel.replyDirty) { // If we're already open, we don't have to do anything if ( - composerModel.get("composeState") === Composer.OPEN && - composerModel.get("draftKey") === opts.draftKey && + composerModel.composeState === Composer.OPEN && + composerModel.draftKey === opts.draftKey && !opts.action ) { return resolve(); @@ -827,26 +822,21 @@ export default Ember.Controller.extend({ // If it's the same draft, just open it up again. if ( - composerModel.get("composeState") === Composer.DRAFT && - composerModel.get("draftKey") === opts.draftKey + composerModel.composeState === Composer.DRAFT && + composerModel.draftKey === opts.draftKey ) { composerModel.set("composeState", Composer.OPEN); if (!opts.action) return resolve(); } // If it's a different draft, cancel it and try opening again. - return self - .cancelComposer() - .then(function() { - return self.open(opts); - }) + return this.cancelComposer() + .then(() => this.open(opts)) .then(resolve, reject); } - if (composerModel) { - if (composerModel.get("action") !== opts.action) { - composerModel.setProperties({ unlistTopic: false, whisper: false }); - } + if (composerModel && composerModel.action !== opts.action) { + composerModel.setProperties({ unlistTopic: false, whisper: false }); } // we need a draft sequence for the composer to work @@ -858,31 +848,31 @@ export default Ember.Controller.extend({ return data; } - return self.confirmDraftAbandon(data); + return this.confirmDraftAbandon(data); }) .then(data => { if (!opts.draft && data.draft) { opts.draft = data.draft; } opts.draftSequence = data.draft_sequence; - self._setModel(composerModel, opts); + this._setModel(composerModel, opts); }) .then(resolve, reject); } // otherwise, do the draft check async else if (!opts.draft && !opts.skipDraftCheck) { Draft.get(opts.draftKey) - .then(data => self.confirmDraftAbandon(data)) + .then(data => this.confirmDraftAbandon(data)) .then(data => { if (data.draft) { opts.draft = data.draft; opts.draftSequence = data.draft_sequence; - self.open(opts); + this.open(opts); } }); } - self._setModel(composerModel, opts); + this._setModel(composerModel, opts); resolve(); }); }, @@ -902,8 +892,10 @@ export default Ember.Controller.extend({ } this.set("model", composerModel); - composerModel.set("composeState", Composer.OPEN); - composerModel.set("isWarning", false); + composerModel.setProperties({ + composeState: Composer.OPEN, + isWarning: false + }); if (opts.usernames && !this.get("model.targetUsernames")) { this.set("model.targetUsernames", opts.usernames); @@ -920,19 +912,17 @@ export default Ember.Controller.extend({ this.set("model.categoryId", opts.topicCategoryId); } - if ( - opts.topicTags && - !this.site.mobileView && - this.site.get("can_tag_topics") - ) { - const self = this; + if (opts.topicTags && !this.site.mobileView && this.site.can_tag_topics) { let tags = escapeExpression(opts.topicTags) .split(",") - .slice(0, self.siteSettings.max_tags_per_topic); - tags.forEach(function(tag, index, array) { - array[index] = tag.substring(0, self.siteSettings.max_tag_length); - }); - self.set("model.tags", tags); + .slice(0, this.siteSettings.max_tags_per_topic); + + tags.forEach( + (tag, index, array) => + (array[index] = tag.substring(0, this.siteSettings.max_tag_length)) + ); + + this.set("model.tags", tags); } if (opts.topicBody) { @@ -940,7 +930,6 @@ export default Ember.Controller.extend({ } }, - // View a new reply we've made viewNewReply() { DiscourseURL.routeTo(this.get("model.createdPost.url")); this.close(); @@ -954,9 +943,9 @@ export default Ember.Controller.extend({ this.send("clearTopicDraft"); } - Draft.clear(key, this.get("model.draftSequence")).then(() => { - this.appEvents.trigger("draft:destroyed", key); - }); + Draft.clear(key, this.get("model.draftSequence")).then(() => + this.appEvents.trigger("draft:destroyed", key) + ); } }, @@ -1006,7 +995,7 @@ export default Ember.Controller.extend({ callback: result => { if (result) { this.destroyDraft(); - this.get("model").clearState(); + this.model.clearState(); this.close(); resolve(); } @@ -1016,7 +1005,7 @@ export default Ember.Controller.extend({ } else { // it is possible there is some sort of crazy draft with no body ... just give up on it this.destroyDraft(); - this.get("model").clearState(); + this.model.clearState(); this.close(); resolve(); } @@ -1035,7 +1024,7 @@ export default Ember.Controller.extend({ }, _saveDraft() { - const model = this.get("model"); + const model = this.model; if (model) { model.saveDraft(); } @@ -1061,14 +1050,14 @@ export default Ember.Controller.extend({ tagValidation(category, tags, lastValidatedAt) { const tagsArray = tags || []; if ( - this.site.get("can_tag_topics") && + this.site.can_tag_topics && category && - category.get("minimum_required_tags") > tagsArray.length + category.minimum_required_tags > tagsArray.length ) { return InputValidation.create({ failed: true, reason: I18n.t("composer.error.tags_missing", { - count: category.get("minimum_required_tags") + count: category.minimum_required_tags }), lastShownAt: lastValidatedAt }); @@ -1093,7 +1082,10 @@ export default Ember.Controller.extend({ // the 'fullscreen-composer' class is added to remove scrollbars from the // document while in fullscreen mode. If the composer is closed for any reason // this class should be removed - $("html").removeClass("fullscreen-composer"); + + const elem = document.querySelector("html"); + elem.classList.remove("fullscreen-composer"); + this.setProperties({ model: null, lastValidatedAt: null }); }, @@ -1103,7 +1095,7 @@ export default Ember.Controller.extend({ @computed("model.action") canEdit(action) { - return action === "edit" && Discourse.User.current().get("can_edit"); + return action === "edit" && this.currentUser.can_edit; }, @computed("model.composeState")