diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 6dd216ece36..2f1a11bbed6 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -2722,7 +2722,7 @@ en: <tr><td><code>status:open</code></td><td><code>status:closed</code></td><td><code>status:archived</code></td><td><code>status:noreplies</code></td><td><code>status:single_user</code></td></tr> <tr><td><code>category:foo</code></td><td><code>user:foo</code></td><td><code>group:foo</code></td><td><code>badge:foo</code></td><td></td></tr> <tr><td><code>in:likes</code></td><td><code>in:posted</code></td><td><code>in:watching</code></td><td><code>in:tracking</code></td><td><code>in:private</code></td></tr> - <tr><td><code>in:bookmarks</code></td><td><code>in:first</code></td><td colspan=3></td></tr> + <tr><td><code>in:bookmarks</code></td><td><code>in:first</code></td><td><code>in:pinned</code></td><td><code>in:unpinned</code></td><td></td></tr> <tr><td><code>posts_count:num</code></td><td><code>before:days or date</code></td><td><code>after:days or date</code></td> <td colspan=2></td></tr> </table> </p> diff --git a/lib/search.rb b/lib/search.rb index fb8b989a417..5bfd9d4e2ed 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 42a4f1866dc..7a0e580643b 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')