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