mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 23:16:20 +08:00
UX: When clicking an activity date, pop up a little menu with options to
go to beginning or end of the topic.
This commit is contained in:
parent
0ce2df36e0
commit
aa41548e8e
|
@ -32,14 +32,25 @@ export default Ember.Component.extend({
|
|||
}.property('bumpedAt', 'createdAt'),
|
||||
|
||||
title: function() {
|
||||
// return {{i18n last_post}}: {{{raw-date topic.bumped_at}}}
|
||||
return I18n.t('first_post') + ": " + Discourse.Formatter.longDate(this.get('createdAt')) + "\n" +
|
||||
I18n.t('last_post') + ": " + Discourse.Formatter.longDate(this.get('bumpedAt'));
|
||||
}.property('bumpedAt', 'createdAt'),
|
||||
|
||||
render: function(buffer) {
|
||||
buffer.push('<a href="' + this.get('topic.lastPostUrl') + '">');
|
||||
buffer.push(Discourse.Formatter.autoUpdatingRelativeAge(this.get('bumpedAt')));
|
||||
buffer.push("</a>");
|
||||
},
|
||||
|
||||
click: function() {
|
||||
var topic = this.get('topic');
|
||||
|
||||
if (Discourse.Mobile.mobileView) {
|
||||
Discourse.URL.routeTo(topic.get('lastPostUrl'));
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendAction('action', {
|
||||
topic: topic,
|
||||
position: this.$('span').position()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -37,6 +37,12 @@ export default Ember.Component.extend({
|
|||
// Without a topic list, we assume it's loaded always.
|
||||
this.set('loaded', true);
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
clickedActivity: function(data) {
|
||||
this.sendAction('activityAction', data);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
function entranceDate(dt) {
|
||||
var bumpedAt = new Date(dt),
|
||||
today = new Date();
|
||||
|
||||
if (bumpedAt.getDate() === today.getDate()) {
|
||||
return moment(bumpedAt).format(I18n.t("dates.time"));
|
||||
}
|
||||
|
||||
if (bumpedAt.getYear() === today.getYear()) {
|
||||
return moment(bumpedAt).format(I18n.t("dates.long_no_year"));
|
||||
}
|
||||
|
||||
return moment(bumpedAt).format(I18n.t('dates.long_with_year'));
|
||||
}
|
||||
|
||||
export default Ember.ObjectController.extend({
|
||||
position: null,
|
||||
|
||||
topDate: function() {
|
||||
return entranceDate(this.get('created_at'));
|
||||
}.property('model.created_at'),
|
||||
|
||||
bottomDate: function() {
|
||||
return entranceDate(this.get('bumped_at'));
|
||||
}.property('model.bumped_at'),
|
||||
|
||||
actions: {
|
||||
show: function(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: function() {
|
||||
Discourse.URL.routeTo(this.get('url'));
|
||||
},
|
||||
|
||||
enterBottom: function() {
|
||||
Discourse.URL.routeTo(this.get('lastPostUrl'));
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,6 +1,10 @@
|
|||
var ApplicationRoute = Em.Route.extend({
|
||||
|
||||
actions: {
|
||||
showTopicEntrance: function(data) {
|
||||
this.controllerFor('topic-entrance').send('show', data);
|
||||
},
|
||||
|
||||
error: function(err, transition) {
|
||||
if (err.status === 404) {
|
||||
// 404
|
||||
|
|
|
@ -77,6 +77,10 @@ Discourse.Route.reopenClass({
|
|||
$('#discourse-modal').modal('hide');
|
||||
var hideDropDownFunction = $('html').data('hide-dropdown');
|
||||
if (hideDropDownFunction) { hideDropDownFunction(); }
|
||||
|
||||
// TODO: Avoid container lookup here
|
||||
var appEvents = Discourse.__container__.lookup('app-events:main');
|
||||
appEvents.trigger('dom:clean');
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,4 +5,5 @@
|
|||
</div>
|
||||
|
||||
{{render "modal"}}
|
||||
{{render "topic-entrance"}}
|
||||
{{render "composer"}}
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
{{number topic.views numberKey="views_long"}}
|
||||
</td>
|
||||
|
||||
{{activity-column topic=topic class="num"}}
|
||||
{{activity-column topic=topic class="num" action="clickedActivity"}}
|
||||
</tr>
|
||||
{{/grouped-each}}
|
||||
</tbody>
|
||||
|
|
|
@ -5,28 +5,28 @@
|
|||
{{#if content.yearly}}
|
||||
<div class="clearfix">
|
||||
<h2><i class="fa fa-calendar-o"></i> {{i18n filters.top.this_year}}</h2>
|
||||
{{basic-topic-list topicList=content.yearly hideCategory=hideCategory}}
|
||||
{{basic-topic-list topicList=content.yearly hideCategory=hideCategory activityAction="showTopicEntrance"}}
|
||||
{{#if content.yearly.topics.length}}<a href="{{unbound showMoreYearlyUrl}}" class='btn btn-default pull-right'>{{i18n show_more}}</a>{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if content.monthly}}
|
||||
<div class="clearfix">
|
||||
<h2><i class="fa fa-calendar-o"></i> {{i18n filters.top.this_month}}</h2>
|
||||
{{basic-topic-list topicList=content.monthly hideCategory=hideCategory}}
|
||||
{{basic-topic-list topicList=content.monthly hideCategory=hideCategory activityAction="showTopicEntrance"}}
|
||||
{{#if content.monthly.topics.length}}<a href="{{unbound showMoreMonthlyUrl}}" class='btn btn-default pull-right'>{{i18n show_more}}</a>{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if content.weekly}}
|
||||
<div class="clearfix">
|
||||
<h2><i class="fa fa-calendar-o"></i> {{i18n filters.top.this_week}}</h2>
|
||||
{{basic-topic-list topicList=content.weekly hideCategory=hideCategory}}
|
||||
{{basic-topic-list topicList=content.weekly hideCategory=hideCategory activityAction="showTopicEntrance"}}
|
||||
{{#if content.weekly.topics.length}}<a href="{{unbound showMoreWeeklyUrl}}" class='btn btn-default pull-right'>{{i18n show_more}}</a>{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if content.daily}}
|
||||
<div class="clearfix">
|
||||
<h2><i class="fa fa-calendar-o"></i> {{i18n filters.top.today}}</h2>
|
||||
{{basic-topic-list topicList=content.daily hideCategory=hideCategory}}
|
||||
{{basic-topic-list topicList=content.daily hideCategory=hideCategory activityAction="showTopicEntrance"}}
|
||||
{{#if content.daily.topics.length}}<a href="{{unbound showMoreDailyUrl}}" class='btn btn-default pull-right'>{{i18n show_more}}</a>{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -49,4 +49,4 @@
|
|||
{{posts-count-column topic=model class="num"}}
|
||||
<td {{bind-attr class=":num :views viewsHeat"}}>{{number views numberKey="views_long"}}</td>
|
||||
|
||||
{{activity-column topic=model class="num"}}
|
||||
{{activity-column topic=model class="num" action="showTopicEntrance"}}
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
{{basic-topic-list topicList=model hideCategory=hideCategory showParticipants=showParticipants}}
|
||||
{{basic-topic-list topicList=model
|
||||
hideCategory=hideCategory
|
||||
showParticipants=showParticipants
|
||||
activityAction="showTopicEntrance"}}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<button {{action enterTop}} class='btn full no-text'>
|
||||
<i class='fa fa-caret-up'></i> {{topDate}}
|
||||
</button>
|
||||
<button {{action enterBottom}} class='btn full no-text jump-bottom'>
|
||||
<i class='fa fa-caret-down'></i> {{bottomDate}}
|
||||
</button>
|
|
@ -102,7 +102,7 @@
|
|||
<div id='suggested-topics'>
|
||||
<h3>{{i18n suggested_topics.title}}</h3>
|
||||
<div class='topics'>
|
||||
{{basic-topic-list topics=details.suggested_topics}}
|
||||
{{basic-topic-list topics=details.suggested_topics activityAction="showTopicEntrance"}}
|
||||
</div>
|
||||
<h3>{{{view.browseMoreMessage}}}</h3>
|
||||
</div>
|
||||
|
|
50
app/assets/javascripts/discourse/views/topic-entrance.js.es6
Normal file
50
app/assets/javascripts/discourse/views/topic-entrance.js.es6
Normal file
|
@ -0,0 +1,50 @@
|
|||
export default Ember.View.extend({
|
||||
elementId: 'topic-entrance',
|
||||
classNameBindings: ['visible::hidden'],
|
||||
visible: Em.computed.notEmpty('controller.model'),
|
||||
|
||||
_positionChanged: function() {
|
||||
var pos = this.get('controller.position');
|
||||
if (!pos) { return; }
|
||||
|
||||
var $self = this.$();
|
||||
|
||||
// Move after we render so the height is correct
|
||||
Em.run.schedule('afterRender', function() {
|
||||
var width = $self.width(),
|
||||
height = $self.height();
|
||||
pos.left = (parseInt(pos.left) - (width / 2));
|
||||
pos.top = (parseInt(pos.top) - (height / 2));
|
||||
|
||||
var windowWidth = $(window).width();
|
||||
if (pos.left + width > windowWidth) {
|
||||
pos.left = (windowWidth - width) - 5;
|
||||
}
|
||||
$self.css(pos);
|
||||
});
|
||||
|
||||
var self = this;
|
||||
$('html').off('mousedown.topic-entrance').on('mousedown.topic-entrance', function(e) {
|
||||
var $target = $(e.target);
|
||||
if (($target.prop('id') === 'topic-entrance') || ($self.has($target).length !== 0)) {
|
||||
return;
|
||||
}
|
||||
self._cleanUp();
|
||||
});
|
||||
}.observes('controller.position'),
|
||||
|
||||
_removed: function() {
|
||||
$('html').off('mousedown.topic-entrance');
|
||||
this.appEvents.off('dom:clean', this, '_cleanUp');
|
||||
}.on('willDestroyElement'),
|
||||
|
||||
_cleanUp: function() {
|
||||
this.set('controller.model', null);
|
||||
$('html').off('mousedown.topic-entrance');
|
||||
},
|
||||
|
||||
_wireClean: function() {
|
||||
this.appEvents.on('dom:clean', this, '_cleanUp');
|
||||
}.on('didInsertElement'),
|
||||
|
||||
});
|
|
@ -15,6 +15,7 @@
|
|||
@import "desktop/topic";
|
||||
@import "desktop/upload";
|
||||
@import "desktop/user";
|
||||
@import "desktop/topic-entrance";
|
||||
|
||||
/* These files doesn't actually exist, they are injected by DiscourseSassImporter. */
|
||||
|
||||
|
|
25
app/assets/stylesheets/desktop/topic-entrance.scss
Normal file
25
app/assets/stylesheets/desktop/topic-entrance.scss
Normal file
|
@ -0,0 +1,25 @@
|
|||
#topic-entrance {
|
||||
border: 1px solid scale-color-diff();
|
||||
padding: 5px;
|
||||
background: $secondary;
|
||||
@include box-shadow(0 0px 2px rgba(0,0,0, .2));
|
||||
z-index: 100;
|
||||
|
||||
position: absolute;
|
||||
width: 133px;
|
||||
padding: 5px;
|
||||
|
||||
button.full {
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
i {
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
button.btn.jump-bottom {
|
||||
margin: 5px 0 0 0;
|
||||
}
|
||||
}
|
|
@ -138,6 +138,9 @@
|
|||
}
|
||||
.activity {
|
||||
width: 60px;
|
||||
span {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.age {
|
||||
width: 60px;
|
||||
|
|
|
@ -30,6 +30,9 @@ en:
|
|||
mb: MB
|
||||
tb: TB
|
||||
dates:
|
||||
time: "h:mm a"
|
||||
long_no_year: "MMM DD h:mm a"
|
||||
long_with_year: "MMM DD, YYYY h:mm a"
|
||||
tiny:
|
||||
half_a_minute: "< 1m"
|
||||
less_than_x_seconds:
|
||||
|
|
Loading…
Reference in New Issue
Block a user