diff --git a/app/assets/javascripts/discourse/controllers/list_controller.js b/app/assets/javascripts/discourse/controllers/list_controller.js
index 232ada03a8f..64701102927 100644
--- a/app/assets/javascripts/discourse/controllers/list_controller.js
+++ b/app/assets/javascripts/discourse/controllers/list_controller.js
@@ -46,14 +46,14 @@ Discourse.ListController = Discourse.Controller.extend({
@returns {Ember.Deferred} the promise that will resolve to the list of items.
**/
load: function(filterMode) {
- var listController = this;
+ var self = this;
this.set('loading', true);
var trackingState = Discourse.TopicTrackingState.current();
if (filterMode === 'categories') {
return Discourse.CategoryList.list(filterMode).then(function(items) {
- listController.setProperties({
+ self.setProperties({
loading: false,
filterMode: filterMode,
categoryMode: true,
@@ -75,7 +75,7 @@ Discourse.ListController = Discourse.Controller.extend({
}
return Discourse.TopicList.list(current).then(function(items) {
- listController.setProperties({
+ self.setProperties({
loading: false,
filterMode: filterMode,
draft: items.draft,
diff --git a/app/assets/javascripts/discourse/controllers/list_topics_controller.js b/app/assets/javascripts/discourse/controllers/list_topics_controller.js
index 6c099a6b668..732924018d4 100644
--- a/app/assets/javascripts/discourse/controllers/list_topics_controller.js
+++ b/app/assets/javascripts/discourse/controllers/list_topics_controller.js
@@ -15,6 +15,10 @@ Discourse.ListTopicsController = Discourse.ObjectController.extend({
latest: Ember.computed.equal('filter', 'latest'),
+ topicListReloading: function() {
+ return (!this.get('controllers.list.loading')) && (!this.get('loaded'));
+ }.property('loaded', 'controllers.list.loading'),
+
categories: function() {
return Discourse.Category.list();
}.property(),
diff --git a/app/assets/javascripts/discourse/templates/components/discourse-basic-topic-list.js.handlebars b/app/assets/javascripts/discourse/templates/components/discourse-basic-topic-list.js.handlebars
index a8b67a62a3c..3a524253ff1 100644
--- a/app/assets/javascripts/discourse/templates/components/discourse-basic-topic-list.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/components/discourse-basic-topic-list.js.handlebars
@@ -5,7 +5,7 @@
{{#discourse-heading sortBy="default" sortOrder=sortOrder}}
{{i18n topic.title}}
{{/discourse-heading}}
- {{#discourse-heading}}
+ {{#discourse-heading sortBy="category" sortOrder=sortOrder}}
{{i18n category_title}}
{{/discourse-heading}}
{{#discourse-heading sortBy="posts" number=true sortOrder=sortOrder}}
diff --git a/app/assets/javascripts/discourse/templates/components/discourse-topic-list-loading.js.handlebars b/app/assets/javascripts/discourse/templates/components/discourse-topic-list-loading.js.handlebars
new file mode 100644
index 00000000000..5883b28e7a3
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/discourse-topic-list-loading.js.handlebars
@@ -0,0 +1,3 @@
+
- {{#if loading}}
-
-
-
-
- {{i18n loading}}
- |
-
-
-
- {{/if}}
-
+ {{discourse-topic-list-loading loading=loading}}
{{outlet listView}}
diff --git a/app/assets/javascripts/discourse/templates/list/topics.js.handlebars b/app/assets/javascripts/discourse/templates/list/topics.js.handlebars
index 702cb135a36..d064c96c8f7 100644
--- a/app/assets/javascripts/discourse/templates/list/topics.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/list/topics.js.handlebars
@@ -1,3 +1,5 @@
+{{discourse-topic-list-loading loading=topicListReloading}}
+
{{#unless loading}}
{{#if loaded}}
@@ -16,17 +18,29 @@
{{#if currentUser}}
|
{{/if}}
-
+ {{#discourse-heading sortBy="default" sortOrder=sortOrder}}
{{i18n topic.title}}
- |
+ {{/discourse-heading}}
{{#unless category}}
- {{i18n category_title}} |
+ {{#discourse-heading sortBy="category" sortOrder=sortOrder}}
+ {{i18n category_title}}
+ {{/discourse-heading}}
{{/unless}}
- {{i18n top_contributors}} |
- {{i18n posts}} |
- {{i18n likes}} |
- {{i18n views}} |
- {{i18n activity}} |
+ {{#discourse-heading sortBy="posters" sortOrder=sortOrder}}
+ {{i18n top_contributors}}
+ {{/discourse-heading}}
+ {{#discourse-heading sortBy="posts" number=true sortOrder=sortOrder}}
+ {{i18n posts}}
+ {{/discourse-heading}}
+ {{#discourse-heading sortBy="likes" number=true sortOrder=sortOrder}}
+ {{i18n likes}}
+ {{/discourse-heading}}
+ {{#discourse-heading sortBy="views" number=true sortOrder=sortOrder}}
+ {{i18n views}}
+ {{/discourse-heading}}
+ {{#discourse-heading sortBy="activity" number=true colspan="2" sortOrder=sortOrder}}
+ {{i18n activity}}
+ {{/discourse-heading}}
@@ -67,6 +81,5 @@
{{/if}}
-
{{/if}}
{{/unless}}
diff --git a/app/assets/stylesheets/desktop/topic-list.scss b/app/assets/stylesheets/desktop/topic-list.scss
index f3aef910f97..15a365b2033 100644
--- a/app/assets/stylesheets/desktop/topic-list.scss
+++ b/app/assets/stylesheets/desktop/topic-list.scss
@@ -178,7 +178,7 @@
width: 140px;
}
.posters {
- width: 150px;
+ width: 170px;
> a {
float: left;
margin-right: 4px;
@@ -206,7 +206,13 @@
@include unselectable;
}
.likes {
- width: 50px;
+ width: 65px;
+ }
+ .views {
+ width: 65px;
+ }
+ .posts {
+ width: 65px;
}
.activity {
width: 50px;
@@ -216,20 +222,6 @@
}
}
-.paginated-topics-list {
- #topic-list {
- .posts {
- width: 95px;
- }
- .likes {
- width: 95px;
- }
- .views {
- width: 95px;
- }
-
- }
-}
#topic-list tbody tr.has-excerpt .star {
vertical-align: top;
diff --git a/lib/topic_query.rb b/lib/topic_query.rb
index f8eda75320e..f9608a104cf 100644
--- a/lib/topic_query.rb
+++ b/lib/topic_query.rb
@@ -24,7 +24,9 @@ class TopicQuery
'likes' => 'like_count',
'views' => 'views',
'posts' => 'posts_count',
- 'activity' => 'bumped_at'
+ 'activity' => 'bumped_at',
+ 'posters' => 'participant_count',
+ 'category' => 'category_id'
}
def initialize(user=nil, options={})
@@ -173,10 +175,23 @@ class TopicQuery
# If we are sorting in the default order desc, we should consider including pinned
# topics. Otherwise, just use bumped_at.
if sort_column == 'default'
- return default_ordering(result, options) if sort_dir == 'DESC'
+ if sort_dir == 'DESC'
+
+ # If something requires a custom order, for example "unread" which sorts the least read
+ # to the top, do nothing
+ return result if options[:unordered]
+
+ # Otherwise apply our default ordering
+ return default_ordering(result, options)
+ end
sort_column = 'bumped_at'
end
+ # If we are sorting by category, actually use the name
+ if sort_column == 'category_id'
+ return result.references(:categories).order(TopicQuerySQL.order_by_category_sql(sort_dir))
+ end
+
result.order("topics.#{sort_column} #{sort_dir}")
end
@@ -203,13 +218,10 @@ class TopicQuery
result = result.references(:categories)
end
- result = apply_ordering(result, options) unless options[:unordered]
-
+ result = apply_ordering(result, options)
result = result.listable_topics.includes(category: :topic_only_relative_url)
result = result.where('categories.name is null or categories.name <> ?', options[:exclude_category]).references(:categories) if options[:exclude_category]
-
-
result = result.limit(options[:per_page]) unless options[:limit] == false
result = result.visible if options[:visible] || @user.nil? || @user.regular?
result = result.where('topics.id <> ?', options[:except_topic_id]).references(:topics) if options[:except_topic_id]
@@ -233,9 +245,7 @@ class TopicQuery
end
def new_results(options={})
- result = TopicQuery.new_filter(default_results(options.reverse_merge(:unordered => true)),
- @user.treat_as_new_topic_start_date)
-
+ result = TopicQuery.new_filter(default_results(options), @user.treat_as_new_topic_start_date)
suggested_ordering(result, options)
end
diff --git a/lib/topic_query_sql.rb b/lib/topic_query_sql.rb
index b8b7e259c6d..d9595e2833b 100644
--- a/lib/topic_query_sql.rb
+++ b/lib/topic_query_sql.rb
@@ -42,6 +42,10 @@ module TopicQuerySQL
end
end
+ def order_by_category_sql(dir)
+ "CASE WHEN categories.id = #{SiteSetting.uncategorized_category_id.to_i} THEN '' ELSE categories.name END #{dir}"
+ end
+
# If you've clearned the pin, use bumped_at, otherwise put it at the top
def order_nocategory_with_pinned_sql
"CASE
diff --git a/spec/components/topic_query_spec.rb b/spec/components/topic_query_spec.rb
index 7c6acd1e69c..0ef4402a47e 100644
--- a/spec/components/topic_query_spec.rb
+++ b/spec/components/topic_query_spec.rb
@@ -65,6 +65,7 @@ describe TopicQuery do
views: 100,
like_count: 66,
posts_count: 3,
+ participant_count: 11,
bumped_at: 15.minutes.ago)
end
let!(:pinned_topic) do
@@ -73,6 +74,7 @@ describe TopicQuery do
views: 10,
like_count: 100,
posts_count: 5,
+ participant_count: 12,
pinned_at: 10.minutes.ago,
bumped_at: 10.minutes.ago)
end
@@ -83,6 +85,7 @@ describe TopicQuery do
like_count: 30,
posts_count: 4,
archived: true,
+ participant_count: 1,
bumped_at: 6.minutes.ago)
end
let!(:invisible_topic) do
@@ -92,6 +95,7 @@ describe TopicQuery do
like_count: 5,
posts_count: 2,
visible: false,
+ participant_count: 3,
bumped_at: 5.minutes.ago)
end
let!(:closed_topic) do
@@ -101,6 +105,7 @@ describe TopicQuery do
like_count: 1,
posts_count: 1,
closed: true,
+ participant_count: 2,
bumped_at: 1.minute.ago)
end
@@ -149,6 +154,14 @@ describe TopicQuery do
ids_in_order('views', false).should == [invisible_topic, closed_topic, pinned_topic, archived_topic, regular_topic].map(&:id)
end
+ it "returns the topics in posters order if requested" do
+ ids_in_order('posters').should == [pinned_topic, regular_topic, invisible_topic, closed_topic, archived_topic].map(&:id)
+ end
+
+ it "returns the topics in reverse posters order if requested" do
+ ids_in_order('posters', false).should == [archived_topic, closed_topic, invisible_topic, regular_topic, pinned_topic].map(&:id)
+ end
+
end
end