diff --git a/app/assets/javascripts/discourse/components/basic-topic-list.js.es6 b/app/assets/javascripts/discourse/components/basic-topic-list.js.es6 index d7cdc327445..ac358350a91 100644 --- a/app/assets/javascripts/discourse/components/basic-topic-list.js.es6 +++ b/app/assets/javascripts/discourse/components/basic-topic-list.js.es6 @@ -48,7 +48,7 @@ export default Ember.Component.extend({ } const topic = this.get('topics').findBy('id', parseInt(topicId)); - this.sendAction('postsAction', {topic, position: target.offset()}); + this.appEvents.trigger('topic-entrance:show', { topic, position: target.offset() }); } return false; } diff --git a/app/assets/javascripts/discourse/components/featured-topic.js.es6 b/app/assets/javascripts/discourse/components/featured-topic.js.es6 index def196f7a1d..f000172e6a5 100644 --- a/app/assets/javascripts/discourse/components/featured-topic.js.es6 +++ b/app/assets/javascripts/discourse/components/featured-topic.js.es6 @@ -4,7 +4,7 @@ export default Ember.Component.extend({ click(e) { const $target = $(e.target); if ($target.closest('.last-posted-at').length) { - this.sendAction('action', {topic: this.get('topic'), position: $target.offset()}); + this.appEvents.trigger('topic-entrance:show', {topic: this.get('topic'), position: $target.offset()}); return false; } } diff --git a/app/assets/javascripts/discourse/components/topic-entrance.js.es6 b/app/assets/javascripts/discourse/components/topic-entrance.js.es6 new file mode 100644 index 00000000000..d3b5983ce43 --- /dev/null +++ b/app/assets/javascripts/discourse/components/topic-entrance.js.es6 @@ -0,0 +1,104 @@ +import DiscourseURL from 'discourse/lib/url'; +import CleansUp from 'discourse/mixins/cleans-up'; +import computed from 'ember-addons/ember-computed-decorators'; + +function entranceDate(dt, showTime) { + const today = new Date(); + + if (dt.toDateString() === today.toDateString()) { + return moment(dt).format(I18n.t("dates.time")); + } + + if (dt.getYear() === today.getYear()) { + // No year + return moment(dt).format( + showTime ? I18n.t("dates.long_date_without_year_with_linebreak") : I18n.t("dates.long_no_year_no_time") + ); + } + + return moment(dt).format( + showTime ? I18n.t('dates.long_date_with_year_with_linebreak') : I18n.t('dates.long_date_with_year_without_time') + ); +} + +export default Ember.Component.extend(CleansUp, { + elementId: 'topic-entrance', + classNameBindings: ['visible::hidden'], + _position: null, + topic: null, + visible: null, + + @computed('topic.created_at') + createdDate: createdAt => new Date(createdAt), + + @computed('topic.bumped_at') + bumpedDate: bumpedAt => new Date(bumpedAt), + + @computed('createdDate', 'bumpedDate') + showTime(createdDate, bumpedDate) { + return bumpedDate.getTime() - createdDate.getTime() < (1000 * 60 * 60 * 24 * 2); + }, + + @computed('createdDate', 'showTime') + topDate: (createdDate, showTime) => entranceDate(createdDate, showTime), + + @computed('bumpedDate', 'showTime') + bottomDate: (bumpedDate, showTime) => entranceDate(bumpedDate, showTime), + + didInsertElement() { + this._super(); + this.appEvents.on('topic-entrance:show', data => this._show(data)); + }, + + _setCSS() { + const pos = this._position; + const $self = this.$(); + const width = $self.width(); + const height = $self.height(); + pos.left = (parseInt(pos.left) - (width / 2)); + pos.top = (parseInt(pos.top) - (height / 2)); + + const windowWidth = $(window).width(); + if (pos.left + width > windowWidth) { + pos.left = (windowWidth - width) - 15; + } + $self.css(pos); + }, + + _show(data) { + this._position = data.position; + + this.set('topic', data.topic); + this.set('visible', true); + + Ember.run.scheduleOnce('afterRender', this, this._setCSS); + + $('html').off('mousedown.topic-entrance').on('mousedown.topic-entrance', e => { + const $target = $(e.target); + if (($target.prop('id') === 'topic-entrance') || (this.$().has($target).length !== 0)) { + return; + } + this.cleanUp(); + }); + }, + + cleanUp() { + this.set('topic', null); + this.set('visible', false); + $('html').off('mousedown.topic-entrance'); + }, + + willDestroyElement() { + this.appEvents.off('topic-entrance:show'); + }, + + actions: { + enterTop() { + DiscourseURL.routeTo(this.get('topic.url')); + }, + + enterBottom() { + DiscourseURL.routeTo(this.get('topic.lastPostUrl')); + } + } +}); diff --git a/app/assets/javascripts/discourse/components/topic-list-item.js.es6 b/app/assets/javascripts/discourse/components/topic-list-item.js.es6 index d9b8569bb87..a38dd9c8f4c 100644 --- a/app/assets/javascripts/discourse/components/topic-list-item.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-list-item.js.es6 @@ -12,7 +12,8 @@ export function showEntrance(e) { target = target.end(); } } - getOwner(this).lookup('controller:application').send("showTopicEntrance", {topic: this.get('topic'), position: target.offset()}); + + this.appEvents.trigger('topic-entrance:show', { topic: this.get('topic'), position: target.offset() }); return false; } } diff --git a/app/assets/javascripts/discourse/controllers/topic-entrance.js.es6 b/app/assets/javascripts/discourse/controllers/topic-entrance.js.es6 deleted file mode 100644 index 4a7fdf61c61..00000000000 --- a/app/assets/javascripts/discourse/controllers/topic-entrance.js.es6 +++ /dev/null @@ -1,63 +0,0 @@ -import DiscourseURL from 'discourse/lib/url'; - -function entranceDate(dt, showTime) { - const today = new Date(); - - if (dt.toDateString() === today.toDateString()) { - return moment(dt).format(I18n.t("dates.time")); - } - - if (dt.getYear() === today.getYear()) { - // No year - return moment(dt).format( - showTime ? I18n.t("dates.long_date_without_year_with_linebreak") : I18n.t("dates.long_no_year_no_time") - ); - } - - return moment(dt).format( - showTime ? I18n.t('dates.long_date_with_year_with_linebreak') : I18n.t('dates.long_date_with_year_without_time') - ); -} - -export default Ember.Controller.extend({ - position: null, - - createdDate: function() { - return new Date(this.get('model.created_at')); - }.property('model.created_at'), - - bumpedDate: function() { - return new Date(this.get('model.bumped_at')); - }.property('model.bumped_at'), - - showTime: function() { - var diffMs = this.get('bumpedDate').getTime() - this.get('createdDate').getTime(); - return diffMs < (1000 * 60 * 60 * 24 * 2); - }.property('createdDate', 'bumpedDate'), - - topDate: function() { - return entranceDate(this.get('createdDate'), this.get('showTime')); - }.property('createdDate'), - - bottomDate: function() { - return entranceDate(this.get('bumpedDate'), this.get('showTime')); - }.property('bumpedDate'), - - actions: { - show(data) { - // Show the chooser but only if the model changes - if (this.get('model') !== data.topic) { - this.set('model', data.topic); - this.set('position', data.position); - } - }, - - enterTop() { - DiscourseURL.routeTo(this.get('model.url')); - }, - - enterBottom() { - DiscourseURL.routeTo(this.get('model.lastPostUrl')); - } - } -}); diff --git a/app/assets/javascripts/discourse/routes/application.js.es6 b/app/assets/javascripts/discourse/routes/application.js.es6 index fab8595cd3d..e2c3aa3f6aa 100644 --- a/app/assets/javascripts/discourse/routes/application.js.es6 +++ b/app/assets/javascripts/discourse/routes/application.js.es6 @@ -46,10 +46,6 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, { return this._super(); }, - showTopicEntrance(data) { - this.controllerFor('topic-entrance').send('show', data); - }, - postWasEnqueued(details) { const title = details.reason ? 'queue_reason.' + details.reason + '.title' : 'queue.approval.title'; showModal('post-enqueued', {model: details, title }); @@ -177,7 +173,6 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, { this.render('application'); this.render('user-card', { into: 'application', outlet: 'user-card' }); this.render('modal', { into: 'application', outlet: 'modal' }); - this.render('topic-entrance', { into: 'application', outlet: 'topic-entrance' }); this.render('composer', { into: 'application', outlet: 'composer' }); }, diff --git a/app/assets/javascripts/discourse/templates/application.hbs b/app/assets/javascripts/discourse/templates/application.hbs index 5a013ead74e..8a074e2eb37 100644 --- a/app/assets/javascripts/discourse/templates/application.hbs +++ b/app/assets/javascripts/discourse/templates/application.hbs @@ -27,5 +27,5 @@ {{plugin-outlet "below-footer"}} {{outlet "modal"}} -{{outlet "topic-entrance"}} +{{topic-entrance}} {{outlet "composer"}} diff --git a/app/assets/javascripts/discourse/templates/components/categories-only.hbs b/app/assets/javascripts/discourse/templates/components/categories-only.hbs index f8fafb5d154..6f6a674c51d 100644 --- a/app/assets/javascripts/discourse/templates/components/categories-only.hbs +++ b/app/assets/javascripts/discourse/templates/components/categories-only.hbs @@ -38,9 +38,7 @@ {{#if showTopics}}