diff --git a/app/assets/javascripts/discourse/components/top-period-buttons.js.es6 b/app/assets/javascripts/discourse/components/top-period-buttons.js.es6
new file mode 100644
index 00000000000..eec8000a46b
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/top-period-buttons.js.es6
@@ -0,0 +1,3 @@
+export default Ember.Component.extend({
+ classNames: ['top-title-buttons']
+});
diff --git a/app/assets/javascripts/discourse/components/top-period-chooser.js.es6 b/app/assets/javascripts/discourse/components/top-period-chooser.js.es6
new file mode 100644
index 00000000000..ee63a0ae4c9
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/top-period-chooser.js.es6
@@ -0,0 +1,31 @@
+import CleansUp from 'discourse/mixins/cleans-up';
+
+export default Ember.Component.extend(CleansUp, {
+ classNames: 'period-chooser',
+ showPeriods: false,
+
+ cleanUp: function() {
+ this.set('showPeriods', false);
+ $('html').off('mousedown.top-period');
+ },
+
+ _clickToClose: function() {
+ var self = this;
+ $('html').off('mousedown.top-period').on('mousedown.top-period', function(e) {
+ var $target = $(e.target);
+ if (($target.prop('id') === 'topic-entrance') || (self.$().has($target).length !== 0)) {
+ return;
+ }
+ self.cleanUp();
+ });
+ },
+
+ click: function() {
+ if (!this.get('showPeriods')) {
+ var $chevron = this.$('i.fa-caret-down');
+ this.$('#period-popup').css($chevron.position());
+ this.set('showPeriods', true);
+ this._clickToClose();
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/components/top-title-button.js.es6 b/app/assets/javascripts/discourse/components/top-title-button.js.es6
new file mode 100644
index 00000000000..8da2fd50787
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/top-title-button.js.es6
@@ -0,0 +1,13 @@
+import TopTitle from 'discourse/components/top-title';
+
+export default TopTitle.extend({
+ tagName: 'button',
+ classNameBindings: [':btn', ':btn-default', 'unless:hidden'],
+
+ click: function() {
+ var url = this.get('period.showMoreUrl');
+ if (url) {
+ Discourse.URL.routeTo(url);
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/components/top-title.js.es6 b/app/assets/javascripts/discourse/components/top-title.js.es6
new file mode 100644
index 00000000000..31c03461d58
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/top-title.js.es6
@@ -0,0 +1,8 @@
+export default Ember.Component.extend({
+ tagName: 'h2',
+
+ _shouldRerender: Discourse.View.renderIfChanged('period.title'),
+ render: function(buffer) {
+ buffer.push(" " + this.get('period.title'));
+ }
+});
diff --git a/app/assets/javascripts/discourse/controllers/discovery.js.es6 b/app/assets/javascripts/discourse/controllers/discovery.js.es6
index 5fe00057a92..16cb2000f63 100644
--- a/app/assets/javascripts/discourse/controllers/discovery.js.es6
+++ b/app/assets/javascripts/discourse/controllers/discovery.js.es6
@@ -1,10 +1,15 @@
import ObjectController from 'discourse/controllers/object';
+import TopPeriod from 'discourse/models/top-period';
export default ObjectController.extend({
+ needs: ['navigation/category'],
loading: false,
loadingSpinner: false,
scheduledSpinner: null,
+ category: Em.computed.alias('controllers.navigation/category.category'),
+ noSubcategories: Em.computed.alias('controllers.navigation/category.noSubcategories'),
+
showMoreUrl: function(period) {
var url = '', category = this.get('category');
if (category) {
@@ -14,8 +19,15 @@ export default ObjectController.extend({
return url;
},
- showMoreDailyUrl: function() { return this.showMoreUrl('daily'); }.property('category', 'noSubcategories'),
- showMoreWeeklyUrl: function() { return this.showMoreUrl('weekly'); }.property('category', 'noSubcategories'),
- showMoreMonthlyUrl: function() { return this.showMoreUrl('monthly'); }.property('category', 'noSubcategories'),
- showMoreYearlyUrl: function() { return this.showMoreUrl('yearly'); }.property('category', 'noSubcategories')
+ periods: function() {
+ var self = this,
+ periods = [];
+ Discourse.Site.currentProp('periods').forEach(function(p) {
+ periods.pushObject(TopPeriod.create({ id: p,
+ showMoreUrl: self.showMoreUrl(p),
+ periods: periods }));
+ });
+ return periods;
+ }.property('category', 'noSubcategories'),
+
});
diff --git a/app/assets/javascripts/discourse/controllers/discovery/top.js.es6 b/app/assets/javascripts/discourse/controllers/discovery/top.js.es6
index 7bb194ad56f..1bce2033a2c 100644
--- a/app/assets/javascripts/discourse/controllers/discovery/top.js.es6
+++ b/app/assets/javascripts/discourse/controllers/discovery/top.js.es6
@@ -3,6 +3,14 @@ import DiscoveryController from 'discourse/controllers/discovery';
export default DiscoveryController.extend({
needs: ['discovery'],
+ period: function() {
+ return this.get('controllers.discovery.periods').findBy('id', this.get('periodId'));
+ }.property('periodId'),
+
+ topicList: function() {
+ return this.get('model.' + this.get('periodId'));
+ }.property('periodId'),
+
actions: {
refresh: function() {
var self = this;
@@ -16,7 +24,6 @@ export default DiscoveryController.extend({
self.send('loadingComplete');
});
}
- },
+ }
- hasDisplayedAllTopLists: Em.computed.and('content.yearly', 'content.monthly', 'content.weekly', 'content.daily')
});
diff --git a/app/assets/javascripts/discourse/mixins/cleans-up.js.es6 b/app/assets/javascripts/discourse/mixins/cleans-up.js.es6
new file mode 100644
index 00000000000..2c180ec9b6c
--- /dev/null
+++ b/app/assets/javascripts/discourse/mixins/cleans-up.js.es6
@@ -0,0 +1,11 @@
+// Include this mixin if you want to be notified when the dom should be
+// cleaned (usually on route change.)
+export default Ember.Mixin.create({
+ _initializeChooser: function() {
+ this.appEvents.on('dom:clean', this, "cleanUp");
+ }.on('didInsertElement'),
+
+ _clearChooser: function() {
+ this.appEvents.off('dom:clean', this, "cleanUp");
+ }.on('willDestroyElement')
+});
diff --git a/app/assets/javascripts/discourse/models/top-period.js.es6 b/app/assets/javascripts/discourse/models/top-period.js.es6
new file mode 100644
index 00000000000..9aef0fcdade
--- /dev/null
+++ b/app/assets/javascripts/discourse/models/top-period.js.es6
@@ -0,0 +1,30 @@
+export default Ember.Object.extend({
+ title: null,
+
+ availablePeriods: function() {
+ var periods = this.get('periods');
+ if (!periods) { return; }
+
+ var self = this;
+ return periods.filter(function(p) {
+ return p !== self;
+ });
+ }.property('showMoreUrl'),
+
+ _createTitle: function() {
+ var id = this.get('id');
+ if (id) {
+ var title = "this_week";
+ if (id === "yearly") {
+ title = "this_year";
+ } else if (id === "monthly") {
+ title = "this_month";
+ } else if (id === "daily") {
+ title = "today";
+ }
+
+ this.set('title', I18n.t("filters.top." + title));
+ }
+ }.on('init')
+
+});
diff --git a/app/assets/javascripts/discourse/models/top_list.js b/app/assets/javascripts/discourse/models/top_list.js
index d5ccb19efb5..7ea8bf5ead6 100644
--- a/app/assets/javascripts/discourse/models/top_list.js
+++ b/app/assets/javascripts/discourse/models/top_list.js
@@ -27,6 +27,7 @@ Discourse.TopList.reopenClass({
if (result[period]) {
// instanciate a new topic list with no sorting
topList.set(period, Discourse.TopicList.from(result[period]));
+ topList.set('periodId', period);
}
});
diff --git a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 b/app/assets/javascripts/discourse/routes/build-category-route.js.es6
index 1f4faa35047..31ec0f56ac6 100644
--- a/app/assets/javascripts/discourse/routes/build-category-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-category-route.js.es6
@@ -62,7 +62,8 @@ export default function(filter, params) {
setupController: function(controller, model) {
var topics = this.get('topics'),
- period = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
+ periods = this.controllerFor('discovery').get('periods'),
+ periodId = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
Discourse.set('title', I18n.t('filters.with_category', { filter: filterText, category: model.get('name') }));
@@ -71,7 +72,7 @@ export default function(filter, params) {
this.controllerFor('discovery/topics').setProperties({
model: topics,
category: model,
- period: period,
+ period: periods.findBy('id', periodId),
selected: [],
noSubcategories: params && !!params.no_subcategories
});
diff --git a/app/assets/javascripts/discourse/routes/build-topic-route.js.es6 b/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
index 8a5d419e461..d1b9cd92440 100644
--- a/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
@@ -35,7 +35,8 @@ export default function(filter) {
return 'queryParams.' + v;
})));
- var period = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
+ var periods = this.controllerFor('discovery').get('periods'),
+ periodId = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
if (filter === Discourse.Utilities.defaultHomepage()) {
@@ -47,7 +48,7 @@ export default function(filter) {
this.controllerFor('discovery/topics').setProperties({
model: model,
category: null,
- period: period,
+ period: periods.findBy('id', periodId),
selected: []
});
diff --git a/app/assets/javascripts/discourse/templates/components/top-period-buttons.js.handlebars b/app/assets/javascripts/discourse/templates/components/top-period-buttons.js.handlebars
new file mode 100644
index 00000000000..718880e7186
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/top-period-buttons.js.handlebars
@@ -0,0 +1,3 @@
+{{#each period.availablePeriods}}
+ {{top-title-button period=this}}
+{{/each}}
diff --git a/app/assets/javascripts/discourse/templates/components/top-period-chooser.js.handlebars b/app/assets/javascripts/discourse/templates/components/top-period-chooser.js.handlebars
new file mode 100644
index 00000000000..f82a1446af2
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/top-period-chooser.js.handlebars
@@ -0,0 +1,10 @@
+{{top-title period=period}}
+
+
+
diff --git a/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars b/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars
index aa6a5e2c232..270702b9ba3 100644
--- a/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars
@@ -2,44 +2,22 @@
{{#if currentUser.redirected_to_top_reason}}
{{currentUser.redirected_to_top_reason}}
{{/if}}
- {{#if content.yearly}}
+
+ {{#if topicList}}
-
{{i18n filters.top.this_year}}
- {{basic-topic-list topicList=content.yearly hideCategory=hideCategory postsAction="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 postsAction="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 postsAction="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 postsAction="showTopicEntrance"}}
- {{#if content.daily.topics.length}}
{{i18n show_more}}{{/if}}
+ {{top-period-chooser period=period}}
+ {{basic-topic-list topicList=topicList hideCategory=hideCategory postsAction="showTopicEntrance"}}
+ {{#if topicList.topics.length}}
{{i18n show_more}}{{/if}}
{{/if}}
+
diff --git a/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars b/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars
index cee89c8b8aa..92e101e158c 100644
--- a/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars
@@ -18,10 +18,9 @@
{{#if top}}
- {{#if yearly}}
{{i18n filters.top.this_year}}
{{/if}}
- {{#if monthly}}
{{i18n filters.top.this_month}}
{{/if}}
- {{#if weekly}}
{{i18n filters.top.this_week}}
{{/if}}
- {{#if daily}}
{{i18n filters.top.today}}
{{/if}}
+
+ {{top-period-chooser period=period}}
+
{{/if}}
{{#if showTable}}
@@ -101,11 +100,7 @@
{{#if top}}
{{#link-to "discovery.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}}, {{#link-to 'discovery.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}} {{i18n or}} {{i18n filters.top.other_periods}}
- {{#unless yearly}}{{i18n filters.top.this_year}}{{/unless}}
- {{#unless monthly}}{{i18n filters.top.this_month}}{{/unless}}
- {{#unless weekly}}{{i18n filters.top.this_week}}{{/unless}}
- {{#unless daily}}{{i18n filters.top.today}}{{/unless}}
-
+ {{top-period-buttons period=period}}
{{else}}
{{{footerEducation}}}
diff --git a/app/assets/javascripts/discourse/templates/mobile/discovery/topics.js.handlebars b/app/assets/javascripts/discourse/templates/mobile/discovery/topics.js.handlebars
index 9864db826f5..7a89824ff22 100644
--- a/app/assets/javascripts/discourse/templates/mobile/discovery/topics.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/mobile/discovery/topics.js.handlebars
@@ -1,10 +1,9 @@
{{#if showTable}}
{{#if top}}
- {{#if yearly}}
{{i18n filters.top.this_year}}
{{/if}}
- {{#if monthly}}
{{i18n filters.top.this_month}}
{{/if}}
- {{#if weekly}}
{{i18n filters.top.this_week}}
{{/if}}
- {{#if daily}}
{{i18n filters.top.today}}
{{/if}}
+
+ {{top-period-chooser period=period}}
+
{{/if}}
{{#if topicTrackingState.hasIncoming}}
@@ -47,10 +46,7 @@
{{#if top}}
{{#link-to "discovery.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}}, {{#link-to 'discovery.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}} {{i18n or}} {{i18n filters.top.other_periods}}
- {{#unless yearly}}{{i18n filters.top.this_year}}{{/unless}}
- {{#unless monthly}}{{i18n filters.top.this_month}}{{/unless}}
- {{#unless weekly}}{{i18n filters.top.this_week}}{{/unless}}
- {{#unless daily}}{{i18n filters.top.today}}{{/unless}}
+ {{top-period-buttons period=period}}
{{else}}
{{{footerEducation}}}
diff --git a/app/assets/javascripts/discourse/views/poster-expansion.js.es6 b/app/assets/javascripts/discourse/views/poster-expansion.js.es6
index e337e5c2e1b..ed94388914d 100644
--- a/app/assets/javascripts/discourse/views/poster-expansion.js.es6
+++ b/app/assets/javascripts/discourse/views/poster-expansion.js.es6
@@ -1,13 +1,14 @@
+import CleansUp from 'discourse/mixins/cleans-up';
+
var clickOutsideEventName = "mousedown.outside-poster-expansion";
-export default Discourse.View.extend({
+export default Discourse.View.extend(CleansUp, {
elementId: 'poster-expansion',
classNameBindings: ['controller.visible::hidden', 'controller.showBadges'],
_setup: function() {
var self = this;
this.appEvents.on('poster:expand', this, '_posterExpand');
- this.appEvents.on('dom:clean', this, '_cleanUp');
$('html').off(clickOutsideEventName).on(clickOutsideEventName, function(e) {
if (self.get('controller.visible')) {
@@ -43,14 +44,13 @@ export default Discourse.View.extend({
});
},
- _cleanUp: function() {
+ cleanUp: function() {
this.get('controller').close();
},
_removeEvents: function() {
$('html').off(clickOutsideEventName);
this.appEvents.off('poster:expand', this, '_posterExpand');
- this.appEvents.off('dom:clean', this, '_cleanUp');
}.on('willDestroyElement')
});
diff --git a/app/assets/javascripts/discourse/views/topic-entrance.js.es6 b/app/assets/javascripts/discourse/views/topic-entrance.js.es6
index 3ec95e2f140..76140158adf 100644
--- a/app/assets/javascripts/discourse/views/topic-entrance.js.es6
+++ b/app/assets/javascripts/discourse/views/topic-entrance.js.es6
@@ -1,3 +1,5 @@
+import CleansUp from 'discourse/mixins/cleans-up';
+
export default Ember.View.extend({
elementId: 'topic-entrance',
classNameBindings: ['visible::hidden'],
@@ -29,27 +31,22 @@ export default Ember.View.extend({
if (($target.prop('id') === 'topic-entrance') || ($self.has($target).length !== 0)) {
return;
}
- self._cleanUp();
+ self.cleanUp();
});
}.observes('controller.position'),
_removed: function() {
$('html').off('mousedown.topic-entrance');
- this.appEvents.off('dom:clean', this, '_cleanUp');
}.on('willDestroyElement'),
- _cleanUp: function() {
+ cleanUp: function() {
this.set('controller.model', null);
$('html').off('mousedown.topic-entrance');
},
- _wireClean: function() {
- this.appEvents.on('dom:clean', this, '_cleanUp');
- }.on('didInsertElement'),
-
keyDown: function(e) {
if (e.which === 27) {
- this._cleanUp();
+ this.cleanUp();
}
}
diff --git a/app/assets/javascripts/main_include.js b/app/assets/javascripts/main_include.js
index 8c7ee2da76d..4154db67e2f 100644
--- a/app/assets/javascripts/main_include.js
+++ b/app/assets/javascripts/main_include.js
@@ -19,6 +19,7 @@
//= require ./discourse/models/user_action
//= require ./discourse/models/composer
//= require ./discourse/models/topic
+//= require ./discourse/models/top-period
//= require ./discourse/controllers/controller
//= require ./discourse/controllers/discovery-sortable
//= require ./discourse/controllers/object
@@ -34,6 +35,7 @@
//= require ./discourse/routes/discourse_route
//= require ./discourse/routes/build-topic-route
//= require ./discourse/routes/discourse_restricted_user_route
+//= require ./discourse/components/top-title
//= require ./discourse/components/text-field
//= require ./discourse/helpers/user-avatar
//= require ./discourse/helpers/cold-age-class
diff --git a/app/assets/stylesheets/common/base/_topic-list.scss b/app/assets/stylesheets/common/base/_topic-list.scss
index 4649d7f95c7..2493d54812d 100644
--- a/app/assets/stylesheets/common/base/_topic-list.scss
+++ b/app/assets/stylesheets/common/base/_topic-list.scss
@@ -260,3 +260,48 @@ ol.category-breadcrumb {
.topic-statuses .fa {
padding-right: 3px;
}
+
+.period-chooser {
+ h2 {
+ float: left;
+ }
+
+ button {
+ outline: 0;
+ background: transparent;
+ border: 0;
+ font-size: 20px;
+ padding: 5px 10px 0 10px;
+ }
+
+ #period-popup {
+ border: 1px solid scale-color-diff();
+ padding: 5px;
+ background: $secondary;
+ position: absolute;
+ z-index: 1110;
+ @include box-shadow(0 2px 2px rgba(0,0,0, .4));
+
+ ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+
+ li {
+ margin: 0;
+ padding: 0;
+ a {
+ display: block;
+ padding: 5px;
+ }
+ &:hover {
+ background-color: dark-light-diff($highlight, $secondary, 50%, -70%);
+ }
+ }
+ }
+ }
+}
+
+.top-title-buttons {
+ display: inline;
+}
diff --git a/app/assets/stylesheets/mobile/topic-list.scss b/app/assets/stylesheets/mobile/topic-list.scss
index 616c94c68db..8de4ffad9ab 100644
--- a/app/assets/stylesheets/mobile/topic-list.scss
+++ b/app/assets/stylesheets/mobile/topic-list.scss
@@ -296,3 +296,9 @@ ol.category-breadcrumb {
max-width: 100%;
padding: 8px 0;
}
+
+.period-chooser {
+ button {
+ margin-top: 10px;
+ }
+}
diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb
index 18ec8d64d4a..1e50370eda5 100644
--- a/app/controllers/list_controller.rb
+++ b/app/controllers/list_controller.rb
@@ -317,11 +317,7 @@ class ListController < ApplicationController
options[:per_page] = SiteSetting.topics_per_period_in_top_summary
topic_query = TopicQuery.new(current_user, options)
- if current_user.present?
- periods = [ListController.best_period_for(current_user.previous_visit_at, options[:category])]
- else
- periods = TopTopic.periods
- end
+ periods = [ListController.best_period_for(current_user.try(:previous_visit_at), options[:category])]
periods.each { |period| top.send("#{period}=", topic_query.list_top_for(period)) }