UX: update chat channel sorting to include unread threads (#29617)

Adds channels with unread threads (watching/tracking) to the sorting logic for both public and direct message channels.

Previously channels with unread threads could easily be missed as we didn't bump them to the top when new thread replies were created.

We are also adding a blue unread badge next to DM channels when there is an unread thread, as previously they weren't appearing as unread within the DMs tab (they only showed within the My Threads section).
This commit is contained in:
David Battersby
2024-11-08 12:31:03 +04:00
committed by GitHub
parent f573fd8f5e
commit 534e8c1628
6 changed files with 167 additions and 57 deletions

View File

@ -36,8 +36,20 @@ RSpec.describe "List channels | Drawer", type: :system do
context "when multiple channels are present" do
fab!(:channel_1) { Fabricate(:category_channel, name: "a channel") }
fab!(:channel_2) { Fabricate(:category_channel, name: "b channel") }
fab!(:channel_3) { Fabricate(:category_channel, name: "c channel") }
fab!(:channel_3) { Fabricate(:category_channel, name: "c channel", threading_enabled: true) }
fab!(:channel_4) { Fabricate(:category_channel, name: "d channel") }
fab!(:message) do
Fabricate(:chat_message, chat_channel: channel_3, user: current_user, use_service: true)
end
fab!(:thread) do
Fabricate(
:chat_thread,
channel: channel_3,
original_message: message,
with_replies: 2,
use_service: true,
)
end
before do
channel_1.add(current_user)
@ -46,32 +58,31 @@ RSpec.describe "List channels | Drawer", type: :system do
channel_4.add(current_user)
end
it "sorts them by urgent, unread, then by slug" do
it "sorts them by urgent, unread messages or threads, then by slug" do
drawer_page.visit_index
Fabricate(
:chat_message,
chat_channel: channel_1,
created_at: 5.minutes.ago,
use_service: true,
)
Fabricate(
:chat_message,
chat_channel: channel_2,
created_at: 2.minutes.ago,
use_service: true,
)
Fabricate(
:chat_message,
chat_channel: channel_3,
chat_channel: channel_4,
message: "@#{current_user.username}",
use_service: true,
)
expect(drawer_page).to have_channel_at_position(channel_4, 1)
expect(drawer_page).to have_channel_at_position(channel_3, 2)
expect(drawer_page).to have_channel_at_position(channel_1, 3)
expect(drawer_page).to have_channel_at_position(channel_2, 4)
end
it "sorts by slug when multiple channels have the same unread count" do
drawer_page.visit_index
Fabricate(:chat_message, chat_channel: channel_2, use_service: true)
Fabricate(:chat_message, chat_channel: channel_4, use_service: true)
expect(drawer_page).to have_channel_at_position(channel_3, 1)
expect(drawer_page).to have_channel_at_position(channel_1, 2)
expect(drawer_page).to have_channel_at_position(channel_2, 3)
expect(drawer_page).to have_channel_at_position(channel_2, 1)
expect(drawer_page).to have_channel_at_position(channel_3, 2)
expect(drawer_page).to have_channel_at_position(channel_4, 3)
expect(drawer_page).to have_channel_at_position(channel_1, 4)
end
end
end
@ -108,19 +119,71 @@ RSpec.describe "List channels | Drawer", type: :system do
context "when multiple channels are present" do
fab!(:user_1) { Fabricate(:user) }
fab!(:user_2) { Fabricate(:user) }
fab!(:user_3) { Fabricate(:user) }
fab!(:dm_channel_1) { Fabricate(:direct_message_channel, users: [current_user]) }
fab!(:dm_channel_2) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
before do
Fabricate(:chat_message, chat_channel: dm_channel_2, user: user_1, use_service: true)
end
fab!(:dm_channel_3) { Fabricate(:direct_message_channel, users: [current_user, user_2]) }
fab!(:dm_channel_4) { Fabricate(:direct_message_channel, users: [current_user, user_3]) }
it "sorts them by latest activity" do
drawer_page.visit_index
drawer_page.click_direct_messages
Fabricate(:chat_message, chat_channel: dm_channel_2, user: user_1, use_service: true)
# last message was read but the created at date is used for sorting
message =
Fabricate(:chat_message, chat_channel: dm_channel_4, user: user_3, use_service: true)
dm_channel_4.membership_for(current_user).mark_read!(message.id)
expect(drawer_page).to have_channel_at_position(dm_channel_2, 1)
expect(drawer_page).to have_channel_at_position(dm_channel_1, 2)
expect(drawer_page).to have_urgent_channel(dm_channel_2)
expect(drawer_page).to have_channel_at_position(dm_channel_4, 2)
expect(drawer_page).to have_channel_at_position(dm_channel_1, 3)
expect(drawer_page).to have_channel_at_position(dm_channel_3, 4)
end
it "sorts channels with threads by urgency" do
drawer_page.visit_index
drawer_page.click_direct_messages
Fabricate(
:chat_thread,
notification_level: :watching,
original_message:
Fabricate(
:chat_message,
chat_channel: dm_channel_4,
user: current_user,
use_service: true,
),
with_replies: 2,
use_service: true,
)
Fabricate(
:chat_thread,
original_message:
Fabricate(
:chat_message,
chat_channel: dm_channel_3,
user: current_user,
use_service: true,
),
with_replies: 2,
use_service: true,
)
expect(drawer_page).to have_channel_at_position(dm_channel_4, 1)
expect(drawer_page).to have_urgent_channel(dm_channel_4)
expect(drawer_page).to have_channel_at_position(dm_channel_3, 2)
expect(drawer_page).to have_unread_channel(dm_channel_3)
expect(drawer_page).to have_channel_at_position(dm_channel_1, 3)
expect(drawer_page).to have_channel_at_position(dm_channel_2, 4)
end
end
end

View File

@ -37,9 +37,17 @@ module PageObjects
has_no_css?(channel_row_selector(channel))
end
def has_unread_channel?(channel, count: nil, wait: Capybara.default_max_wait_time)
def has_unread_channel?(
channel,
count: nil,
urgent: false,
wait: Capybara.default_max_wait_time
)
unread_indicator_selector =
"#{channel_row_selector(channel)} .chat-channel-unread-indicator"
unread_indicator_selector += ".-urgent" if urgent
has_css?(unread_indicator_selector) &&
if count
has_css?(

View File

@ -70,6 +70,10 @@ module PageObjects
channels_index.has_no_unread_channel?(channel)
end
def has_urgent_channel?(channel)
channels_index.has_unread_channel?(channel, urgent: true)
end
def has_user_threads_section?
has_css?("#c-footer-threads")
end