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:
Robin Ward 2014-08-15 16:39:34 -04:00
parent 0ce2df36e0
commit aa41548e8e
17 changed files with 172 additions and 11 deletions

View File

@ -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()
});
}
});

View File

@ -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);
}
}
});

View File

@ -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'));
}
}
});

View File

@ -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

View File

@ -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');
},
/**

View File

@ -5,4 +5,5 @@
</div>
{{render "modal"}}
{{render "topic-entrance"}}
{{render "composer"}}

View File

@ -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>

View File

@ -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}}

View File

@ -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"}}

View File

@ -1 +1,4 @@
{{basic-topic-list topicList=model hideCategory=hideCategory showParticipants=showParticipants}}
{{basic-topic-list topicList=model
hideCategory=hideCategory
showParticipants=showParticipants
activityAction="showTopicEntrance"}}

View File

@ -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>

View File

@ -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>

View 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'),
});

View File

@ -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. */

View 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;
}
}

View File

@ -138,6 +138,9 @@
}
.activity {
width: 60px;
span {
cursor: pointer;
}
}
.age {
width: 60px;

View File

@ -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: