From 091af27a31ba84f863823f666019b6704751fef2 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 12 Mar 2015 14:41:58 -0400 Subject: [PATCH] FIX: Reply as new topic should select the correct category --- .../discourse/components/post-gutter.js.es6 | 5 +- .../discourse/controllers/composer.js.es6 | 2 +- .../discourse/controllers/topic.js.es6 | 197 ++++++++--------- .../models/{composer.js => composer.js.es6} | 208 +++++++++--------- 4 files changed, 205 insertions(+), 207 deletions(-) rename app/assets/javascripts/discourse/models/{composer.js => composer.js.es6} (83%) diff --git a/app/assets/javascripts/discourse/components/post-gutter.js.es6 b/app/assets/javascripts/discourse/components/post-gutter.js.es6 index 31f887adb81..d40fcbad44e 100644 --- a/app/assets/javascripts/discourse/components/post-gutter.js.es6 +++ b/app/assets/javascripts/discourse/components/post-gutter.js.es6 @@ -1,6 +1,7 @@ var MAX_SHOWN = 5; import StringBuffer from 'discourse/mixins/string-buffer'; +import { iconHTML } from 'discourse/helpers/fa-icon'; export default Em.Component.extend(StringBuffer, { classNameBindings: [':gutter'], @@ -55,14 +56,14 @@ export default Em.Component.extend(StringBuffer, { if (collapsed) { var remaining = links.length - MAX_SHOWN; if (remaining > 0) { - buffer.push("
  • " + I18n.t('post.more_links', {count: remaining}) + "
  • "); + buffer.push("
  • " + I18n.t('post.more_links', {count: remaining}) + "
  • "); } } buffer.push(''); } if ((links.length <= MAX_SHOWN || !collapsed) && this.get('canReplyAsNewTopic')) { - buffer.push("" + I18n.t('post.reply_as_new_topic') + ""); + buffer.push("" + iconHTML('plus') + I18n.t('post.reply_as_new_topic') + ""); } }, diff --git a/app/assets/javascripts/discourse/controllers/composer.js.es6 b/app/assets/javascripts/discourse/controllers/composer.js.es6 index 928c2d2dc1f..40ef1d2a5a4 100644 --- a/app/assets/javascripts/discourse/controllers/composer.js.es6 +++ b/app/assets/javascripts/discourse/controllers/composer.js.es6 @@ -410,7 +410,7 @@ export default DiscourseController.extend({ // Given a potential instance and options, set the model for this composer. _setModel(composerModel, opts) { if (opts.draft) { - composerModel = Discourse.Composer.loadDraft(opts.draftKey, opts.draftSequence, opts.draft); + composerModel = Discourse.Composer.loadDraft(opts); if (composerModel) { composerModel.set('topic', opts.topic); } diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 3b3850b6710..e0da67fe63f 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -20,7 +20,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }.observes('topic'), _titleChanged: function() { - var title = this.get('title'); + const title = this.get('title'); if (!Ember.isEmpty(title)) { // Note normally you don't have to trigger this, but topic titles can be updated @@ -30,8 +30,8 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }.observes('title', 'category'), termChanged: function() { - var dropdown = this.get('controllers.header.visibleDropdown'); - var term = this.get('controllers.search.term'); + const dropdown = this.get('controllers.header.visibleDropdown'); + const term = this.get('controllers.search.term'); if(dropdown === 'search-dropdown' && term){ this.set('searchHighlight', term); @@ -43,13 +43,13 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }.observes('controllers.search.term', 'controllers.header.visibleDropdown'), - postStreamLoadedAllPostsChanged: function(){ + postStreamLoadedAllPostsChanged: function() { // semantics of loaded all posts are slightly diff at topic level, // it just means that we "once" loaded all posts, this means we don't // keep re-rendering the suggested topics when new posts zoom in - var loaded = this.get('postStream.loadedAllPosts'); + let loaded = this.get('postStream.loadedAllPosts'); - if(loaded) { + if (loaded) { this.set('loadedTopicId', this.get('model.id')); } else { loaded = this.get('loadedTopicId') === this.get('model.id'); @@ -60,7 +60,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }.observes('postStream', 'postStream.loadedAllPosts'), show_deleted: function(key, value) { - var postStream = this.get('postStream'); + const postStream = this.get('postStream'); if (!postStream) { return; } if (arguments.length > 1) { @@ -70,7 +70,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }.property('postStream.summary'), filter: function(key, value) { - var postStream = this.get('postStream'); + const postStream = this.get('postStream'); if (!postStream) { return; } if (arguments.length > 1) { @@ -80,7 +80,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }.property('postStream.summary'), username_filters: function(key, value) { - var postStream = this.get('postStream'); + const postStream = this.get('postStream'); if (!postStream) { return; } if (arguments.length > 1) { @@ -89,20 +89,19 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon return postStream.get('streamFilters.username_filters'); }.property('postStream.streamFilters.username_filters'), - init: function() { - this._super(); + _clearSelected: function() { this.set('selectedPosts', []); this.set('selectedReplies', []); - }, + }.on('init'), actions: { - deleteTopic: function() { + deleteTopic() { this.deleteTopic(); }, // Post related methods - replyToPost: function(post) { - var composerController = this.get('controllers.composer'), + replyToPost(post) { + const composerController = this.get('controllers.composer'), quoteController = this.get('controllers.quote-button'), quotedText = Discourse.Quote.build(quoteController.get('post'), quoteController.get('buffer')), topic = post ? post.get('topic') : this.get('model'); @@ -116,7 +115,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon composerController.appendText(quotedText); } else { - var opts = { + const opts = { action: Discourse.Composer.REPLY, draftKey: topic.get('draft_key'), draftSequence: topic.get('draft_sequence') @@ -135,14 +134,14 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon return false; }, - toggleLike: function(post) { - var likeAction = post.get('actionByName.like'); + toggleLike(post) { + const likeAction = post.get('actionByName.like'); if (likeAction && likeAction.get('canToggle')) { likeAction.toggle(); } }, - recoverPost: function(post) { + recoverPost(post) { // Recovering the first post recovers the topic instead if (post.get('post_number') === 1) { this.recoverTopic(); @@ -151,7 +150,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon post.recover(); }, - deletePost: function(post) { + deletePost(post) { // Deleting the first post deletes the topic if (post.get('post_number') === 1) { @@ -159,7 +158,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon return; } - var user = Discourse.User.current(), + const user = Discourse.User.current(), replyCount = post.get('reply_count'), self = this; @@ -169,13 +168,13 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon {label: I18n.t("cancel"), 'class': 'btn-danger rightg'}, {label: I18n.t("post.controls.delete_replies.no_value"), - callback: function() { + callback() { post.destroy(user); } }, {label: I18n.t("post.controls.delete_replies.yes_value"), 'class': 'btn-primary', - callback: function() { + callback() { Discourse.Post.deleteMany([post], [post]); self.get('postStream.posts').forEach(function (p) { if (p === post || p.get('reply_to_post_number') === post.get('post_number')) { @@ -188,7 +187,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon } else { post.destroy(user).then(null, function(e) { post.undoDeleteState(); - var response = $.parseJSON(e.responseText); + const response = $.parseJSON(e.responseText); if (response && response.errors) { bootbox.alert(response.errors[0]); } else { @@ -198,7 +197,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon } }, - editPost: function(post) { + editPost(post) { if (!Discourse.User.current()) { return bootbox.alert(I18n.t('post.controls.edit_anonymous')); } @@ -211,7 +210,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }); }, - toggleBookmark: function(post) { + toggleBookmark(post) { if (!Discourse.User.current()) { alert(I18n.t("bookmarks.not_bookmarked")); return; @@ -229,12 +228,12 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon } }, - jumpTop: function() { + jumpTop() { this.get('controllers.topic-progress').send('jumpTop'); }, - selectAll: function() { - var posts = this.get('postStream.posts'), + selectAll() { + const posts = this.get('postStream.posts'), selectedPosts = this.get('selectedPosts'); if (posts) { selectedPosts.addObjects(posts); @@ -242,37 +241,37 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon this.set('allPostsSelected', true); }, - deselectAll: function() { + deselectAll() { this.get('selectedPosts').clear(); this.get('selectedReplies').clear(); this.set('allPostsSelected', false); }, - toggleParticipant: function(user) { + toggleParticipant(user) { this.get('postStream').toggleParticipant(Em.get(user, 'username')); }, - editTopic: function() { + editTopic() { if (!this.get('details.can_edit')) return false; this.set('editingTopic', true); return false; }, - cancelEditingTopic: function() { + cancelEditingTopic() { this.set('editingTopic', false); this.rollbackBuffer(); }, - toggleMultiSelect: function() { + toggleMultiSelect() { this.toggleProperty('multiSelect'); }, - finishedEditingTopic: function() { + finishedEditingTopic() { if (!this.get('editingTopic')) { return; } // save the modifications - var self = this, + const self = this, props = this.get('buffered.buffer'); Topic.update(this.get('model'), props).then(function() { @@ -289,12 +288,12 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }); }, - toggledSelectedPost: function(post) { + toggledSelectedPost(post) { this.performTogglePost(post); }, - toggledSelectedPostReplies: function(post) { - var selectedReplies = this.get('selectedReplies'); + toggledSelectedPostReplies(post) { + const selectedReplies = this.get('selectedReplies'); if (this.performTogglePost(post)) { selectedReplies.addObject(post); } else { @@ -302,8 +301,8 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon } }, - deleteSelected: function() { - var self = this; + deleteSelected() { + const self = this; bootbox.confirm(I18n.t("post.delete.confirm", { count: this.get('selectedPostsCount')}), function(result) { if (result) { @@ -312,7 +311,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon return self.deleteTopic(); } - var selectedPosts = self.get('selectedPosts'), + const selectedPosts = self.get('selectedPosts'), selectedReplies = self.get('selectedReplies'), postStream = self.get('postStream'), toRemove = []; @@ -328,59 +327,54 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }); }, - expandHidden: function(post) { + expandHidden(post) { post.expandHidden(); }, - toggleVisibility: function() { + toggleVisibility() { this.get('content').toggleStatus('visible'); }, - toggleClosed: function() { + toggleClosed() { this.get('content').toggleStatus('closed'); }, - recoverTopic: function() { + recoverTopic() { this.get('content').recover(); }, - makeBanner: function() { + makeBanner() { this.get('content').makeBanner(); }, - removeBanner: function() { + removeBanner() { this.get('content').removeBanner(); }, - togglePinned: function() { + togglePinned() { // Note that this is different than clearPin this.get('content').setStatus('pinned', this.get('pinned_at') ? false : true); }, - togglePinnedGlobally: function() { + togglePinnedGlobally() { // Note that this is different than clearPin this.get('content').setStatus('pinned_globally', this.get('pinned_at') ? false : true); }, - toggleArchived: function() { + toggleArchived() { this.get('content').toggleStatus('archived'); }, // Toggle the star on the topic - toggleStar: function() { + toggleStar() { this.get('content').toggleStar(); }, - /** - Clears the pin from a topic for the currently logged in user - - @method clearPin - **/ - clearPin: function() { + clearPin() { this.get('content').clearPin(); }, - togglePinnedForUser: function() { + togglePinnedForUser() { if (this.get('pinned_at')) { if (this.get('pinned')) { this.get('content').clearPin(); @@ -390,28 +384,29 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon } }, - replyAsNewTopic: function(post) { - var composerController = this.get('controllers.composer'), - quoteController = this.get('controllers.quote-button'), - quotedText = Discourse.Quote.build(quoteController.get('post'), quoteController.get('buffer')), - self = this; + replyAsNewTopic(post) { + const composerController = this.get('controllers.composer'), + quoteController = this.get('controllers.quote-button'), + quotedText = Discourse.Quote.build(quoteController.get('post'), quoteController.get('buffer')), + self = this; quoteController.deselectText(); composerController.open({ action: Discourse.Composer.CREATE_TOPIC, - draftKey: Discourse.Composer.REPLY_AS_NEW_TOPIC_KEY + draftKey: Discourse.Composer.REPLY_AS_NEW_TOPIC_KEY, + categoryId: this.get('category.id') }).then(function() { return Em.isEmpty(quotedText) ? Discourse.Post.loadQuote(post.get('id')) : quotedText; }).then(function(q) { - var postUrl = "" + location.protocol + "//" + location.host + (post.get('url')), - postLink = "[" + self.get('title') + "](" + postUrl + ")"; + const postUrl = "" + location.protocol + "//" + location.host + (post.get('url')), + postLink = "[" + self.get('title') + "](" + postUrl + ")"; composerController.appendText(I18n.t("post.continue_discussion", { postLink: postLink }) + "\n\n" + q); }); }, - expandFirstPost: function(post) { - var self = this; + expandFirstPost(post) { + const self = this; this.set('loadingExpanded', true); post.expand().then(function() { self.set('firstPostExpanded', true); @@ -422,8 +417,8 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }); }, - retryLoading: function() { - var self = this; + retryLoading() { + const self = this; self.set('retrying', true); this.get('postStream').refresh().then(function() { self.set('retrying', false); @@ -432,7 +427,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }); }, - toggleWiki: function(post) { + toggleWiki(post) { // the request to the server is made in an observer in the post class post.toggleProperty('wiki'); }, @@ -449,21 +444,21 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon } }, - rebakePost: function (post) { + rebakePost(post) { post.rebake(); }, - unhidePost: function (post) { + unhidePost(post) { post.unhide(); } }, - togglePinnedState: function() { + togglePinnedState() { this.send('togglePinnedForUser'); }, showExpandButton: function() { - var post = this.get('post'); + const post = this.get('post'); return post.get('post_number') === 1 && post.get('topic.expandable_first_post'); }.property(), @@ -495,12 +490,12 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }.property('selectedPostsCount', 'allPostsSelected'), canDeleteSelected: function() { - var selectedPosts = this.get('selectedPosts'); + const selectedPosts = this.get('selectedPosts'); if (this.get('allPostsSelected')) return true; if (this.get('selectedPostsCount') === 0) return false; - var canDelete = true; + let canDelete = true; selectedPosts.forEach(function(p) { if (!p.get('can_delete')) { canDelete = false; @@ -520,19 +515,19 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon } }.observes('multiSelect'), - deselectPost: function(post) { + deselectPost(post) { this.get('selectedPosts').removeObject(post); - var selectedReplies = this.get('selectedReplies'); + const selectedReplies = this.get('selectedReplies'); selectedReplies.removeObject(post); - var selectedReply = selectedReplies.findProperty('post_number', post.get('reply_to_post_number')); + const selectedReply = selectedReplies.findProperty('post_number', post.get('reply_to_post_number')); if (selectedReply) { selectedReplies.removeObject(selectedReply); } this.set('allPostsSelected', false); }, - postSelected: function(post) { + postSelected(post) { if (this.get('allPostsSelected')) { return true; } if (this.get('selectedPosts').contains(post)) { return true; } if (this.get('selectedReplies').findProperty('post_number', post.get('reply_to_post_number'))) { return true; } @@ -548,11 +543,11 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon return spinnerHTML; }.property(), - recoverTopic: function() { + recoverTopic() { this.get('content').recover(); }, - deleteTopic: function() { + deleteTopic() { this.unsubscribe(); this.get('content').destroy(Discourse.User.current()); }, @@ -600,8 +595,8 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }); }, - unsubscribe: function() { - var topicId = this.get('content.id'); + unsubscribe() { + const topicId = this.get('content.id'); if (!topicId) return; // there is a condition where the view never calls unsubscribe, navigate to a topic from a topic @@ -609,12 +604,12 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }, // Topic related - reply: function() { + reply() { this.replyToPost(); }, - performTogglePost: function(post) { - var selectedPosts = this.get('selectedPosts'); + performTogglePost(post) { + const selectedPosts = this.get('selectedPosts'); if (this.postSelected(post)) { this.deselectPost(post); return false; @@ -631,14 +626,14 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon // If our current post is changed, notify the router _currentPostChanged: function() { - var currentPost = this.get('currentPost'); + const currentPost = this.get('currentPost'); if (currentPost) { this.send('postChangedRoute', currentPost); } }.observes('currentPost'), - readPosts: function(topicId, postNumbers) { - var postStream = this.get('postStream'); + readPosts(topicId, postNumbers) { + const postStream = this.get('postStream'); if(this.get('postStream.topic.id') === topicId){ _.each(postStream.get('posts'), function(post){ @@ -649,7 +644,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon } }); - var max = _.max(postNumbers); + const max = _.max(postNumbers); if(max > this.get('last_read_post_number')){ this.set('last_read_post_number', max); } @@ -657,10 +652,10 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon }, // Called the the topmost visible post on the page changes. - topVisibleChanged: function(post) { + topVisibleChanged(post) { if (!post) { return; } - var postStream = this.get('postStream'), + const postStream = this.get('postStream'), firstLoadedPost = postStream.get('firstLoadedPost'); this.set('currentPost', post.get('post_number')); @@ -671,16 +666,16 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon // Note: jQuery shouldn't be done in a controller, but how else can we // trigger a scroll after a promise resolves in a controller? We need // to do this to preserve upwards infinte scrolling. - var $body = $('body'), - $elem = $('#post-cloak-' + post.get('post_number')), - distToElement = $body.scrollTop() - $elem.position().top; + const $body = $('body'); + let $elem = $('#post-cloak-' + post.get('post_number')); + const distToElement = $body.scrollTop() - $elem.position().top; postStream.prependMore().then(function() { Em.run.next(function () { $elem = $('#post-cloak-' + post.get('post_number')); // Quickly going back might mean the element is destroyed - var position = $elem.position(); + const position = $elem.position(); if (position && position.top) { $('html, body').scrollTop(position.top + distToElement); } @@ -695,10 +690,10 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon @method bottomVisibleChanged @params {Discourse.Post} post that is at the bottom **/ - bottomVisibleChanged: function(post) { + bottomVisibleChanged(post) { if (!post) { return; } - var postStream = this.get('postStream'), + const postStream = this.get('postStream'), lastLoadedPost = postStream.get('lastLoadedPost'); this.set('controllers.topic-progress.progressPosition', postStream.progressIndexOfPost(post)); diff --git a/app/assets/javascripts/discourse/models/composer.js b/app/assets/javascripts/discourse/models/composer.js.es6 similarity index 83% rename from app/assets/javascripts/discourse/models/composer.js rename to app/assets/javascripts/discourse/models/composer.js.es6 index af70156cb79..4a80fdeab04 100644 --- a/app/assets/javascripts/discourse/models/composer.js +++ b/app/assets/javascripts/discourse/models/composer.js.es6 @@ -1,32 +1,32 @@ -var CLOSED = 'closed', - SAVING = 'saving', - OPEN = 'open', - DRAFT = 'draft', +const CLOSED = 'closed', + SAVING = 'saving', + OPEN = 'open', + DRAFT = 'draft', - // The actions the composer can take - CREATE_TOPIC = 'createTopic', - PRIVATE_MESSAGE = 'privateMessage', - REPLY = 'reply', - EDIT = 'edit', - REPLY_AS_NEW_TOPIC_KEY = "reply_as_new_topic", + // The actions the composer can take + CREATE_TOPIC = 'createTopic', + PRIVATE_MESSAGE = 'privateMessage', + REPLY = 'reply', + EDIT = 'edit', + REPLY_AS_NEW_TOPIC_KEY = "reply_as_new_topic", - // When creating, these fields are moved into the post model from the composer model - _create_serializer = { - raw: 'reply', - title: 'title', - category: 'categoryId', - topic_id: 'topic.id', - is_warning: 'isWarning', - archetype: 'archetypeId', - target_usernames: 'targetUsernames' - }, + // When creating, these fields are moved into the post model from the composer model + _create_serializer = { + raw: 'reply', + title: 'title', + category: 'categoryId', + topic_id: 'topic.id', + is_warning: 'isWarning', + archetype: 'archetypeId', + target_usernames: 'targetUsernames' + }, - _edit_topic_serializer = { - title: 'topic.title', - categoryId: 'topic.category.id' - }; + _edit_topic_serializer = { + title: 'topic.title', + categoryId: 'topic.category.id' + }; -Discourse.Composer = Discourse.Model.extend({ +const Composer = Discourse.Model.extend({ archetypes: function() { return Discourse.Site.currentProp('archetypes'); @@ -46,7 +46,6 @@ Discourse.Composer = Discourse.Model.extend({ viewOpen: Em.computed.equal('composeState', OPEN), viewDraft: Em.computed.equal('composeState', DRAFT), - archetype: function() { return this.get('archetypes').findProperty('id', this.get('archetypeId')); }.property('archetypeId'), @@ -61,18 +60,18 @@ Discourse.Composer = Discourse.Model.extend({ // Determine the appropriate title for this action actionTitle: function() { - var topic = this.get('topic'); + const topic = this.get('topic'); - var postLink, topicLink; + let postLink, topicLink; if (topic) { - var postNumber = this.get('post.post_number'); + const postNumber = this.get('post.post_number'); postLink = "" + I18n.t("post.post_number", { number: postNumber }) + ""; topicLink = " " + (Handlebars.Utils.escapeExpression(topic.get('title'))) + ""; } - var postDescription, - post = this.get('post'); + let postDescription; + const post = this.get('post'); if (post) { postDescription = I18n.t('post.' + this.get('action'), { @@ -82,8 +81,8 @@ Discourse.Composer = Discourse.Model.extend({ }); if (!Discourse.Mobile.mobileView) { - var replyUsername = post.get('reply_to_user.username'); - var replyAvatarTemplate = post.get('reply_to_user.avatar_template'); + const replyUsername = post.get('reply_to_user.username'); + const replyAvatarTemplate = post.get('reply_to_user.avatar_template'); if (replyUsername && replyAvatarTemplate && this.get('action') === EDIT) { postDescription += " " + I18n.t("post.in_reply_to") + " " + Discourse.Utilities.tinyAvatar(replyAvatarTemplate) + " " + replyUsername; } @@ -164,7 +163,7 @@ Discourse.Composer = Discourse.Model.extend({ }.property('action'), hasMetaData: function() { - var metaData = this.get('metaData'); + const metaData = this.get('metaData'); return metaData ? Em.isEmpty(Em.keys(this.get('metaData'))) : false; }.property('metaData'), @@ -227,7 +226,7 @@ Discourse.Composer = Discourse.Model.extend({ @property titleLength **/ titleLength: function() { - var title = this.get('title') || ""; + const title = this.get('title') || ""; return title.replace(/\s+/img, " ").trim().length; }.property('title'), @@ -237,17 +236,16 @@ Discourse.Composer = Discourse.Model.extend({ @property replyLength **/ replyLength: function() { - var reply = this.get('reply') || ""; + let reply = this.get('reply') || ""; while (Discourse.Quote.REGEXP.test(reply)) { reply = reply.replace(Discourse.Quote.REGEXP, ""); } return reply.replace(/\s+/img, " ").trim().length; }.property('reply'), - init: function() { - this._super(); - var val = (Discourse.Mobile.mobileView ? false : (Discourse.KeyValueStore.get('composer.showPreview') || 'true')); + _setupComposer: function() { + const val = (Discourse.Mobile.mobileView ? false : (Discourse.KeyValueStore.get('composer.showPreview') || 'true')); this.set('showPreview', val === 'true'); this.set('archetypeId', Discourse.Site.currentProp('default_archetype')); - }, + }.on('init'), /** Append text to the current reply @@ -255,17 +253,16 @@ Discourse.Composer = Discourse.Model.extend({ @method appendText @param {String} text the text to append **/ - appendText: function(text,position,opts) { - var reply = (this.get('reply') || ''); + appendText(text,position,opts) { + const reply = (this.get('reply') || ''); position = typeof(position) === "number" ? position : reply.length; - var before = reply.slice(0, position) || ''; - var after = reply.slice(position) || ''; + let before = reply.slice(0, position) || ''; + let after = reply.slice(position) || ''; - var stripped, i; - - if(opts && opts.block){ - if(before.trim() !== ""){ + let stripped, i; + if (opts && opts.block){ + if (before.trim() !== ""){ stripped = before.replace(/\r/g, ""); for(i=0; i<2; i++){ if(stripped[stripped.length - 1 - i] !== "\n"){ @@ -298,7 +295,7 @@ Discourse.Composer = Discourse.Model.extend({ return before.length + text.length; }, - togglePreview: function() { + togglePreview() { this.toggleProperty('showPreview'); Discourse.KeyValueStore.set({ key: 'composer.showPreview', value: this.get('showPreview') }); }, @@ -312,13 +309,13 @@ Discourse.Composer = Discourse.Model.extend({ topic - The topic we're replying to, if present quote - If we're opening a reply from a quote, the quote we're making */ - open: function(opts) { + open(opts) { if (!opts) opts = {}; this.set('loading', false); - var replyBlank = Em.isEmpty(this.get("reply")); + const replyBlank = Em.isEmpty(this.get("reply")); - var composer = this; + const composer = this; if (!replyBlank && (opts.action !== this.get('action') || ((opts.reply || opts.action === this.EDIT) && this.get('reply') !== this.get('originalText'))) && !opts.tested) { @@ -363,7 +360,7 @@ Discourse.Composer = Discourse.Model.extend({ // If we are editing a post, load it. if (opts.action === EDIT && opts.post) { - var topicProps = this.serialize(_edit_topic_serializer); + const topicProps = this.serialize(_edit_topic_serializer); topicProps.loading = true; this.setProperties(topicProps); @@ -387,7 +384,7 @@ Discourse.Composer = Discourse.Model.extend({ return false; }, - save: function(opts) { + save(opts) { if( !this.get('cantSubmitPost') ) { return this.get('editingPost') ? this.editPost(opts) : this.createPost(opts); } @@ -398,7 +395,7 @@ Discourse.Composer = Discourse.Model.extend({ @method clearState **/ - clearState: function() { + clearState() { this.setProperties({ originalText: null, reply: null, @@ -410,11 +407,11 @@ Discourse.Composer = Discourse.Model.extend({ }, // When you edit a post - editPost: function(opts) { - var post = this.get('post'), + editPost(opts) { + const post = this.get('post'), oldCooked = post.get('cooked'), - self = this, - promise; + self = this; + let promise; // Update the title if we've changed it, otherwise consider it a // successful resolved promise @@ -422,7 +419,7 @@ Discourse.Composer = Discourse.Model.extend({ post.get('post_number') === 1 && this.get('topic.details.can_edit')) { - var topicProps = this.getProperties(Object.keys(_edit_topic_serializer)); + const topicProps = this.getProperties(Object.keys(_edit_topic_serializer)); promise = Discourse.Topic.update(this.get('topic'), topicProps); } else { promise = Ember.RSVP.resolve(); @@ -441,7 +438,7 @@ Discourse.Composer = Discourse.Model.extend({ post.updateFromPost(result); self.clearState(); }).catch(function(error) { - var response = $.parseJSON(error.responseText); + const response = $.parseJSON(error.responseText); if (response && response.errors) { return(response.errors[0]); } else { @@ -453,14 +450,14 @@ Discourse.Composer = Discourse.Model.extend({ }); }, - serialize: function(serializer, dest) { + serialize(serializer, dest) { if (!dest) { dest = {}; } - var self = this; + const self = this; Object.keys(serializer).forEach(function(f) { - var val = self.get(serializer[f]); + const val = self.get(serializer[f]); if (typeof val !== 'undefined') { Ember.set(dest, f, val); } @@ -469,15 +466,15 @@ Discourse.Composer = Discourse.Model.extend({ }, // Create a new Post - createPost: function(opts) { - var post = this.get('post'), + createPost(opts) { + const post = this.get('post'), topic = this.get('topic'), currentUser = Discourse.User.current(), - postStream = this.get('topic.postStream'), - addedToStream = false; + postStream = this.get('topic.postStream'); + let addedToStream = false; // Build the post object - var createdPost = Discourse.Post.create({ + const createdPost = Discourse.Post.create({ imageSizes: opts.imageSizes, cooked: this.getCookedHtml(), reply_count: 0, @@ -509,7 +506,7 @@ Discourse.Composer = Discourse.Model.extend({ }); } - var state = null; + let state = null; // If we're in a topic, we can append the post instantly. if (postStream) { @@ -533,12 +530,12 @@ Discourse.Composer = Discourse.Model.extend({ } } - var composer = this; - var promise = new Ember.RSVP.Promise(function(resolve, reject) { + const composer = this; + const promise = new Ember.RSVP.Promise(function(resolve, reject) { composer.set('composeState', SAVING); createdPost.save(function(result) { - var saving = true; + let saving = true; createdPost.updateFromJson(result); @@ -555,7 +552,7 @@ Discourse.Composer = Discourse.Model.extend({ saving = false; // Update topic_count for the category - var category = Discourse.Site.currentProp('categories').find(function(x) { return x.get('id') === (parseInt(createdPost.get('category'),10) || 1); }); + const category = Discourse.Site.currentProp('categories').find(function(x) { return x.get('id') === (parseInt(createdPost.get('category'),10) || 1); }); if (category) category.incrementProperty('topic_count'); Discourse.notifyPropertyChange('globalNotice'); } @@ -578,9 +575,9 @@ Discourse.Composer = Discourse.Model.extend({ composer.set('composeState', OPEN); // TODO extract error handling code - var parsedError; + let parsedError; try { - var parsedJSON = $.parseJSON(error.responseText); + const parsedJSON = $.parseJSON(error.responseText); if (parsedJSON.errors) { parsedError = parsedJSON.errors[0]; } else if (parsedJSON.failed) { @@ -599,11 +596,11 @@ Discourse.Composer = Discourse.Model.extend({ return promise; }, - getCookedHtml: function() { + getCookedHtml() { return $('#wmd-preview').html().replace(/<\/span>/g, ''); }, - saveDraft: function() { + saveDraft() { // Do not save when drafts are disabled if (this.get('disableDrafts')) return; // Do not save when there is no reply @@ -611,7 +608,7 @@ Discourse.Composer = Discourse.Model.extend({ // Do not save when the reply's length is too small if (this.get('replyLength') < Discourse.SiteSettings.min_post_length) return; - var data = { + const data = { reply: this.get('reply'), action: this.get('action'), title: this.get('title'), @@ -624,7 +621,7 @@ Discourse.Composer = Discourse.Model.extend({ this.set('draftStatus', I18n.t('composer.saving_draft_tip')); - var composer = this; + const composer = this; // try to save the draft return Discourse.Draft.save(this.get('draftKey'), this.get('draftSequence'), data) @@ -637,16 +634,21 @@ Discourse.Composer = Discourse.Model.extend({ }); -Discourse.Composer.reopenClass({ +Composer.reopenClass({ - open: function(opts) { - var composer = Discourse.Composer.create(); + open(opts) { + const composer = Composer.create(); composer.open(opts); return composer; }, - loadDraft: function(draftKey, draftSequence, draft, topic) { - var composer; + loadDraft(opts) { + opts = opts || {}; + + let draft = opts.draft; + const draftKey = opts.draftKey; + const draftSequence = opts.draftSequence; + try { if (draft && typeof draft === 'string') { draft = JSON.parse(draft); @@ -656,13 +658,12 @@ Discourse.Composer.reopenClass({ Discourse.Draft.clear(draftKey, draftSequence); } if (draft && ((draft.title && draft.title !== '') || (draft.reply && draft.reply !== ''))) { - composer = this.open({ - draftKey: draftKey, - draftSequence: draftSequence, - topic: topic, + return this.open({ + draftKey, + draftSequence, action: draft.action, title: draft.title, - categoryId: draft.categoryId, + categoryId: draft.categoryId || opts.categoryId, postId: draft.postId, archetypeId: draft.archetypeId, reply: draft.reply, @@ -672,35 +673,36 @@ Discourse.Composer.reopenClass({ composerState: DRAFT }); } - return composer; }, - serializeToTopic: function(fieldName, property) { + serializeToTopic(fieldName, property) { if (!property) { property = fieldName; } _edit_topic_serializer[fieldName] = property; }, - serializeOnCreate: function(fieldName, property) { + serializeOnCreate(fieldName, property) { if (!property) { property = fieldName; } _create_serializer[fieldName] = property; }, - serializedFieldsForCreate: function() { + serializedFieldsForCreate() { return Object.keys(_create_serializer); }, // The status the compose view can have - CLOSED: CLOSED, - SAVING: SAVING, - OPEN: OPEN, - DRAFT: DRAFT, + CLOSED, + SAVING, + OPEN, + DRAFT, // The actions the composer can take - CREATE_TOPIC: CREATE_TOPIC, - PRIVATE_MESSAGE: PRIVATE_MESSAGE, - REPLY: REPLY, - EDIT: EDIT, + CREATE_TOPIC, + PRIVATE_MESSAGE, + REPLY, + EDIT, // Draft key - REPLY_AS_NEW_TOPIC_KEY: REPLY_AS_NEW_TOPIC_KEY + REPLY_AS_NEW_TOPIC_KEY }); + +export default Composer;