FEATURE: Initial chat thread unread indicators (#21694)

This commit adds the thread index and individual thread
in the index list unread indicators, and wires up the message
bus events to mark the threads as read/unread when:

1. People send a new message in the thread
2. The user marks a thread as read

There are several hacky parts and TODOs to cover before
this is more functional:

1. We need to flesh out the thread scrolling and message
   visibility behaviour. Currently if you scroll to the end
   of the thread it will just mark the whole thread read
   unconditionally.
2. We need to send down the thread current user membership
   along with the last read message ID to the client and
   update that with read state.
3. We need to handle the sidebar unread dot for when threads
   are unread in the channel and clear it based on when the
   channel was last viewed.
4. We need to show some indicator of thread unreads on the
   thread indicators on original messages.
5. UI improvements to make the experience nicer and more
   like the actual design rather than just placeholders.

But, the basic premise around incrementing/decrementing the
thread overview count and showing which thread is unread
in the list is working as intended.
This commit is contained in:
Martin Brennan
2023-05-25 09:56:19 +02:00
committed by GitHub
parent eae47d82e2
commit b6c5a2da08
50 changed files with 665 additions and 167 deletions

View File

@ -25,7 +25,9 @@ describe "Thread list in side panel | drawer", type: :system, js: true do
visit("/")
chat_page.open_from_header
drawer_page.open_channel(channel)
expect(find(".chat-drawer-header__right-actions")).not_to have_css(".open-thread-list-btn")
expect(find(".chat-drawer-header__right-actions")).not_to have_css(
drawer_page.thread_list_button_selector,
)
end
end
@ -55,7 +57,7 @@ describe "Thread list in side panel | drawer", type: :system, js: true do
visit("/")
chat_page.open_from_header
drawer_page.open_channel(channel)
find(".open-thread-list-btn").click
drawer_page.open_thread_list
expect(drawer_page).to have_open_thread_list
end
@ -63,7 +65,7 @@ describe "Thread list in side panel | drawer", type: :system, js: true do
visit("/")
chat_page.open_from_header
drawer_page.open_channel(channel)
find(".open-thread-list-btn").click
drawer_page.open_thread_list
expect(drawer_page).to have_open_thread_list
expect(thread_list_page).to have_content(thread_1.title)
expect(thread_list_page).to have_content(thread_2.title)
@ -73,7 +75,7 @@ describe "Thread list in side panel | drawer", type: :system, js: true do
visit("/")
chat_page.open_from_header
drawer_page.open_channel(channel)
find(".open-thread-list-btn").click
drawer_page.open_thread_list
expect(drawer_page).to have_open_thread_list
thread_list_page.item_by_id(thread_1.id).click
expect(drawer_page).to have_open_thread(thread_1)

View File

@ -20,7 +20,7 @@ describe "Thread list in side panel | full page", type: :system, js: true do
context "when there are no threads that the user is participating in" do
it "shows a message" do
chat_page.visit_channel(channel)
chat_page.open_thread_list
channel_page.open_thread_list
expect(page).to have_content(I18n.t("js.chat.threads.none"))
end
end
@ -37,14 +37,14 @@ describe "Thread list in side panel | full page", type: :system, js: true do
it "shows a default title for threads without a title" do
chat_page.visit_channel(channel)
chat_page.open_thread_list
channel_page.open_thread_list
expect(page).to have_content(I18n.t("js.chat.thread.default_title", thread_id: thread_1.id))
end
it "shows the thread title with emoji" do
thread_1.update!(title: "What is for dinner? :hamburger:")
chat_page.visit_channel(channel)
chat_page.open_thread_list
channel_page.open_thread_list
expect(thread_list_page.item_by_id(thread_1.id)).to have_content("What is for dinner?")
expect(thread_list_page.item_by_id(thread_1.id)).to have_css("img.emoji[alt='hamburger']")
end
@ -53,7 +53,7 @@ describe "Thread list in side panel | full page", type: :system, js: true do
thread_1.original_message.update!(message: "This is a long message for the excerpt")
thread_1.original_message.rebake!
chat_page.visit_channel(channel)
chat_page.open_thread_list
channel_page.open_thread_list
expect(thread_list_page.item_by_id(thread_1.id)).to have_content(
"This is a long message for the excerpt",
)
@ -61,7 +61,7 @@ describe "Thread list in side panel | full page", type: :system, js: true do
it "shows the thread original message user username and avatar" do
chat_page.visit_channel(channel)
chat_page.open_thread_list
channel_page.open_thread_list
expect(thread_list_page.item_by_id(thread_1.id)).to have_css(
".chat-thread-original-message__avatar .chat-user-avatar .chat-user-avatar-container img",
)
@ -72,7 +72,7 @@ describe "Thread list in side panel | full page", type: :system, js: true do
it "opens a thread" do
chat_page.visit_channel(channel)
chat_page.open_thread_list
channel_page.open_thread_list
thread_list_page.item_by_id(thread_1.id).click
expect(side_panel).to have_open_thread(thread_1)
end
@ -82,7 +82,7 @@ describe "Thread list in side panel | full page", type: :system, js: true do
def open_thread_list
chat_page.visit_channel(channel)
chat_page.open_thread_list
channel_page.open_thread_list
expect(side_panel).to have_open_thread_list
end