mirror of
https://github.com/discourse/discourse.git
synced 2025-02-07 19:20:46 +08:00
Migrate the topic entrace to use a component
This commit is contained in:
parent
32a8d5ed1f
commit
684b3805fd
|
@ -48,7 +48,7 @@ export default Ember.Component.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
const topic = this.get('topics').findBy('id', parseInt(topicId));
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ export default Ember.Component.extend({
|
||||||
click(e) {
|
click(e) {
|
||||||
const $target = $(e.target);
|
const $target = $(e.target);
|
||||||
if ($target.closest('.last-posted-at').length) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -12,7 +12,8 @@ export function showEntrance(e) {
|
||||||
target = target.end();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -46,10 +46,6 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
|
||||||
return this._super();
|
return this._super();
|
||||||
},
|
},
|
||||||
|
|
||||||
showTopicEntrance(data) {
|
|
||||||
this.controllerFor('topic-entrance').send('show', data);
|
|
||||||
},
|
|
||||||
|
|
||||||
postWasEnqueued(details) {
|
postWasEnqueued(details) {
|
||||||
const title = details.reason ? 'queue_reason.' + details.reason + '.title' : 'queue.approval.title';
|
const title = details.reason ? 'queue_reason.' + details.reason + '.title' : 'queue.approval.title';
|
||||||
showModal('post-enqueued', {model: details, title });
|
showModal('post-enqueued', {model: details, title });
|
||||||
|
@ -177,7 +173,6 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
|
||||||
this.render('application');
|
this.render('application');
|
||||||
this.render('user-card', { into: 'application', outlet: 'user-card' });
|
this.render('user-card', { into: 'application', outlet: 'user-card' });
|
||||||
this.render('modal', { into: 'application', outlet: 'modal' });
|
this.render('modal', { into: 'application', outlet: 'modal' });
|
||||||
this.render('topic-entrance', { into: 'application', outlet: 'topic-entrance' });
|
|
||||||
this.render('composer', { into: 'application', outlet: 'composer' });
|
this.render('composer', { into: 'application', outlet: 'composer' });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,5 @@
|
||||||
{{plugin-outlet "below-footer"}}
|
{{plugin-outlet "below-footer"}}
|
||||||
|
|
||||||
{{outlet "modal"}}
|
{{outlet "modal"}}
|
||||||
{{outlet "topic-entrance"}}
|
{{topic-entrance}}
|
||||||
{{outlet "composer"}}
|
{{outlet "composer"}}
|
||||||
|
|
|
@ -38,9 +38,7 @@
|
||||||
{{#if showTopics}}
|
{{#if showTopics}}
|
||||||
<td class="latest">
|
<td class="latest">
|
||||||
{{#each c.featuredTopics as |t|}}
|
{{#each c.featuredTopics as |t|}}
|
||||||
{{featured-topic topic=t
|
{{featured-topic topic=t latestTopicOnly=latestTopicOnly}}
|
||||||
latestTopicOnly=latestTopicOnly
|
|
||||||
action="showTopicEntrance"}}
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</td>
|
</td>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -184,10 +184,9 @@
|
||||||
{{#if model.isPrivateMessage}}
|
{{#if model.isPrivateMessage}}
|
||||||
{{basic-topic-list hideCategory="true"
|
{{basic-topic-list hideCategory="true"
|
||||||
showPosters="true"
|
showPosters="true"
|
||||||
topics=model.details.suggested_topics
|
topics=model.details.suggested_topics}}
|
||||||
postsAction="showTopicEntrance"}}
|
|
||||||
{{else}}
|
{{else}}
|
||||||
{{basic-topic-list topics=model.details.suggested_topics postsAction="showTopicEntrance"}}
|
{{basic-topic-list topics=model.details.suggested_topics}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<h3>{{{browseMoreMessage}}}</h3>
|
<h3>{{{browseMoreMessage}}}</h3>
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
canBulkSelect=canBulkSelect
|
canBulkSelect=canBulkSelect
|
||||||
bulkSelectEnabled=bulkSelectEnabled
|
bulkSelectEnabled=bulkSelectEnabled
|
||||||
selected=selected
|
selected=selected
|
||||||
postsAction="showTopicEntrance"
|
|
||||||
skipHeader=true}}
|
skipHeader=true}}
|
||||||
|
|
||||||
{{conditional-loading-spinner condition=model.loadingMore}}
|
{{conditional-loading-spinner condition=model.loadingMore}}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
import CleansUp from 'discourse/mixins/cleans-up';
|
|
||||||
|
|
||||||
export default Ember.View.extend(CleansUp, {
|
|
||||||
elementId: 'topic-entrance',
|
|
||||||
classNameBindings: ['visible::hidden'],
|
|
||||||
visible: Em.computed.notEmpty('controller.model'),
|
|
||||||
|
|
||||||
_positionChanged: function() {
|
|
||||||
const pos = this.get('controller.position');
|
|
||||||
if (!pos) { return; }
|
|
||||||
|
|
||||||
const $self = this.$();
|
|
||||||
|
|
||||||
// Move after we render so the height is correct
|
|
||||||
Em.run.schedule('afterRender', function() {
|
|
||||||
const width = $self.width(),
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('html').off('mousedown.topic-entrance').on('mousedown.topic-entrance', e => {
|
|
||||||
const $target = $(e.target);
|
|
||||||
if (($target.prop('id') === 'topic-entrance') || ($self.has($target).length !== 0)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.cleanUp();
|
|
||||||
});
|
|
||||||
}.observes('controller.position'),
|
|
||||||
|
|
||||||
_removed: function() {
|
|
||||||
$('html').off('mousedown.topic-entrance');
|
|
||||||
}.on('willDestroyElement'),
|
|
||||||
|
|
||||||
cleanUp() {
|
|
||||||
this.set('controller.model', null);
|
|
||||||
$('html').off('mousedown.topic-entrance');
|
|
||||||
},
|
|
||||||
|
|
||||||
keyDown(e) {
|
|
||||||
if (e.which === 27) {
|
|
||||||
this.cleanUp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
Loading…
Reference in New Issue
Block a user