diff --git a/app/assets/javascripts/discourse/components/activity-column.js.es6 b/app/assets/javascripts/discourse/components/activity-column.js.es6
index 3f17f5b427e..c0a5269759a 100644
--- a/app/assets/javascripts/discourse/components/activity-column.js.es6
+++ b/app/assets/javascripts/discourse/components/activity-column.js.es6
@@ -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('');
buffer.push(Discourse.Formatter.autoUpdatingRelativeAge(this.get('bumpedAt')));
- buffer.push("");
+ },
+
+ 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()
+ });
}
});
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 62373cce4db..d966ca1cfc3 100644
--- a/app/assets/javascripts/discourse/components/basic-topic-list.js.es6
+++ b/app/assets/javascripts/discourse/components/basic-topic-list.js.es6
@@ -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);
+ }
}
});
diff --git a/app/assets/javascripts/discourse/controllers/topic-entrance.js.es6 b/app/assets/javascripts/discourse/controllers/topic-entrance.js.es6
new file mode 100644
index 00000000000..1a19dd4425c
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/topic-entrance.js.es6
@@ -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'));
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/routes/application.js.es6 b/app/assets/javascripts/discourse/routes/application.js.es6
index 2473f49e13a..4a09027737d 100644
--- a/app/assets/javascripts/discourse/routes/application.js.es6
+++ b/app/assets/javascripts/discourse/routes/application.js.es6
@@ -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
diff --git a/app/assets/javascripts/discourse/routes/discourse_route.js b/app/assets/javascripts/discourse/routes/discourse_route.js
index 1db776cc78c..6934a9a4846 100644
--- a/app/assets/javascripts/discourse/routes/discourse_route.js
+++ b/app/assets/javascripts/discourse/routes/discourse_route.js
@@ -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');
},
/**
diff --git a/app/assets/javascripts/discourse/templates/application.js.handlebars b/app/assets/javascripts/discourse/templates/application.js.handlebars
index 4a624f7071e..f850ab4efb0 100644
--- a/app/assets/javascripts/discourse/templates/application.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/application.js.handlebars
@@ -5,4 +5,5 @@
{{render "modal"}}
+{{render "topic-entrance"}}
{{render "composer"}}
diff --git a/app/assets/javascripts/discourse/templates/components/basic-topic-list.js.handlebars b/app/assets/javascripts/discourse/templates/components/basic-topic-list.js.handlebars
index b9e1b854033..8c55a5f4464 100644
--- a/app/assets/javascripts/discourse/templates/components/basic-topic-list.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/components/basic-topic-list.js.handlebars
@@ -53,7 +53,7 @@
{{number topic.views numberKey="views_long"}}
- {{activity-column topic=topic class="num"}}
+ {{activity-column topic=topic class="num" action="clickedActivity"}}
{{/grouped-each}}
diff --git a/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars b/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars
index 27fbfbfe7cd..4ecd1c064c4 100644
--- a/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars
@@ -5,28 +5,28 @@
{{#if content.yearly}}
{{i18n filters.top.this_year}}
- {{basic-topic-list topicList=content.yearly hideCategory=hideCategory}}
+ {{basic-topic-list topicList=content.yearly hideCategory=hideCategory activityAction="showTopicEntrance"}}
{{#if content.yearly.topics.length}}
{{i18n show_more}}{{/if}}
{{/if}}
{{#if content.monthly}}
{{i18n filters.top.this_month}}
- {{basic-topic-list topicList=content.monthly hideCategory=hideCategory}}
+ {{basic-topic-list topicList=content.monthly hideCategory=hideCategory activityAction="showTopicEntrance"}}
{{#if content.monthly.topics.length}}
{{i18n show_more}}{{/if}}
{{/if}}
{{#if content.weekly}}
{{i18n filters.top.this_week}}
- {{basic-topic-list topicList=content.weekly hideCategory=hideCategory}}
+ {{basic-topic-list topicList=content.weekly hideCategory=hideCategory activityAction="showTopicEntrance"}}
{{#if content.weekly.topics.length}}
{{i18n show_more}}{{/if}}
{{/if}}
{{#if content.daily}}
{{i18n filters.top.today}}
- {{basic-topic-list topicList=content.daily hideCategory=hideCategory}}
+ {{basic-topic-list topicList=content.daily hideCategory=hideCategory activityAction="showTopicEntrance"}}
{{#if content.daily.topics.length}}
{{i18n show_more}}{{/if}}
{{/if}}
diff --git a/app/assets/javascripts/discourse/templates/list/topic_list_item.js.handlebars b/app/assets/javascripts/discourse/templates/list/topic_list_item.js.handlebars
index 5123e5fe1f5..e9baf550d17 100644
--- a/app/assets/javascripts/discourse/templates/list/topic_list_item.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/list/topic_list_item.js.handlebars
@@ -49,4 +49,4 @@
{{posts-count-column topic=model class="num"}}
{{number views numberKey="views_long"}} |
-{{activity-column topic=model class="num"}}
+{{activity-column topic=model class="num" action="showTopicEntrance"}}
diff --git a/app/assets/javascripts/discourse/templates/list/user_topics_list.js.handlebars b/app/assets/javascripts/discourse/templates/list/user_topics_list.js.handlebars
index 44836b7c277..f7e73c447ab 100644
--- a/app/assets/javascripts/discourse/templates/list/user_topics_list.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/list/user_topics_list.js.handlebars
@@ -1 +1,4 @@
-{{basic-topic-list topicList=model hideCategory=hideCategory showParticipants=showParticipants}}
+{{basic-topic-list topicList=model
+ hideCategory=hideCategory
+ showParticipants=showParticipants
+ activityAction="showTopicEntrance"}}
diff --git a/app/assets/javascripts/discourse/templates/topic-entrance.js.handlebars b/app/assets/javascripts/discourse/templates/topic-entrance.js.handlebars
new file mode 100644
index 00000000000..4291a27f4cd
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/topic-entrance.js.handlebars
@@ -0,0 +1,6 @@
+
+
diff --git a/app/assets/javascripts/discourse/templates/topic.js.handlebars b/app/assets/javascripts/discourse/templates/topic.js.handlebars
index 6949cab4dbe..72cb989c45b 100644
--- a/app/assets/javascripts/discourse/templates/topic.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/topic.js.handlebars
@@ -102,7 +102,7 @@
{{i18n suggested_topics.title}}
- {{basic-topic-list topics=details.suggested_topics}}
+ {{basic-topic-list topics=details.suggested_topics activityAction="showTopicEntrance"}}
{{{view.browseMoreMessage}}}
diff --git a/app/assets/javascripts/discourse/views/topic-entrance.js.es6 b/app/assets/javascripts/discourse/views/topic-entrance.js.es6
new file mode 100644
index 00000000000..20408d0e375
--- /dev/null
+++ b/app/assets/javascripts/discourse/views/topic-entrance.js.es6
@@ -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'),
+
+});
diff --git a/app/assets/stylesheets/desktop.scss b/app/assets/stylesheets/desktop.scss
index fa2cf8ed38c..a36b12e34a2 100644
--- a/app/assets/stylesheets/desktop.scss
+++ b/app/assets/stylesheets/desktop.scss
@@ -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. */
diff --git a/app/assets/stylesheets/desktop/topic-entrance.scss b/app/assets/stylesheets/desktop/topic-entrance.scss
new file mode 100644
index 00000000000..058b389eaa5
--- /dev/null
+++ b/app/assets/stylesheets/desktop/topic-entrance.scss
@@ -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;
+ }
+}
diff --git a/app/assets/stylesheets/desktop/topic-list.scss b/app/assets/stylesheets/desktop/topic-list.scss
index 42e24c171a3..5ba472836b6 100644
--- a/app/assets/stylesheets/desktop/topic-list.scss
+++ b/app/assets/stylesheets/desktop/topic-list.scss
@@ -138,6 +138,9 @@
}
.activity {
width: 60px;
+ span {
+ cursor: pointer;
+ }
}
.age {
width: 60px;
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 2fe32b5d260..d0fb8212a40 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -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: