FEATURE: add mention count to threads (#29739)
Previously we only counted mentions that were made within channels, however for threads this was never implemented. This change adds a mention count to the ThreadUnreadsQuery, which is used for channel thread lists and the user thread list. We are also expanding channel mentions count to include mentions within threads. The goal is to have a more consistent urgent badge across chat, in places such as channel lists and the chat header.
This commit is contained in:
parent
cd6d2ffaa4
commit
5ce4af1aa6
|
@ -46,7 +46,6 @@ module Chat
|
|||
AND notifications.notification_type = :notification_type_mention
|
||||
AND (data::json->>'chat_message_id')::bigint > COALESCE(user_chat_channel_memberships.last_read_message_id, 0)
|
||||
AND (data::json->>'chat_channel_id')::bigint = memberships.chat_channel_id
|
||||
AND (chat_messages.thread_id IS NULL OR chat_messages.id = chat_threads.original_message_id)
|
||||
) AS mention_count,
|
||||
(
|
||||
SELECT COUNT(*) AS watched_threads_unread_count
|
||||
|
|
|
@ -59,7 +59,22 @@ module Chat
|
|||
AND user_chat_channel_memberships.muted = false
|
||||
AND user_chat_channel_memberships.user_id = :user_id
|
||||
) AS unread_count,
|
||||
0 as mention_count,
|
||||
(
|
||||
SELECT COUNT(*) AS mention_count
|
||||
FROM notifications
|
||||
INNER JOIN chat_messages ON chat_messages.id = (data::json->>'chat_message_id')::bigint
|
||||
INNER JOIN chat_channels ON chat_channels.id = chat_messages.chat_channel_id
|
||||
INNER JOIN user_chat_channel_memberships ON user_chat_channel_memberships.chat_channel_id = chat_messages.chat_channel_id
|
||||
LEFT JOIN chat_threads ON chat_threads.id = chat_messages.thread_id
|
||||
WHERE NOT read
|
||||
AND notifications.user_id = :user_id
|
||||
AND notifications.notification_type = :notification_type_mention
|
||||
AND user_chat_channel_memberships.user_id = :user_id
|
||||
AND chat_channels.threading_enabled
|
||||
AND chat_messages.deleted_at IS NULL
|
||||
AND chat_messages.thread_id = memberships.thread_id
|
||||
AND NOT user_chat_channel_memberships.muted
|
||||
) AS mention_count,
|
||||
(
|
||||
SELECT COUNT(*) AS watched_threads_unread_count
|
||||
FROM chat_messages
|
||||
|
@ -122,6 +137,7 @@ module Chat
|
|||
limit: MAX_THREADS,
|
||||
tracking_level: ::Chat::UserChatThreadMembership.notification_levels[:tracking],
|
||||
watching_level: ::Chat::UserChatThreadMembership.notification_levels[:watching],
|
||||
notification_type_mention: ::Notification.types[:chat_mention],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,6 +11,7 @@ export default class ChatChannelUnreadIndicator extends Component {
|
|||
get showUnreadIndicator() {
|
||||
return (
|
||||
this.args.channel.tracking.unreadCount > 0 ||
|
||||
this.args.channel.tracking.mentionCount > 0 ||
|
||||
this.args.channel.unreadThreadsCountSinceLastViewed > 0
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,10 @@ export default class ChatThreadUnreadIndicator extends Component {
|
|||
}
|
||||
|
||||
get urgentCount() {
|
||||
return this.args.thread.tracking.watchedThreadsUnreadCount;
|
||||
return (
|
||||
this.args.thread.tracking.mentionCount +
|
||||
this.args.thread.tracking.watchedThreadsUnreadCount
|
||||
);
|
||||
}
|
||||
|
||||
get showUnreadIndicator() {
|
||||
|
|
|
@ -225,14 +225,14 @@ describe Chat::ChannelUnreadsQuery do
|
|||
)
|
||||
end
|
||||
|
||||
it "does not include other thread messages in the mention count" do
|
||||
it "includes thread messages with mentions in the channel mention count" do
|
||||
thread_message_1 = Fabricate(:chat_message, chat_channel: channel_1, thread: thread)
|
||||
thread_message_2 = Fabricate(:chat_message, chat_channel: channel_1, thread: thread)
|
||||
create_mention(thread_message_1, channel_1)
|
||||
create_mention(thread_message_2, channel_1)
|
||||
expect(query.first).to eq(
|
||||
{
|
||||
mention_count: 0,
|
||||
mention_count: 2,
|
||||
unread_count: 1,
|
||||
watched_threads_unread_count: 0,
|
||||
channel_id: channel_1.id,
|
||||
|
|
|
@ -36,6 +36,24 @@ describe Chat::ThreadUnreadsQuery do
|
|||
thread_4.add(current_user)
|
||||
end
|
||||
|
||||
def create_mention(message, channel, thread)
|
||||
notification =
|
||||
Notification.create!(
|
||||
notification_type: Notification.types[:chat_mention],
|
||||
user_id: current_user.id,
|
||||
data: {
|
||||
chat_message_id: message.id,
|
||||
chat_channel_id: channel.id,
|
||||
thread_id: thread.id,
|
||||
}.to_json,
|
||||
)
|
||||
Chat::UserMention.create!(
|
||||
notifications: [notification],
|
||||
user: current_user,
|
||||
chat_message: message,
|
||||
)
|
||||
end
|
||||
|
||||
context "with unread messages across multiple threads" do
|
||||
fab!(:message_1) { Fabricate(:chat_message, chat_channel: channel_1, thread: thread_1) }
|
||||
fab!(:message_2) { Fabricate(:chat_message, chat_channel: channel_2, thread: thread_3) }
|
||||
|
@ -188,6 +206,87 @@ describe Chat::ThreadUnreadsQuery do
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "with mentions" do
|
||||
let!(:message) { create_mention(message_1, channel_1, thread_1) }
|
||||
|
||||
it "counts both unread messages and mentions separately" do
|
||||
expect(query.map(&:to_h)).to eq(
|
||||
[
|
||||
{
|
||||
channel_id: channel_1.id,
|
||||
thread_id: thread_1.id,
|
||||
mention_count: 1,
|
||||
unread_count: 1,
|
||||
watched_threads_unread_count: 0,
|
||||
},
|
||||
{
|
||||
channel_id: channel_1.id,
|
||||
thread_id: thread_2.id,
|
||||
mention_count: 0,
|
||||
unread_count: 0,
|
||||
watched_threads_unread_count: 0,
|
||||
},
|
||||
{
|
||||
channel_id: channel_2.id,
|
||||
thread_id: thread_3.id,
|
||||
mention_count: 0,
|
||||
unread_count: 1,
|
||||
watched_threads_unread_count: 0,
|
||||
},
|
||||
{
|
||||
channel_id: channel_2.id,
|
||||
thread_id: thread_4.id,
|
||||
mention_count: 0,
|
||||
unread_count: 1,
|
||||
watched_threads_unread_count: 0,
|
||||
},
|
||||
],
|
||||
)
|
||||
end
|
||||
|
||||
it "does not count mentions in muted channels" do
|
||||
channel_1.membership_for(current_user).update!(muted: true)
|
||||
|
||||
expect(query.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq(
|
||||
{
|
||||
thread_id: thread_1.id,
|
||||
channel_id: channel_1.id,
|
||||
unread_count: 0,
|
||||
mention_count: 0,
|
||||
watched_threads_unread_count: 0,
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
it "does not count mentions in threads when channel has threading_enabled = false" do
|
||||
channel_1.update!(threading_enabled: false)
|
||||
|
||||
expect(query.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq(
|
||||
{
|
||||
thread_id: thread_1.id,
|
||||
channel_id: channel_1.id,
|
||||
unread_count: 0,
|
||||
mention_count: 0,
|
||||
watched_threads_unread_count: 0,
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
it "does not count mentions in threads when the message is deleted" do
|
||||
message_1.trash!
|
||||
|
||||
expect(query.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq(
|
||||
{
|
||||
thread_id: thread_1.id,
|
||||
channel_id: channel_1.id,
|
||||
unread_count: 0,
|
||||
mention_count: 0,
|
||||
watched_threads_unread_count: 0,
|
||||
},
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when only the thread_ids are provided" do
|
||||
|
@ -254,6 +353,20 @@ describe Chat::ThreadUnreadsQuery do
|
|||
},
|
||||
)
|
||||
end
|
||||
|
||||
it "counts mentions but not unreads" do
|
||||
create_mention(message_1, channel_1, thread_1)
|
||||
|
||||
expect(query.map(&:to_h)).to include(
|
||||
{
|
||||
channel_id: channel_1.id,
|
||||
mention_count: 1,
|
||||
thread_id: thread_1.id,
|
||||
unread_count: 0,
|
||||
watched_threads_unread_count: 0,
|
||||
},
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is not a member of a thread" do
|
||||
|
|
Loading…
Reference in New Issue