diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 6dd216ece..2f1a11bbe 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -2722,7 +2722,7 @@ en:
status:open | status:closed | status:archived | status:noreplies | status:single_user |
category:foo | user:foo | group:foo | badge:foo | |
in:likes | in:posted | in:watching | in:tracking | in:private |
- in:bookmarks | in:first | |
+ in:bookmarks | in:first | in:pinned | in:unpinned | |
posts_count:num | before:days or date | after:days or date | |
diff --git a/lib/search.rb b/lib/search.rb
index fb8b989a4..5bfd9d4e2 100644
--- a/lib/search.rb
+++ b/lib/search.rb
@@ -219,6 +219,18 @@ class Search
posts.where("posts.post_number = 1")
end
+ advanced_filter(/in:pinned/) do |posts|
+ posts.where("topics.pinned_at IS NOT NULL")
+ end
+
+ advanced_filter(/in:unpinned/) do |posts|
+ if @guardian.user
+ posts.where("topics.pinned_at IS NOT NULL AND topics.id IN (
+ SELECT topic_id FROM topic_users WHERE user_id = ? AND cleared_pinned_at IS NOT NULL
+ )", @guardian.user.id)
+ end
+ end
+
advanced_filter(/badge:(.*)/) do |posts,match|
badge_id = Badge.where('name ilike ? OR id = ?', match, match.to_i).pluck(:id).first
if badge_id
diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb
index 42a4f1866..7a0e58064 100644
--- a/spec/components/search_spec.rb
+++ b/spec/components/search_spec.rb
@@ -408,6 +408,24 @@ describe Search do
describe 'Advanced search' do
+ it 'supports pinned and unpinned' do
+ topic = Fabricate(:topic)
+ Fabricate(:post, raw: 'hi this is a test 123 123', topic: topic)
+ _post = Fabricate(:post, raw: 'boom boom shake the room', topic: topic)
+
+ topic.update_pinned(true)
+
+ user = Fabricate(:user)
+ guardian = Guardian.new(user)
+
+ expect(Search.execute('boom in:pinned').posts.length).to eq(1)
+ expect(Search.execute('boom in:unpinned', guardian: guardian).posts.length).to eq(0)
+
+ topic.clear_pin_for(user)
+
+ expect(Search.execute('boom in:unpinned', guardian: guardian).posts.length).to eq(1)
+ end
+
it 'supports before and after in:first user:' do
time = Time.zone.parse('2001-05-20 2:55')