diff --git a/app/assets/javascripts/discourse/controllers/topic_controller.js b/app/assets/javascripts/discourse/controllers/topic_controller.js index a1f4812ebbe..6ed6aa8df8d 100644 --- a/app/assets/javascripts/discourse/controllers/topic_controller.js +++ b/app/assets/javascripts/discourse/controllers/topic_controller.js @@ -167,6 +167,11 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected this.get('content').setStatus('pinned', this.get('pinned_at') ? false : true); }, + togglePinnedGlobally: function() { + // Note that this is different than clearPin + this.get('content').setStatus('pinned_globally', this.get('pinned_at') ? false : true); + }, + toggleArchived: function() { this.get('content').toggleStatus('archived'); }, diff --git a/app/assets/javascripts/discourse/templates/topic_admin_menu.js.handlebars b/app/assets/javascripts/discourse/templates/topic_admin_menu.js.handlebars index e6e97348a78..24186ce776b 100644 --- a/app/assets/javascripts/discourse/templates/topic_admin_menu.js.handlebars +++ b/app/assets/javascripts/discourse/templates/topic_admin_menu.js.handlebars @@ -33,6 +33,7 @@ {{else}} + {{/if}} diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 2a76e8e6b53..f31fe6f96e6 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -365,7 +365,7 @@ class TopicsController < ApplicationController end def check_for_status_presence(key, attr) - invalid_param(key) unless %w(visible closed pinned archived).include?(attr) + invalid_param(key) unless %w(pinned_globally visible closed pinned archived).include?(attr) end def invalid_param(key) diff --git a/app/models/topic.rb b/app/models/topic.rb index 4a8af7a5832..2dc476c89db 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -618,8 +618,9 @@ class Topic < ActiveRecord::Base TopicUser.change(user.id, id, cleared_pinned_at: Time.now) end - def update_pinned(status) + def update_pinned(status, global=false) update_column(:pinned_at, status ? Time.now : nil) + update_column(:pinned_globally, global) end def draft_key diff --git a/app/models/topic_status_update.rb b/app/models/topic_status_update.rb index e166a46e56b..471a7b66553 100644 --- a/app/models/topic_status_update.rb +++ b/app/models/topic_status_update.rb @@ -14,8 +14,8 @@ TopicStatusUpdate = Struct.new(:topic, :user) do private def change(status) - if status.pinned? - topic.update_pinned status.enabled? + if status.pinned? || status.pinned_globally? + topic.update_pinned status.enabled?, status.pinned_globally? elsif status.autoclosed? topic.update_column 'closed', status.enabled? else @@ -67,7 +67,7 @@ TopicStatusUpdate = Struct.new(:topic, :user) do end Status = Struct.new(:name, :enabled) do - %w(pinned autoclosed closed).each do |status| + %w(pinned_globally pinned autoclosed closed).each do |status| define_method("#{status}?") { name == status } end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 2c779db59c7..a986b3d9f76 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -796,6 +796,7 @@ en: auto_close: "Auto Close" unpin: "Un-Pin Topic" pin: "Pin Topic" + pin_globally: "Pin Topic Globally" unarchive: "Unarchive Topic" archive: "Archive Topic" invisible: "Make Invisible" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 0b849de1430..adad0d20e0e 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -930,6 +930,9 @@ en: autoclosed_disabled: "This topic is now opened. New replies are allowed." pinned_enabled: "This topic is now pinned. It will appear at the top of its category until it is either unpinned by a moderator, or the Clear Pin button is pressed." pinned_disabled: "This topic is now unpinned. It will no longer appear at the top of its category." + + pinned_globally_enabled: "This topic is now pinned globally. It will appear at the top of its category and all topic lists until it is either unpinned by a moderator, or the Clear Pin button is pressed." + pinned_globally_disabled: "This topic is now unpinned. It will no longer appear at the top of its category." visible_enabled: "This topic is now visible. It will be displayed in topic lists." visible_disabled: "This topic is now invisible. It will no longer be displayed in any topic lists. The only way to access this topic is via direct link." diff --git a/db/migrate/20140407055830_add_pinned_globally_to_topics.rb b/db/migrate/20140407055830_add_pinned_globally_to_topics.rb new file mode 100644 index 00000000000..a450cf1bdab --- /dev/null +++ b/db/migrate/20140407055830_add_pinned_globally_to_topics.rb @@ -0,0 +1,12 @@ +class AddPinnedGloballyToTopics < ActiveRecord::Migration + def up + add_column :topics, :pinned_globally, :boolean, null: false, default: false + execute "UPDATE topics set pinned_globally = 't' where category_id = ( + SELECT value::int FROM site_settings WHERE name = 'uncategorized_category_id') AND pinned_at IS NOT NULL + " + end + + def down + remove_column :topics, :pinned_globally + end +end diff --git a/lib/topic_query_sql.rb b/lib/topic_query_sql.rb index ce0a54dcbd7..0df8c3ce7f0 100644 --- a/lib/topic_query_sql.rb +++ b/lib/topic_query_sql.rb @@ -31,7 +31,7 @@ module TopicQuerySQL # If you've clearned the pin, use bumped_at, otherwise put it at the top def order_nocategory_with_pinned_sql "CASE - WHEN topics.category_id = #{SiteSetting.uncategorized_category_id.to_i} and (COALESCE(topics.pinned_at, '#{lowest_date}') > COALESCE(tu.cleared_pinned_at, '#{lowest_date}')) + WHEN topics.pinned_globally and (COALESCE(topics.pinned_at, '#{lowest_date}') > COALESCE(tu.cleared_pinned_at, '#{lowest_date}')) THEN '#{highest_date}' ELSE topics.bumped_at END DESC" @@ -42,7 +42,7 @@ module TopicQuerySQL end def order_nocategory_basic_bumped - "CASE WHEN topics.category_id = #{SiteSetting.uncategorized_category_id.to_i} and (topics.pinned_at IS NOT NULL) THEN 0 ELSE 1 END, topics.bumped_at DESC" + "CASE WHEN topics.pinned_globally and (topics.pinned_at IS NOT NULL) THEN 0 ELSE 1 END, topics.bumped_at DESC" end def order_top_for(score) diff --git a/spec/components/topic_query_spec.rb b/spec/components/topic_query_spec.rb index daa46de6b10..3455fce1f91 100644 --- a/spec/components/topic_query_spec.rb +++ b/spec/components/topic_query_spec.rb @@ -101,6 +101,7 @@ describe TopicQuery do posts_count: 5, participant_count: 12, pinned_at: 10.minutes.ago, + pinned_globally: true, bumped_at: 10.minutes.ago) end let!(:archived_topic) do