From 129617b415651ee220d3f350094cf80744c1589f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Fri, 17 Jan 2014 04:38:08 +0100 Subject: [PATCH] Lots of bugfixes BUGFIX: navigation bar should always activate the right tab (even when diging into a top period) BUGFIX: /top pages titles BUGFIX: no "edit category" button on /top page after visiting a category BUGFIX: properly hide category columns when there is no children category (on both filter + top pages) BUGFIX: promises not caught when scrolling down a topic list to load more of them BUGFIX: CSS on category dropdowns Updated `top_menu` i18n with available filters --- .../components/navigation_item_component.js | 2 +- .../controllers/discovery_top_controller.js | 2 +- .../discovery_topics_controller.js | 2 +- .../navigation_default_controller.js | 4 +- .../javascripts/discourse/lib/computed.js | 2 - .../javascripts/discourse/models/top_list.js | 11 +-- .../discourse/models/topic_list.js | 4 +- .../discourse/routes/application_routes.js | 4 +- .../routes/discovery_route_builders.js | 30 +++---- .../discourse/routes/discovery_top_route.js | 40 --------- .../discourse/routes/discovery_top_routes.js | 89 +++++++++++++++++++ .../components/basic-topic-list.js.handlebars | 10 ++- .../templates/discovery/top.js.handlebars | 8 +- .../templates/discovery/topics.js.handlebars | 4 +- .../discourse/views/discovery_topics_view.js | 2 +- .../stylesheets/desktop/topic-list.scss | 14 ++- app/controllers/list_controller.rb | 21 ++--- app/models/user.rb | 2 +- app/serializers/top_list_serializer.rb | 6 ++ config/locales/client.en.yml | 8 ++ config/locales/server.cs.yml | 2 +- config/locales/server.da.yml | 2 +- config/locales/server.de.yml | 2 +- config/locales/server.en.yml | 2 +- config/locales/server.es.yml | 2 +- config/locales/server.fr.yml | 2 +- config/locales/server.id.yml | 2 +- config/locales/server.it.yml | 2 +- config/locales/server.ja.yml | 2 +- config/locales/server.ko.yml | 2 +- config/locales/server.nl.yml | 2 +- config/locales/server.pt.yml | 2 +- config/locales/server.pt_BR.yml | 2 +- config/locales/server.ru.yml | 2 +- config/locales/server.sv.yml | 2 +- config/locales/server.zh_CN.yml | 2 +- config/routes.rb | 4 +- 37 files changed, 178 insertions(+), 123 deletions(-) delete mode 100644 app/assets/javascripts/discourse/routes/discovery_top_route.js create mode 100644 app/assets/javascripts/discourse/routes/discovery_top_routes.js diff --git a/app/assets/javascripts/discourse/components/navigation_item_component.js b/app/assets/javascripts/discourse/components/navigation_item_component.js index 61bd338eac0..e9e8f3e72c2 100644 --- a/app/assets/javascripts/discourse/components/navigation_item_component.js +++ b/app/assets/javascripts/discourse/components/navigation_item_component.js @@ -27,7 +27,7 @@ Discourse.NavigationItemComponent = Ember.Component.extend({ active: function() { return this.get('content.filterMode') === this.get('filterMode') || - (this.get('filterMode') === 'top' && this.get('content.filterMode').indexOf('top') >= 0); + this.get('filterMode').indexOf(this.get('content.filterMode')) === 0; }.property('content.filterMode', 'filterMode'), name: function() { diff --git a/app/assets/javascripts/discourse/controllers/discovery_top_controller.js b/app/assets/javascripts/discourse/controllers/discovery_top_controller.js index 5699591484b..4c95239cc8a 100644 --- a/app/assets/javascripts/discourse/controllers/discovery_top_controller.js +++ b/app/assets/javascripts/discourse/controllers/discovery_top_controller.js @@ -7,7 +7,7 @@ @module Discourse **/ Discourse.DiscoveryTopController = Discourse.ObjectController.extend({ - category:null, + category: null, redirectedToTopPageReason: function() { // no need for a reason if the default homepage is "top" diff --git a/app/assets/javascripts/discourse/controllers/discovery_topics_controller.js b/app/assets/javascripts/discourse/controllers/discovery_topics_controller.js index 32e4e27e1e8..22fad099959 100644 --- a/app/assets/javascripts/discourse/controllers/discovery_topics_controller.js +++ b/app/assets/javascripts/discourse/controllers/discovery_topics_controller.js @@ -46,7 +46,7 @@ Discourse.DiscoveryTopicsController = Discourse.ObjectController.extend({ hasTopics: Em.computed.gt('topics.length', 0), showTable: Em.computed.or('hasTopics', 'topicTrackingState.hasIncoming'), - latest: Ember.computed.equal('filter', 'latest'), + latest: Em.computed.equal('filter', 'latest'), allLoaded: Em.computed.empty('more_topics_url'), updateTitle: function(){ diff --git a/app/assets/javascripts/discourse/controllers/navigation_default_controller.js b/app/assets/javascripts/discourse/controllers/navigation_default_controller.js index 8fa71600ad6..9c2a48a1051 100644 --- a/app/assets/javascripts/discourse/controllers/navigation_default_controller.js +++ b/app/assets/javascripts/discourse/controllers/navigation_default_controller.js @@ -28,13 +28,13 @@ Discourse.NavigationDefaultController = Discourse.Controller.extend({ navItems: function() { return Discourse.NavItem.buildList(); - }.property() + }.property() }); Discourse.NavigationCategoryController = Discourse.NavigationDefaultController.extend({ navItems: function() { return Discourse.NavItem.buildList(this.get('category'), { noSubcategories: this.get('noSubcategories') }); - }.property('category', 'noSubcategories') + }.property('category', 'noSubcategories') }); Discourse.NavigationCategoriesController = Discourse.NavigationDefaultController.extend({}); diff --git a/app/assets/javascripts/discourse/lib/computed.js b/app/assets/javascripts/discourse/lib/computed.js index eb9c53b83d6..38512f58e9c 100644 --- a/app/assets/javascripts/discourse/lib/computed.js +++ b/app/assets/javascripts/discourse/lib/computed.js @@ -88,8 +88,6 @@ Discourse.computed = { }))); }); return computed.property.apply(computed, args); - } - }; diff --git a/app/assets/javascripts/discourse/models/top_list.js b/app/assets/javascripts/discourse/models/top_list.js index e5ea4d1cf08..d42b21270c6 100644 --- a/app/assets/javascripts/discourse/models/top_list.js +++ b/app/assets/javascripts/discourse/models/top_list.js @@ -10,15 +10,12 @@ Discourse.TopList = Discourse.Model.extend({}); Discourse.TopList.reopenClass({ - find: function(period, category) { + find: function(filter) { return PreloadStore.getAndRemove("top_lists", function() { - var url = ""; - if (category) { url += category.get("url") + "/l"; } - url += "/top"; - if (period) { url += "/" + period; } - return Discourse.ajax(url + ".json"); + var url = Discourse.getURL("/") + (filter || "top") + ".json"; + return Discourse.ajax(url); }).then(function (result) { - var topList = Discourse.TopList.create({}); + var topList = Discourse.TopList.create({ can_create_topic: result.can_create_topic }); Discourse.Site.currentProp('periods').forEach(function(period) { // if there is a list for that period diff --git a/app/assets/javascripts/discourse/models/topic_list.js b/app/assets/javascripts/discourse/models/topic_list.js index 34e65c8c171..8bc5428d774 100644 --- a/app/assets/javascripts/discourse/models/topic_list.js +++ b/app/assets/javascripts/discourse/models/topic_list.js @@ -78,7 +78,7 @@ Discourse.TopicList = Discourse.Model.extend({ }.observes('sortOrder.order', 'sortOrder.descending'), loadMore: function() { - if (this.get('loadingMore')) { return Ember.RSVP.reject(); } + if (this.get('loadingMore')) { return Ember.RSVP.resolve(); } var moreUrl = this.get('more_topics_url'); if (moreUrl) { @@ -105,7 +105,7 @@ Discourse.TopicList = Discourse.Model.extend({ }); } else { // Return a promise indicating no more results - return Ember.RSVP.reject(); + return Ember.RSVP.resolve(); } }, diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js index 4905598d59a..08c64d7dde7 100644 --- a/app/assets/javascripts/discourse/routes/application_routes.js +++ b/app/assets/javascripts/discourse/routes/application_routes.js @@ -21,7 +21,7 @@ Discourse.Route.buildRoutes(function() { this.resource('discovery', { path: '/' }, function() { router = this; - + // top this.route('top'); this.route('topCategory', { path: '/category/:slug/l/top' }); @@ -56,9 +56,7 @@ Discourse.Route.buildRoutes(function() { // default filter for a category this.route('category', { path: '/category/:slug' }); - this.route('category', { path: '/category/:slug/more' }); this.route('categoryNone', { path: '/category/:slug/none' }); - this.route('categoryNone', { path: '/category/:slug/none/more' }); this.route('category', { path: '/category/:parentSlug/:slug' }); // homepage diff --git a/app/assets/javascripts/discourse/routes/discovery_route_builders.js b/app/assets/javascripts/discourse/routes/discovery_route_builders.js index 0dd511ee9cc..4b2b4b0b8f9 100644 --- a/app/assets/javascripts/discourse/routes/discovery_route_builders.js +++ b/app/assets/javascripts/discourse/routes/discovery_route_builders.js @@ -6,11 +6,6 @@ **/ function buildTopicRoute(filter) { return Discourse.Route.extend({ - renderTemplate: function() { - this.render('navigation/default', { outlet: 'navigation-bar' }); - this.render('discovery/topics', { controller: 'discoveryTopics', outlet: 'list-container' }); - }, - beforeModel: function() { this.controllerFor('navigationDefault').set('filterMode', filter); }, @@ -27,10 +22,15 @@ function buildTopicRoute(filter) { }, setupController: function(controller, model) { - var filterText = I18n.t('filters.' + filter + '.title', {count: 0}); + var filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0}); Discourse.set('title', I18n.t('filters.with_topics', {filter: filterText})); this.controllerFor('discoveryTopics').set('model', model); this.controllerFor('navigationDefault').set('canCreateTopic', model.get('can_create_topic')); + }, + + renderTemplate: function() { + this.render('navigation/default', { outlet: 'navigation-bar' }); + this.render('discovery/topics', { controller: 'discoveryTopics', outlet: 'list-container' }); } }); } @@ -44,11 +44,6 @@ function buildTopicRoute(filter) { **/ function buildCategoryRoute(filter, params) { return Discourse.Route.extend({ - renderTemplate: function() { - this.render('navigation/category', { outlet: 'navigation-bar' }); - this.render('discovery/topics', { controller: 'discoveryTopics', outlet: 'list-container' }); - }, - model: function(params) { return Discourse.Category.findBySlug(params.slug, params.parentSlug); }, @@ -74,10 +69,8 @@ function buildCategoryRoute(filter, params) { } // If all the categories are the same, we can hide them - var diffCat = list.get('topics').find(function (t) { - return t.get('category') !== model; - }); - if (!diffCat) { list.set('hideCategory', true); } + var hideCategory = !list.get('topics').find(function (t) { return t.get('category') !== model; }); + list.set('hideCategory', hideCategory); self.set('topics', list); }); }, @@ -85,13 +78,18 @@ function buildCategoryRoute(filter, params) { setupController: function(controller, model) { var topics = this.get('topics'); - var filterText = I18n.t('filters.' + filter + '.title', {count: 0}); + var filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0}); Discourse.set('title', I18n.t('filters.with_category', {filter: filterText, category: model.get('name').capitalize()})); this.controllerFor('discoveryTopics').set('model', topics); this.controllerFor('navigationCategory').set('canCreateTopic', topics.get('can_create_topic')); this.set('topics', null); }, + renderTemplate: function() { + this.render('navigation/category', { outlet: 'navigation-bar' }); + this.render('discovery/topics', { controller: 'discoveryTopics', outlet: 'list-container' }); + }, + deactivate: function() { this._super(); this.controllerFor('search').set('searchContext', null); diff --git a/app/assets/javascripts/discourse/routes/discovery_top_route.js b/app/assets/javascripts/discourse/routes/discovery_top_route.js deleted file mode 100644 index e07777c59fc..00000000000 --- a/app/assets/javascripts/discourse/routes/discovery_top_route.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - Handles the routes related to "Top" - - @class DiscoveryTopRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.DiscoveryTopRoute = Discourse.Route.extend({ - model: function(params) { - return Discourse.Category.findBySlug(params.slug, params.parentSlug); - }, - - beforeModel: function() { - this.controllerFor('navigationCategory').set('filterMode', 'top'); - }, - - afterModel: function(model) { - var self = this; - return Discourse.TopList.find(null, model).then(function(list) { - self.set('topics', list); - }); - }, - - renderTemplate: function() { - this.render('navigation/category', { outlet: 'navigation-bar' }); - this.render('discovery/top', { outlet: 'list-container' }); - }, - - setupController: function(controller, model) { - this.controllerFor('discoveryTop').set('model', this.get('topics')); - this.controllerFor('discoveryTop').set('category', model); - this.controllerFor('navigationCategory').set('category', model); - Discourse.set('title', I18n.t('filters.top.title')); - this.set('topics', null); - } -}); - -Discourse.DiscoveryTopCategoryRoute = Discourse.DiscoveryTopRoute.extend({}); -Discourse.DiscoveryTopCategoryNoneRoute = Discourse.DiscoveryTopRoute.extend({}); diff --git a/app/assets/javascripts/discourse/routes/discovery_top_routes.js b/app/assets/javascripts/discourse/routes/discovery_top_routes.js new file mode 100644 index 00000000000..54accbc8a91 --- /dev/null +++ b/app/assets/javascripts/discourse/routes/discovery_top_routes.js @@ -0,0 +1,89 @@ +/** + Handles the routes related to "Top" + + @class DiscoveryTopRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ +Discourse.DiscoveryTopRoute = Discourse.Route.extend({ + beforeModel: function() { + this.controllerFor('navigationDefault').set('filterMode', 'top'); + }, + + model: function() { + return Discourse.TopList.find(); + }, + + setupController: function(controller, model) { + var filterText = I18n.t('filters.top.title'); + Discourse.set('title', I18n.t('filters.with_topics', {filter: filterText})); + this.controllerFor('discoveryTop').setProperties({ model: model, category: null }); + this.controllerFor('navigationDefault').set('canCreateTopic', model.get('can_create_topic')); + }, + + renderTemplate: function() { + this.render('navigation/default', { outlet: 'navigation-bar' }); + this.render('discovery/top', { outlet: 'list-container' }); + } +}); + +/** + Handles the routes related to "Top" within a category + + @class DiscoveryTopCategoryRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ +Discourse.DiscoveryTopCategoryRoute = Discourse.Route.extend({ + model: function(params) { + return Discourse.Category.findBySlug(params.slug, params.parentSlug); + }, + + afterModel: function(model) { + var self = this, + noSubcategories = this.get('no_subcategories'), + filterMode = "category/" + Discourse.Category.slugFor(model) + (noSubcategories ? "/none" : "") + "/l/top"; + + this.controllerFor('search').set('searchContext', model); + + var opts = { category: model, filterMode: filterMode}; + opts.noSubcategories = noSubcategories; + opts.canEditCategory = Discourse.User.current('staff'); + this.controllerFor('navigationCategory').setProperties(opts); + + return Discourse.TopList.find(filterMode).then(function(list) { + // If all the categories are the same, we can hide them + var hideCategory = !_.any(Discourse.Site.currentProp('periods'), function(period){ + if (list[period]) { + return list[period].get('topics').find(function(t) { return t.get('category') !== model; }); + } + return false; + }); + list.set('hideCategory', hideCategory); + self.set('topList', list); + }); + }, + + setupController: function(controller, model) { + var topList = this.get('topList'); + var filterText = I18n.t('filters.top.title'); + Discourse.set('title', I18n.t('filters.with_category', {filter: filterText, category: model.get('name').capitalize()})); + this.controllerFor('discoveryTop').setProperties({ model: topList, category: model }); + this.controllerFor('navigationCategory').set('canCreateTopic', topList.get('can_create_topic')); + this.set('topList', null); + }, + + renderTemplate: function() { + this.render('navigation/category', { outlet: 'navigation-bar' }); + this.render('discovery/top', { controller: 'discoveryTop', outlet: 'list-container' }); + }, + + deactivate: function() { + this._super(); + this.controllerFor('search').set('searchContext', null); + } +}); + +Discourse.DiscoveryTopCategoryNoneRoute = Discourse.DiscoveryTopCategoryRoute.extend({no_subcategories: true}); 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 e3fbf1793eb..6fb157d8645 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 @@ -5,9 +5,11 @@ {{#sortable-heading sortBy="default" sortOrder=sortOrder}} {{i18n topic.title}} {{/sortable-heading}} - {{#sortable-heading sortBy="category" sortOrder=sortOrder}} - {{i18n category_title}} - {{/sortable-heading}} + {{#unless controller.hideCategory}} + {{#sortable-heading sortBy="category" sortOrder=sortOrder}} + {{i18n category_title}} + {{/sortable-heading}} + {{/unless}} {{#sortable-heading sortBy="posts" number=true sortOrder=sortOrder}} {{i18n posts}} {{/sortable-heading}} @@ -38,9 +40,11 @@ {{/if}} + {{#unless controller.hideCategory}} {{categoryLink topic.category}} + {{/unless}} {{number topic.posts_count numberKey="posts_long"}} diff --git a/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars b/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars index 9bfea84d4f8..f78add2d5f5 100644 --- a/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars +++ b/app/assets/javascripts/discourse/templates/discovery/top.js.handlebars @@ -7,28 +7,28 @@ {{#if content.yearly}}

{{i18n filters.top.this_year}}

- {{basic-topic-list topicList=content.yearly}} + {{basic-topic-list topicList=content.yearly hideCategory=hideCategory}} {{#if content.yearly.topics.length}}{{i18n show_more}}{{/if}}
{{/if}} {{#if content.monthly}}

{{i18n filters.top.this_month}}

- {{basic-topic-list topicList=content.monthly}} + {{basic-topic-list topicList=content.monthly hideCategory=hideCategory}} {{#if content.monthly.topics.length}}{{i18n show_more}}{{/if}}
{{/if}} {{#if content.weekly}}

{{i18n filters.top.this_week}}

- {{basic-topic-list topicList=content.weekly}} + {{basic-topic-list topicList=content.weekly hideCategory=hideCategory}} {{#if content.weekly.topics.length}}{{i18n show_more}}{{/if}}
{{/if}} {{#if content.daily}}

{{i18n filters.top.today}}

- {{basic-topic-list topicList=content.daily}} + {{basic-topic-list topicList=content.daily hideCategory=hideCategory}} {{#if content.daily.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 a556052c7d5..362f4f47a45 100644 --- a/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars +++ b/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars @@ -9,7 +9,7 @@ {{#sortable-heading sortBy="default" sortOrder=sortOrder}} {{i18n topic.title}} {{/sortable-heading}} - {{#unless category}} + {{#unless controller.hideCategory}} {{#sortable-heading sortBy="category" sortOrder=sortOrder}} {{i18n category_title}} {{/sortable-heading}} @@ -59,7 +59,7 @@ {{footerMessage}} {{#if allLoaded}} {{#if latest}} - {{#if canCreateTopic}} + {{#if can_create_topic}} {{i18n topic.suggest_create_topic}} {{/if}} {{else}} diff --git a/app/assets/javascripts/discourse/views/discovery_topics_view.js b/app/assets/javascripts/discourse/views/discovery_topics_view.js index 806bb22b11f..9a1cd641383 100644 --- a/app/assets/javascripts/discourse/views/discovery_topics_view.js +++ b/app/assets/javascripts/discourse/views/discovery_topics_view.js @@ -20,7 +20,7 @@ Discourse.DiscoveryTopicsView = Discourse.View.extend(Discourse.LoadMore, { loadMore: function() { var self = this; Discourse.notifyTitle(0); - self.get('controller').loadMoreTopics().then(function (hasMoreResults) { + this.get('controller').loadMoreTopics().then(function (hasMoreResults) { Em.run.schedule('afterRender', function() { self.saveScrollPosition(); }); diff --git a/app/assets/stylesheets/desktop/topic-list.scss b/app/assets/stylesheets/desktop/topic-list.scss index 3f18fa479a9..acc06b13b53 100644 --- a/app/assets/stylesheets/desktop/topic-list.scss +++ b/app/assets/stylesheets/desktop/topic-list.scss @@ -13,6 +13,7 @@ float: left; margin-bottom: 15px; } + .btn { float: right; margin-left: 8px; @@ -21,23 +22,20 @@ font-weight: normal; } - a.badge-category {padding: 3px 12px; font-size: 16px; + a.badge-category { + padding: 3px 12px; + font-size: 16px; &.category-dropdown-button { - padding: 3px 9px 2px 9px; - - i {height: 20px;} - + padding: 3px 9px; + i { height: 20px; } } } .badge-category { - font-weight: normal; text-transform: capitalize; - - } } diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index eb8bb2581d8..cd8848370f1 100644 --- a/app/controllers/list_controller.rb +++ b/app/controllers/list_controller.rb @@ -10,7 +10,7 @@ class ListController < ApplicationController :top_lists, TopTopic.periods.map { |p| "top_#{p}".to_sym } ].flatten - before_filter :set_category, only: [:category, :category_feed] + before_filter :set_category, only: [:category_feed] skip_before_filter :check_xhr # Create our filters @@ -151,19 +151,19 @@ class ListController < ApplicationController private def set_category - slug = params.fetch(:category) - parent_slug = params[:parent_category] + slug_or_id = params.fetch(:category) + parent_slug_or_id = params[:parent_category] parent_category_id = nil if parent_slug.present? - parent_category_id = Category.where(slug: parent_slug).pluck(:id).first || - Category.where(id: parent_slug.to_i).pluck(:id).first + parent_category_id = Category.where(slug: parent_slug_or_id).pluck(:id).first || + Category.where(id: parent_slug_or_id.to_i).pluck(:id).first raise Discourse::NotFound.new if parent_category_id.blank? end - @category = Category.where(slug: slug, parent_category_id: parent_category_id).includes(:featured_users).first || - Category.where(id: slug.to_i, parent_category_id: parent_category_id).includes(:featured_users).first + @category = Category.where(slug: slug_or_id, parent_category_id: parent_category_id).includes(:featured_users).first || + Category.where(id: slug_or_id.to_i, parent_category_id: parent_category_id).includes(:featured_users).first end def build_topic_list_options @@ -172,7 +172,7 @@ class ListController < ApplicationController menu_item = menu_items.select { |item| item.query_should_exclude_category?(action_name, params[:format]) }.first # exclude_category = 1. from params / 2. parsed from top menu / 3. nil - result = { + options = { page: params[:page], topic_ids: param_to_integer_list(:topic_ids), exclude_category: (params[:exclude_category] || menu_item.try(:filter)), @@ -181,8 +181,9 @@ class ListController < ApplicationController sort_descending: params[:sort_descending], status: params[:status] } - result[:no_subcategories] = true if params[:no_subcategories] == 'true' - result + options[:no_subcategories] = true if params[:no_subcategories] == 'true' + + options end def list_target_user diff --git a/app/models/user.rb b/app/models/user.rb index 6868e1a203c..fb494487756 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -607,7 +607,7 @@ class User < ActiveRecord::Base private def previous_visit_at_update_required?(timestamp) - seen_before? && last_seen_at < (timestamp - SiteSetting.previous_visit_timeout_hours.hours) + seen_before? && (last_seen_at < (timestamp - SiteSetting.previous_visit_timeout_hours.hours)) end def update_previous_visit(timestamp) diff --git a/app/serializers/top_list_serializer.rb b/app/serializers/top_list_serializer.rb index bc6bfd71a1d..d39b8a45373 100644 --- a/app/serializers/top_list_serializer.rb +++ b/app/serializers/top_list_serializer.rb @@ -1,5 +1,11 @@ class TopListSerializer < ApplicationSerializer + attribute :can_create_topic + + def can_create_topic + scope.can_create?(Topic) + end + TopTopic.periods.each do |period| attribute period diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index f54c1566337..35c33a3b95c 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1118,6 +1118,14 @@ en: top: title: "Top" help: "a selection of the best topics" + yearly: + title: "Top Yearly" + monthly: + title: "Top Monthly" + weekly: + title: "Top Weekly" + daily: + title: "Top Daily" this_year: "This year" this_month: "This month" this_week: "This week" diff --git a/config/locales/server.cs.yml b/config/locales/server.cs.yml index 1d7f6941968..e05fb9c43cb 100644 --- a/config/locales/server.cs.yml +++ b/config/locales/server.cs.yml @@ -540,7 +540,7 @@ cs: ga_domain_name: "Doménové jméno pro Google analytics, např. mysite.com; viz http://google.com/analytics" enable_escaped_fragments: "Povolit alternativní řešení, které pomůže starým webovým robotům indexovat váš web. VAROVÁNÍ: povolte pouze v případě, že to opravdu potřebujete." enable_noscript_support: "Povolit podporu <noscript> tagu" - top_menu: "Určuje, které položky se zobrazí v navigaci na hlavní stránce a v jakém pořadí. Příklad: latest|hot|read|starred|unread|new|posted|categories" + top_menu: "Určuje, které položky se zobrazí v navigaci na hlavní stránce a v jakém pořadí. Příklad: latest|new|unread|starred|categories|top|read|posted" post_menu: "Určuje, které položky se zobrazí v menu u příspěvku a v jakém pořadí. Příklad: like|edit|flag|delete|share|bookmark|reply" share_links: "Určuje, které položky se zobrazí ve sdílecím dialogu a v jakém pořadí. Příklad: twitter|facebook|google+" track_external_right_clicks: "Počítat kliknutí na externí odkazy pravým tlačítkem (např. otevření do nové záložky); defaultně zakázáno kvůli přepisu URL" diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml index 205a895e21f..600f8a6e004 100644 --- a/config/locales/server.da.yml +++ b/config/locales/server.da.yml @@ -599,7 +599,7 @@ da: ga_domain_name: "Google analytics domænenavn, f.eks.: example.com; se http://google.com/analytics." enable_escaped_fragments: "Aktivér workaround som kan hjælpe ældre webcrawlers med at indeksere sitet. ADVARSEL: aktivér kun hvis du har behov for det." enable_noscript_support: "Aktivér standard webcrawler søgemaskineunderstøttelse vha. noscript-tagget" - top_menu: "Angiv hvilke elementer der skal vises i hjemmesidenavigationen, og i hvilken rækkefølge. Eksempel: latest|hot|read|starred|unread|new|posted|categories." + top_menu: "Angiv hvilke elementer der skal vises i hjemmesidenavigationen, og i hvilken rækkefølge. Eksempel: latest|new|unread|starred|categories|top|read|posted." post_menu: "Angiv hvilke elementer der skal vises i indlægsmenuen, og i hvilken rækkefølge. Eksempel: like|edit|flag|delete|share|bookmark|reply." share_links: "Angiv hvilke elementer der skal vises i “del“-dialogboksen og i hvilken rækkefølge. Eksempel twitter|facebook|google+|email." track_external_right_clicks: "Spor højreklik på eksterne links (f.eks.: åbn i ny tab); deaktiveret som standard fordi den omskriver URLer" diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml index 9db5e619ba8..452480ddfa5 100644 --- a/config/locales/server.de.yml +++ b/config/locales/server.de.yml @@ -513,7 +513,7 @@ de: ga_domain_name: "Google Analytics Domänenname, zum Beispiel: mysite.com; siehe http://google.com/analytics" enable_escaped_fragments: "Aktiviere Umgehungslösung um älteren Suchmaschinen-Webcrawler zu helfen die Seite zu indexieren. ACHTUNG: Nur aktivieren falls wirklich nötig." enable_noscript_support: "Aktiviere standard Suchmaschinen-Webcrawler Unterstützung durch den noscript Tag" - top_menu: "Bestimme, welche Navigationselemente in welcher Reihenfolge auftauchen. Beispiel: latest|hot|read|starred|unread|new|posted|categories" + top_menu: "Bestimme, welche Navigationselemente in welcher Reihenfolge auftauchen. Beispiel: latest|new|unread|starred|categories|top|read|posted" post_menu: "Bestimme, welche Funktionen in welcher Reihenfolge im Beitragsmenü auftauchen. Beispiel: like|edit|flag|delete|share|bookmark|reply" share_links: "Bestimme, welche Dienste in welcher Reihenfolge im Teilen-Dialog auftauchen. Beispiel: twitter|facebook|google+|email" track_external_right_clicks: "Verfolge, welche externen Links per Rechtsklick geöffnet werden (zum Beispiel in einem neuen Browser-Tab). Standardmäßig deaktiviert, da dies URL-Rewrites erfordert." diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 58e0a0c1c77..3f134043ce3 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -600,7 +600,7 @@ en: ga_domain_name: "Google analytics domain name, eg: mysite.com; see http://google.com/analytics" enable_escaped_fragments: "Enable workaround solution to help older search engine webcrawlers index your site. WARNING: enable only if you have to." enable_noscript_support: "Enable standard webcrawler search engine support via the noscript tag" - top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|hot|read|starred|unread|new|posted|categories" + top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|starred|categories|top|read|posted" post_menu: "Determine which items appear on the post menu, and in what order. Example like|edit|flag|delete|share|bookmark|reply" share_links: "Determine which items appear on the share dialog, and in what order. Example twitter|facebook|google+|email" track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default because it rewrites URLs" diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml index 6694f767671..a979b6b715a 100644 --- a/config/locales/server.es.yml +++ b/config/locales/server.es.yml @@ -331,7 +331,7 @@ es: post_undo_action_window_mins: "Número de segundos en los que a los usuarios se les permite revertir la acción en un post (like, flag, etc)" must_approve_users: "Los administradores deben aprovar a todos los usuarios antes de tener acceso" ga_tracking_code: "Código de Google Analytics, ej: UA-12345678-9; visita http://google.com/analytics" - top_menu: "Determinar que items aparecen en la navegación de la home y en qué orden. Ejemplo latest|hot|read|starred|unread|new|posted|categories" + top_menu: "Determinar que items aparecen en la navegación de la home y en qué orden. Ejemplo latest|new|unread|starred|categories|top|read|posted" post_menu: "Determinar que items aparecen en el menú de post y en qué orden. Ejemplo like|edit|flag|delete|share|bookmark|reply" track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default because it rewrites URLs" topics_per_page: "Cuantos topics son cargados por defecto en la página de lista de topics" diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index 19d9a4e7a85..5ae5b133239 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -551,7 +551,7 @@ fr: ga_domain_name: "Domaine suivi par Google Analytics, par exemple : monsite.com, voir: http://google.com/analytics" enable_escaped_fragments: "Activer une solution de contournement afin d'aider d'ancien moteurs de recherche d'indexer votre site. ATTENTION : à activer seulement si vous le devez." enable_noscript_support: "Activer le support des moteurs de recherches standards via le tag noscript" - top_menu: "L'ordre des éléments dans le menu du haut. Exemple latest|hot|read|starred|unread|new|posted|categories" + top_menu: "L'ordre des éléments dans le menu du haut. Exemple latest|new|unread|starred|categories|top|read|posted" post_menu: "L'ordre des éléments dans le menu de rédaction. Exemple like|edit|flag|delete|share|bookmark|reply" share_links: "Liste ordonnée des boutons de partage. Exemple : twitter|facebook|google+|email" track_external_right_clicks: "Suivi des clics sur les liens externes (ex: ouverture dans un nouvel onglet) désactivé par défaut car nécessite une ré-écrite de toutes les urls" diff --git a/config/locales/server.id.yml b/config/locales/server.id.yml index 14e07f0e5fb..da918b9d200 100644 --- a/config/locales/server.id.yml +++ b/config/locales/server.id.yml @@ -342,7 +342,7 @@ id: post_undo_action_window_mins: "Number of seconds users are allowed to reverse actions on a post (like, flag, etc)" must_approve_users: "Admins must approve all users before they gain access" ga_tracking_code: "Google analytics tracking code code, eg: UA-12345678-9; see http://google.com/analytics" - top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|hot|read|starred|unread|new|posted|categories" + top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|starred|categories|top|read|posted" post_menu: "Determine which items appear on the post menu, and in what order. Example like|edit|flag|delete|share|bookmark|reply" track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default because it rewrites URLs" topics_per_page: "How many topics are loaded by default on the topics list page" diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml index 3af56b03dc0..95dfc83039d 100644 --- a/config/locales/server.it.yml +++ b/config/locales/server.it.yml @@ -462,7 +462,7 @@ it: must_approve_users: "Gli amministratori devono autorizzare ogni utente prima che esso abbia accesso" ga_tracking_code: "Codice Google Analytics per il tracking, es: UA-12345678-9; per informazioni http://google.com/analytics" ga_domain_name: "Nome del Dominio Google analytics, esempio: miosito.com; see http://google.com/analytics" - top_menu: "Determina quali elementi vengono mostrati nella navigazione in homepage, ed in quale ordine. Esempio latest|hot|read|starred|unread|new|posted|categories" + top_menu: "Determina quali elementi vengono mostrati nella navigazione in homepage, ed in quale ordine. Esempio latest|new|unread|starred|categories|top|read|posted" post_menu: "Determina quali elementi vengono mostrati nel menù del post, ed in quale ordine. Esempio like|edit|flag|delete|share|bookmark|reply" share_links: "Determina quali elementi vengono mostrati nella dialog di condivisione e in quale ordine. Esempio twitter|facebook|google+" track_external_right_clicks: "Traccia i link esterni sui quali viene fatto click destro (es: apri in una nuova tab). Disabilitato di default perché viene fatto il rewrite delle URL" diff --git a/config/locales/server.ja.yml b/config/locales/server.ja.yml index c929d566a18..0655ed29628 100644 --- a/config/locales/server.ja.yml +++ b/config/locales/server.ja.yml @@ -533,7 +533,7 @@ ja: ga_domain_name: "Google analytics のドメイン名。例: mysite.com; 参考 http://google.com/analytics" enable_escaped_fragments: "古いサーチエンジンクローラがあなたのサイトのインデックスを構築するのをサポートするワークアラウンドを有効にする。注意: 必要な場合のみ有効にすることを推奨。" enable_noscript_support: "noscript タグ経由でアクセスしてきた標準サーチエンジンクローラのサポートを有効にする" - top_menu: "ホームページナビゲーションに表示する項目を指定。例 latest|hot|read|starred|unread|new|posted|categories" + top_menu: "ホームページナビゲーションに表示する項目を指定。例 latest|new|unread|starred|categories|top|read|posted" post_menu: "ポストメニューに表示する項目を指定。例 like|edit|flag|delete|share|bookmark|reply" share_links: "シェアダイアログに表示する項目を指定。例 twitter|facebook|google+|email" track_external_right_clicks: "右クリックされた外部リンクをトラックする (例: 新しいタブで開く)。URL のリライトを要するためデフォルトでは無効化されています" diff --git a/config/locales/server.ko.yml b/config/locales/server.ko.yml index 6e7ee7f3f66..d6334a47f15 100644 --- a/config/locales/server.ko.yml +++ b/config/locales/server.ko.yml @@ -552,7 +552,7 @@ ko: ga_domain_name: "Google analytics domain name, eg: mysite.com; see http://google.com/analytics" enable_escaped_fragments: "당신의 사이트의 오래된 정보를 검색하기 위한 웹크롤러 Workaround 솔루션을 활성. 주의: 꼭 필요할 때만 활성화" enable_noscript_support: "당신의 사이트를 검색하기 위한 noscript 테그를 이용한 일반적인 웹 크롤러를 활성화" - top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|hot|read|starred|unread|new|posted|categories" + top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|starred|categories|top|read|posted" post_menu: "게시물 메뉴에 어떤 사항들이 무슨 순서로 올라올지 결정합니다. 예: 좋아요|수정|신고|삭제|공유|북마크|답글" share_links: "Determine which items appear on the share dialog, and in what order. Example twitter|facebook|google+" track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default because it rewrites URLs" diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index 5602e15b290..ae074588786 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -564,7 +564,7 @@ nl: ga_domain_name: "Google analytics domeinnaam, bijv. mijnsite.nl; zie http://google.com/analytics" enable_escaped_fragments: "Schakel workaround in om oude crawlers je site te kunnen laten indexeren. WAARSCHUWING: gebruik dit alleen als je het echt nodig hebt." enable_noscript_support: "Ondersteun <noscript> tag" - top_menu: "De volgorde en selectie van items in het hoofdmenu. Bijvoorbeeld latest|hot|read|starred|unread|new|posted|categories" + top_menu: "De volgorde en selectie van items in het hoofdmenu. Bijvoorbeeld latest|new|unread|starred|categories|top|read|posted" post_menu: "De volgorde en selectie van items in het berichtmenu. Bijvoorbeeld like|edit|flag|delete|share|bookmark|reply" share_links: "De volgorde en selectie van items in het deelmenu. Bijvoorbeeld twitter|facebook|google+" track_external_right_clicks: "Houd bij welke externe links met de rechtermuisknop worden aangeklikt (bijv: open in nieuwe tab). Dit staat standaard uit, gezien het de URLs moet herschrijven, waardoor het gebruiksgemak afneemt" diff --git a/config/locales/server.pt.yml b/config/locales/server.pt.yml index b0f4c9084b6..f366d52603a 100644 --- a/config/locales/server.pt.yml +++ b/config/locales/server.pt.yml @@ -283,7 +283,7 @@ pt: post_undo_action_window_mins: "The window in which someone can reverse an action on a post (such as liking)" must_approve_users: "The owners of the forum must approve users before they gain access." ga_tracking_code: "Google analytics tracking code, see: http://google.com/analytics" - top_menu: "The order of the items in the top menu. Example latest|hot|read|starred|unread|new|posted|categories" + top_menu: "The order of the items in the top menu. Example latest|new|unread|starred|categories|top|read|posted" post_menu: "The order of the items on the post menu." max_length_show_reply: "Embedded replies to posts won't be shown if they directly below and are below this length." track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default cause it has to re-write urls, hurting usability" diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml index 9beb2855194..65b98892eae 100644 --- a/config/locales/server.pt_BR.yml +++ b/config/locales/server.pt_BR.yml @@ -544,7 +544,7 @@ pt_BR: ga_domain_name: "Nome de domínio no Google Analytics, exemplo: meusite.com; see http://google.com/analytics" enable_escaped_fragments: "Ativa solução alternativa que ajuda os mecanismos de busca antigos a indexarem o seu site. ALERTA: apenas ative se você realmente precisa disto." enable_noscript_support: "Ativar suporte a tag <noscript>" - top_menu: "A ordem dos items no menu de cima. Exemplo latest|hot|read|starred|unread|new|posted|categories" + top_menu: "A ordem dos items no menu de cima. Exemplo latest|new|unread|starred|categories|top|read|posted" post_menu: "A ordem dos items no menu da postagem." share_links: "Determine quais ítens aparecerem no diálogo de compartilhar, e em que ordem. Por exemplo: twitter|facebook|google+|email" track_external_right_clicks: "Rastrear cliques externos que são clicados com o botão direito (ex: abrir em nova aba) desativado por padrão, pois tem que reescrever urls, quebrando a usabilidade" diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml index 903d0a7ba44..8026cf7da6e 100644 --- a/config/locales/server.ru.yml +++ b/config/locales/server.ru.yml @@ -552,7 +552,7 @@ ru: ga_domain_name: 'Доменное имя для Google analytics, например: mysite.com; смотрите http://google.com/analytics' enable_escaped_fragments: 'Включить поддержку escaped_fragments для устаревших поисковых роботов (типа Яндекс). Внимание: включайте только при крайней необходимости.' enable_noscript_support: 'Включить поддержку тэга noscript для поисковых роботов' - top_menu: 'Определите, как должны располагаться элементы в навигации на главной странице. Пример: latest|hot|read|starred|unread|new|posted|categories' + top_menu: 'Определите, как должны располагаться элементы в навигации на главной странице. Пример: latest|new|unread|starred|categories|top|read|posted' post_menu: 'Определите, какие элементы должны отображаться в меню у сообщения и в какой последовательности. Пример: like|edit|flag|delete|share|bookmark|reply' share_links: 'Определите, какие элементы должны отображаться в меню «Поделиться» и в какой последовательности. Пример: twitter|facebook|google+' track_external_right_clicks: 'Отслеживать внешние ссылки, открытые правой кнопкой мыши (например: открыть в новой вкладке), по умолчанию отключено, так как это перезаписывает пути' diff --git a/config/locales/server.sv.yml b/config/locales/server.sv.yml index 4bd71603a5e..c867eb240b6 100644 --- a/config/locales/server.sv.yml +++ b/config/locales/server.sv.yml @@ -384,7 +384,7 @@ sv: post_undo_action_window_mins: "Number of seconds users are allowed to reverse actions on a post (like, flag, etc)" must_approve_users: "Admins must approve all users before they gain access" ga_tracking_code: "Google analytics tracking code code, eg: UA-12345678-9; see http://google.com/analytics" - top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|hot|read|starred|unread|new|posted|categories" + top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|starred|categories|top|read|posted" post_menu: "Determine which items appear on the post menu, and in what order. Example like|edit|flag|delete|share|bookmark|reply" share_links: "Determine which items appear on the share dialog, and in what order. Example twitter|facebook|google+|email" track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default because it rewrites URLs" diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml index 2de43c2cda6..6419dc01415 100644 --- a/config/locales/server.zh_CN.yml +++ b/config/locales/server.zh_CN.yml @@ -482,7 +482,7 @@ zh_CN: must_approve_users: "用户必须获得管理员批准方能访问" ga_tracking_code: "谷歌分析追踪代码,例如:UA-12345678-9。参考 http://google.com/analytics" ga_domain_name: "谷歌分析域名,例如:mysite.com;参考 http://google.com/analytics" - top_menu: "确定在主页导航条包含哪些条目,以及排列顺序。例如:latest|hot|read|starred|unread|new|posted|categories" + top_menu: "确定在主页导航条包含哪些条目,以及排列顺序。例如:latest|new|unread|starred|categories|top|read|posted" post_menu: "确定在帖子菜单条包含哪些条目,以及排列顺序。例如:like|edit|flag|delete|share|bookmark|reply" share_links: "确定在分享对话框里显示哪些条目、以什么顺序显示。例如 twitter|facebook|google+" track_external_right_clicks: "追踪外部链接的右键点击(例如:在浏览器新标签打开),缺省是禁用的,因为它会重写URL" diff --git a/config/routes.rb b/config/routes.rb index b6e3bea3af8..70d390e2ef2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -203,14 +203,12 @@ Discourse::Application.routes.draw do post "category/:category_id/move" => "categories#move", as: "category_move" get "category/:category.rss" => "list#category_feed", format: :rss, as: "category_feed" get "category/:category" => "list#category" - get "category/:category/more" => "list#category" get "category/:category/none" => "list#category_none" - get "category/:category/none/more" => "list#category_none" get "category/:parent_category/:category" => "list#category" - get "category/:parent_category/:category/more" => "list#category" get "top" => "list#top_lists" get "category/:category/l/top" => "list#top_lists" + get "category/:category/none/l/top" => "list#top_lists" get "category/:parent_category/:category/l/top" => "list#top_lists" TopTopic.periods.each do |period|