From da76dd3d6bc37648ac25dfd6d92cb03ed1ff8fd4 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 30 Dec 2016 11:46:09 -0500 Subject: [PATCH] REFACTOR: Cleaner `quoteButton` object, and some bug fixes --- .../discourse/components/quote-button.js.es6 | 26 ++++++++----- .../discourse/controllers/topic.js.es6 | 37 +++++++++---------- .../discourse/lib/quote-state.js.es6 | 15 ++++++++ .../javascripts/discourse/routes/topic.js.es6 | 2 +- .../javascripts/discourse/templates/topic.hbs | 4 +- 5 files changed, 50 insertions(+), 34 deletions(-) create mode 100644 app/assets/javascripts/discourse/lib/quote-state.js.es6 diff --git a/app/assets/javascripts/discourse/components/quote-button.js.es6 b/app/assets/javascripts/discourse/components/quote-button.js.es6 index 77a5c8192a2..97de8f927d8 100644 --- a/app/assets/javascripts/discourse/components/quote-button.js.es6 +++ b/app/assets/javascripts/discourse/components/quote-button.js.es6 @@ -1,4 +1,3 @@ -import computed from 'ember-addons/ember-computed-decorators'; import { selectedText } from 'discourse/lib/utilities'; // we don't want to deselect when we click on buttons that use it @@ -10,17 +9,22 @@ function willQuote(e) { export default Ember.Component.extend({ classNames: ['quote-button'], classNameBindings: ['visible'], - - @computed('quoteState.buffer') - visible: buffer => buffer && buffer.length > 0, + visible: false, _isMouseDown: false, _reselected: false, + _hideButton() { + this.get('quoteState').clear(); + this.set('visible', false); + }, + _selectionChanged() { + const quoteState = this.get('quoteState'); + const selection = window.getSelection(); if (selection.isCollapsed) { - if (this.get("visible")) this.sendAction("deselectText"); + if (this.get("visible")) { this._hideButton(); } return; } @@ -34,12 +38,13 @@ export default Ember.Component.extend({ postId = postId || $ancestor.closest('.boxed, .reply').data('post-id'); if ($ancestor.closest(".contents").length === 0 || !postId) { - if (this.get("visible")) this.sendAction("deselectText"); + if (this.get("visible")) { this._hideButton(); } return; } } - this.get("quoteState").setProperties({ postId, buffer: selectedText() }); + quoteState.selected(postId, selectedText()); + this.set('visible', quoteState.buffer.length > 0); // on Desktop, shows the button at the beginning of the selection // on Mobile, shows the button at the end of the selection @@ -97,11 +102,11 @@ export default Ember.Component.extend({ const wait = (isWinphone || isAndroid) ? 250 : 25; const onSelectionChanged = _.debounce(() => this._selectionChanged(), wait); - $(document).on("mousedown.quote-button", (e) => { + $(document).on("mousedown.quote-button", e => { this._isMouseDown = true; this._reselected = false; if (!willQuote(e)) { - this.sendAction("deselectText"); + this._hideButton(); } }).on("mouseup.quote-button", () => { this._isMouseDown = false; @@ -120,7 +125,8 @@ export default Ember.Component.extend({ }, click() { - this.sendAction("selectText"); + const { postId, buffer } = this.get('quoteState'); + this.attrs.selectText(postId, buffer).then(() => this._hideButton()); return false; } }); diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index ef4dfad0b63..89d11a01fc7 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -11,6 +11,7 @@ import { categoryBadgeHTML } from 'discourse/helpers/category-link'; import Post from 'discourse/models/post'; import debounce from 'discourse/lib/debounce'; import isElementInViewport from "discourse/lib/is-element-in-viewport"; +import QuoteState from 'discourse/lib/quote-state'; export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { composer: Ember.inject.controller(), @@ -119,7 +120,7 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { this._super(); this.set('selectedPosts', []); this.set('selectedReplies', []); - this.set('quoteState', Ember.Object.create({ buffer: null, postId: null })); + this.set('quoteState', new QuoteState()); }, showCategoryChooser: Ember.computed.not("model.isPrivateMessage"), @@ -167,16 +168,8 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { this.send('showFeatureTopic'); }, - deselectText() { - this.get('quoteState').setProperties({ buffer: null, postId: null }); - }, - - selectText() { - const { postId, buffer } = this.get('quoteState'); - - this.send('deselectText'); - - this.get('model.postStream').loadPost(postId).then(post => { + selectText(postId, buffer) { + return this.get('model.postStream').loadPost(postId).then(post => { // If we can't create a post, delegate to reply as new topic if (!this.get('model.details.can_create_post')) { this.send('replyAsNewTopic', post); @@ -196,15 +189,19 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { // If the composer is associated with a different post, we don't change it. const composer = this.get('composer'); - const composerPost = composer.get('content.post'); + const composerPost = composer.get('model.post'); if (composerPost && (composerPost.get('id') !== this.get('post.id'))) { composerOpts.post = composerPost; } const quotedText = Quote.build(post, buffer); composerOpts.quote = quotedText; - if (composer.get('content.viewOpen') || composer.get('content.viewDraft')) { + if (composer.get('model.viewOpen')) { this.appEvents.trigger('composer:insert-text', quotedText); + } else if (composer.get('model.viewDraft')) { + const model = composer.get('model'); + model.set('reply', model.get('reply') + quotedText); + composer.send('openIfDraft'); } else { composer.open(composerOpts); } @@ -314,9 +311,10 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { const quoteState = this.get('quoteState'); const postStream = this.get('model.postStream'); - const quotedPost = postStream.findLoadedPost(quoteState.get('postId')); - const quotedText = Quote.build(quotedPost, quoteState.get('buffer')); - this.send('deselectText'); + const quotedPost = postStream.findLoadedPost(quoteState.postId); + const quotedText = Quote.build(quotedPost, quoteState.buffer); + + quoteState.clear(); if (composerController.get('content.topic.id') === topic.get('id') && composerController.get('content.action') === Composer.REPLY) { @@ -652,10 +650,9 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { replyAsNewTopic(post) { const composerController = this.get('composer'); - const quoteState = this.get('quoteState'); - post = post || quoteState.get('post'); - const quotedText = Quote.build(post, quoteState.get('buffer')); - this.send('deselectText'); + const { quoteState } = this; + const quotedText = Quote.build(post, quoteState.buffer); + quoteState.clear(); composerController.open({ action: Composer.CREATE_TOPIC, diff --git a/app/assets/javascripts/discourse/lib/quote-state.js.es6 b/app/assets/javascripts/discourse/lib/quote-state.js.es6 new file mode 100644 index 00000000000..db1e1826fb1 --- /dev/null +++ b/app/assets/javascripts/discourse/lib/quote-state.js.es6 @@ -0,0 +1,15 @@ +export default class QuoteState { + constructor() { + this.clear(); + } + + selected(postId, buffer) { + this.postId = postId; + this.buffer = buffer; + } + + clear() { + this.buffer = ''; + this.postId = null; + } +} diff --git a/app/assets/javascripts/discourse/routes/topic.js.es6 b/app/assets/javascripts/discourse/routes/topic.js.es6 index 794c432a7b6..9cda61f8d7c 100644 --- a/app/assets/javascripts/discourse/routes/topic.js.es6 +++ b/app/assets/javascripts/discourse/routes/topic.js.es6 @@ -117,7 +117,6 @@ const TopicRoute = Discourse.Route.extend({ willTransition() { this._super(); - this.controllerFor("topic").send('deselectText'); Em.run.cancel(scheduledReplace); isTransitioning = true; return true; @@ -207,6 +206,7 @@ const TopicRoute = Discourse.Route.extend({ // close the multi select when switching topics controller.set('multiSelect', false); + controller.get('quoteState').clear(); this.controllerFor('composer').set('topic', model); this.topicTrackingState.trackIncoming('all'); diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs index 23d43fb907f..bd02891d6bc 100644 --- a/app/assets/javascripts/discourse/templates/topic.hbs +++ b/app/assets/javascripts/discourse/templates/topic.hbs @@ -273,8 +273,6 @@ {{share-popup topic=model replyAsNewTopic="replyAsNewTopic"}} {{#if currentUser.enable_quoting}} - {{quote-button quoteState=quoteState - selectText="selectText" - deselectText="deselectText"}} + {{quote-button quoteState=quoteState selectText=(action "selectText")}} {{/if}} {{/discourse-topic}}