mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 03:06:53 +08:00
FEATURE: Allow showing hashtag autocomplete results without term (#19219)
This commit allows us to type # in the UI and present autocomplete results immediately with the following logic for the topic composer, and reversed for the chat composer: * Categories the user can access and has not muted sorted by `topic_count` * Tags the user can access and has not muted sorted by `topic_count` * Chat channels the user is a member of sorted by `messages_count` So in effect, we allow searching for hashtags without a search term. To do this we add a new `search_without_term` to each data source so each one can define how it wants to handle this logic.
This commit is contained in:
@ -44,4 +44,27 @@ class Chat::ChatChannelHashtagDataSource
|
||||
def self.search_sort(search_results, _)
|
||||
search_results.sort_by { |result| result.text.downcase }
|
||||
end
|
||||
|
||||
def self.search_without_term(guardian, limit)
|
||||
if SiteSetting.enable_experimental_hashtag_autocomplete
|
||||
allowed_channel_ids_sql =
|
||||
Chat::ChatChannelFetcher.generate_allowed_channel_ids_sql(
|
||||
guardian,
|
||||
exclude_dm_channels: true,
|
||||
)
|
||||
ChatChannel
|
||||
.joins(
|
||||
"INNER JOIN user_chat_channel_memberships
|
||||
ON user_chat_channel_memberships.chat_channel_id = chat_channels.id
|
||||
AND user_chat_channel_memberships.user_id = #{guardian.user.id}
|
||||
AND user_chat_channel_memberships.following = true",
|
||||
)
|
||||
.where("chat_channels.id IN (#{allowed_channel_ids_sql})")
|
||||
.order(messages_count: :desc)
|
||||
.limit(limit)
|
||||
.map { |channel| channel_to_hashtag_item(guardian, channel) }
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -5,9 +5,24 @@ RSpec.describe Chat::ChatChannelHashtagDataSource do
|
||||
fab!(:category) { Fabricate(:category) }
|
||||
fab!(:group) { Fabricate(:group) }
|
||||
fab!(:private_category) { Fabricate(:private_category, group: group) }
|
||||
fab!(:channel1) { Fabricate(:chat_channel, slug: "random", name: "Zany Things", chatable: category, description: "Just weird stuff") }
|
||||
fab!(:channel1) do
|
||||
Fabricate(
|
||||
:chat_channel,
|
||||
slug: "random",
|
||||
name: "Zany Things",
|
||||
chatable: category,
|
||||
description: "Just weird stuff",
|
||||
messages_count: 245,
|
||||
)
|
||||
end
|
||||
fab!(:channel2) do
|
||||
Fabricate(:chat_channel, slug: "secret", name: "Secret Stuff", chatable: private_category)
|
||||
Fabricate(
|
||||
:chat_channel,
|
||||
slug: "secret",
|
||||
name: "Secret Stuff",
|
||||
chatable: private_category,
|
||||
messages_count: 78,
|
||||
)
|
||||
end
|
||||
let!(:guardian) { Guardian.new(user) }
|
||||
|
||||
@ -109,4 +124,41 @@ RSpec.describe Chat::ChatChannelHashtagDataSource do
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#search_without_term" do
|
||||
fab!(:channel3) { Fabricate(:chat_channel, slug: "general", messages_count: 24) }
|
||||
fab!(:channel4) { Fabricate(:chat_channel, slug: "chat", messages_count: 435) }
|
||||
fab!(:channel5) { Fabricate(:chat_channel, slug: "code-review", messages_count: 334) }
|
||||
fab!(:membership2) do
|
||||
Fabricate(:user_chat_channel_membership, user: user, chat_channel: channel1)
|
||||
end
|
||||
fab!(:membership2) do
|
||||
Fabricate(:user_chat_channel_membership, user: user, chat_channel: channel2)
|
||||
end
|
||||
fab!(:membership3) do
|
||||
Fabricate(:user_chat_channel_membership, user: user, chat_channel: channel3)
|
||||
end
|
||||
fab!(:membership4) do
|
||||
Fabricate(:user_chat_channel_membership, user: user, chat_channel: channel4)
|
||||
end
|
||||
fab!(:membership5) do
|
||||
Fabricate(:user_chat_channel_membership, user: user, chat_channel: channel5)
|
||||
end
|
||||
|
||||
it "returns distinct channels for messages that have been recently created in the past 2 weeks" do
|
||||
expect(described_class.search_without_term(guardian, 5).map(&:slug)).to eq(
|
||||
%w[chat code-review random general],
|
||||
)
|
||||
end
|
||||
|
||||
it "does not return channels the user does not have permission to view" do
|
||||
expect(described_class.search_without_term(guardian, 5).map(&:slug)).not_to include("secret")
|
||||
end
|
||||
|
||||
it "does not return channels where the user is not following the channel via user_chat_channel_memberships" do
|
||||
membership5.destroy
|
||||
membership3.update!(following: false)
|
||||
expect(described_class.search_without_term(guardian, 5).map(&:slug)).to eq(%w[chat random])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user