mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 02:40:53 -06:00
UI: refines thread list item (#23207)
It will now replies count and participants list. Also the title will be OM excerpt or user defined title, no more default "Thread" title. Lastly, the author of the last reply is also shown as prefix of it.
This commit is contained in:
parent
46c7e47f50
commit
39b598f304
@ -12,6 +12,7 @@ class Chat::Api::ChannelThreadsController < Chat::ApiController
|
||||
tracking: result.tracking,
|
||||
memberships: result.memberships,
|
||||
load_more_url: result.load_more_url,
|
||||
threads_participants: result.participants,
|
||||
),
|
||||
::Chat::ThreadListSerializer,
|
||||
root: false,
|
||||
|
@ -2,15 +2,30 @@
|
||||
|
||||
module Chat
|
||||
class ThreadsView
|
||||
attr_reader :user, :channel, :threads, :tracking, :memberships, :load_more_url
|
||||
attr_reader :user,
|
||||
:channel,
|
||||
:threads,
|
||||
:tracking,
|
||||
:memberships,
|
||||
:load_more_url,
|
||||
:threads_participants
|
||||
|
||||
def initialize(channel:, threads:, user:, tracking:, memberships:, load_more_url:)
|
||||
def initialize(
|
||||
channel:,
|
||||
threads:,
|
||||
user:,
|
||||
tracking:,
|
||||
memberships:,
|
||||
load_more_url:,
|
||||
threads_participants:
|
||||
)
|
||||
@channel = channel
|
||||
@threads = threads
|
||||
@user = user
|
||||
@tracking = tracking
|
||||
@memberships = memberships
|
||||
@load_more_url = load_more_url
|
||||
@threads_participants = threads_participants
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -12,6 +12,7 @@ module Chat
|
||||
membership: object.memberships.find { |m| m.thread_id == thread.id },
|
||||
include_thread_preview: true,
|
||||
include_thread_original_message: true,
|
||||
participants: object.threads_participants[thread.id],
|
||||
root: nil,
|
||||
)
|
||||
end
|
||||
|
@ -33,6 +33,7 @@ module Chat
|
||||
model :threads
|
||||
step :fetch_tracking
|
||||
step :fetch_memberships
|
||||
step :fetch_participants
|
||||
step :build_load_more_url
|
||||
|
||||
# @!visibility private
|
||||
@ -133,6 +134,10 @@ module Chat
|
||||
)
|
||||
end
|
||||
|
||||
def fetch_participants(threads:, **)
|
||||
context.participants = ::Chat::ThreadParticipantQuery.call(thread_ids: threads.map(&:id))
|
||||
end
|
||||
|
||||
def build_load_more_url(contract:, **)
|
||||
load_more_params = { offset: context.offset + context.limit }.to_query
|
||||
context.load_more_url =
|
||||
|
@ -17,8 +17,13 @@
|
||||
<div class="chat-thread-list-item__om-user-avatar">
|
||||
<Chat::UserAvatar @user={{@thread.originalMessage.user}} />
|
||||
</div>
|
||||
<div class="chat-thread-list-item__title overflow-ellipsis">
|
||||
{{replace-emoji this.title}}
|
||||
<div class="chat-thread-list-item__title">
|
||||
|
||||
{{#if this.title}}
|
||||
{{replace-emoji this.title}}
|
||||
{{else}}
|
||||
{{@thread.originalMessage.excerpt}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="chat-thread-list-item__unread-indicator">
|
||||
<Chat::ThreadList::Item::UnreadIndicator @thread={{@thread}} />
|
||||
@ -26,14 +31,26 @@
|
||||
</div>
|
||||
|
||||
<div class="chat-thread-list-item__body">
|
||||
{{replace-emoji (html-safe @thread.originalMessage.excerpt)}}
|
||||
<span class="chat-thread-list-item__last-reply-author">
|
||||
@{{@thread.preview.lastReplyUser.username}}:
|
||||
</span>
|
||||
<span class="chat-thread-list-item__last-reply-excerpt">
|
||||
{{replace-emoji (html-safe @thread.preview.lastReplyExcerpt)}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="chat-thread-list-item__metadata">
|
||||
<div class="chat-thread-list-item__participants"></div>
|
||||
<div class="chat-thread-list-item__last-reply">
|
||||
<Chat::Thread::Participants
|
||||
@thread={{@thread}}
|
||||
class="chat-thread-list-item__participants"
|
||||
/>
|
||||
<span class="chat-thread-list-item__replies-count">
|
||||
{{i18n "chat.thread.replies" count=@thread.preview.replyCount}}
|
||||
</span>
|
||||
<span class="chat-thread-list-item__metadata__separator">·</span>
|
||||
<div class="chat-thread-list-item__last-reply-timestamp">
|
||||
{{#if @thread.preview.lastReplyCreatedAt}}
|
||||
{{i18n "chat.thread.last_reply"}}
|
||||
<span>{{i18n "chat.thread.last_reply"}}</span>
|
||||
{{format-date @thread.preview.lastReplyCreatedAt leaveAgo="true"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
{{#if (gt @thread.preview.participantUsers.length 1)}}
|
||||
<div class="chat-thread-participants">
|
||||
<div class="chat-thread-participants" ...attributes>
|
||||
<div class="chat-thread-participants__avatar-group">
|
||||
{{#each @thread.preview.participantUsers as |user|}}
|
||||
<Chat::UserAvatar
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
import I18n from "I18n";
|
||||
import ChatMessagesManager from "discourse/plugins/chat/discourse/lib/chat-messages-manager";
|
||||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
@ -48,11 +47,7 @@ export default class ChatThread {
|
||||
? ChatMessage.create(channel, args.original_message)
|
||||
: null;
|
||||
|
||||
this.title =
|
||||
args.title ||
|
||||
`${I18n.t("chat.thread.default_title", {
|
||||
thread_id: this.id,
|
||||
})}`;
|
||||
this.title = args.title;
|
||||
|
||||
if (args.current_user_membership) {
|
||||
this.currentUserMembership = UserChatThreadMembership.create(
|
||||
|
@ -80,6 +80,7 @@
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 0.25rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
&__replies-count {
|
||||
|
@ -46,14 +46,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__metadata {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
&__last-reply-author {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
&__last-reply {
|
||||
&__metadata {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__metadata__separator {
|
||||
padding-inline: 0.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
&__participants {
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
&__replies-count {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
&__last-reply-timestamp,
|
||||
&__replies-count {
|
||||
color: var(--secondary-low);
|
||||
font-size: var(--font-down-1);
|
||||
@include ellipsis;
|
||||
}
|
||||
|
||||
&__header {
|
||||
@ -66,6 +86,7 @@
|
||||
&__title {
|
||||
flex: 1 1 auto;
|
||||
font-weight: bold;
|
||||
@include ellipsis;
|
||||
}
|
||||
|
||||
&__unread-indicator {
|
||||
@ -77,16 +98,10 @@
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
justify-content: center;
|
||||
color: var(--primary);
|
||||
|
||||
&:hover,
|
||||
&:visited {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
&__om-user-avatar {
|
||||
margin-right: 0.5rem;
|
||||
margin-right: 0.25rem;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
.chat-thread-participants {
|
||||
margin-left: 0.5rem;
|
||||
&__other-count {
|
||||
font-size: var(--font-down-2);
|
||||
color: var(--primary-high);
|
||||
@ -19,8 +18,6 @@
|
||||
width: auto !important;
|
||||
|
||||
.avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
@ -38,8 +35,6 @@
|
||||
margin-right: -10px;
|
||||
}
|
||||
.avatar {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border: 1px solid var(--primary-very-low);
|
||||
}
|
||||
}
|
||||
|
@ -579,7 +579,6 @@ en:
|
||||
thread:
|
||||
title: "Title"
|
||||
view_thread: View thread
|
||||
default_title: "Thread"
|
||||
replies:
|
||||
one: "%{count} reply"
|
||||
other: "%{count} replies"
|
||||
|
@ -260,6 +260,14 @@ RSpec.describe ::Chat::LookupChannelThreads do
|
||||
end
|
||||
end
|
||||
|
||||
describe "step - fetch_participants" do
|
||||
it "returns correct participants" do
|
||||
expect(result.participants).to eq(
|
||||
::Chat::ThreadParticipantQuery.call(thread_ids: [thread_1, thread_2, thread_3].map(&:id)),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "step - build_load_more_url" do
|
||||
it "returns a url with the correct params" do
|
||||
expect(result.load_more_url).to eq("/chat/api/channels/#{channel_1.id}/threads?offset=10")
|
||||
|
@ -40,7 +40,7 @@ module PageObjects
|
||||
end
|
||||
|
||||
def last_reply_datetime_selector(last_reply)
|
||||
".chat-thread-list-item__last-reply .relative-date[data-time='#{(last_reply.created_at.iso8601.to_time.to_f * 1000).to_i}']"
|
||||
".chat-thread-list-item__last-reply-timestamp .relative-date[data-time='#{(last_reply.created_at.iso8601.to_time.to_f * 1000).to_i}']"
|
||||
end
|
||||
|
||||
def has_no_unread_item?(id)
|
||||
|
@ -83,10 +83,11 @@ describe "Thread list in side panel | full page", type: :system do
|
||||
thread_2.add(current_user)
|
||||
end
|
||||
|
||||
it "shows a default title for threads without a title" do
|
||||
it "shows the OM excerpt for threads without a title" do
|
||||
chat_page.visit_channel(channel)
|
||||
channel_page.open_thread_list
|
||||
expect(page).to have_content(I18n.t("js.chat.thread.default_title", thread_id: thread_1.id))
|
||||
|
||||
expect(page).to have_content(thread_1.original_message.excerpt)
|
||||
end
|
||||
|
||||
it "shows the thread title with emoji" do
|
||||
@ -125,6 +126,28 @@ describe "Thread list in side panel | full page", type: :system do
|
||||
)
|
||||
end
|
||||
|
||||
it "shows replies count" do
|
||||
chat_page.visit_channel(channel)
|
||||
channel_page.open_thread_list
|
||||
|
||||
expect(thread_list_page.item_by_id(thread_1.id)).to have_css(
|
||||
".chat-thread-list-item__replies-count",
|
||||
text: I18n.t("js.chat.thread.replies", count: thread_1.replies_count_cache),
|
||||
)
|
||||
end
|
||||
|
||||
it "shows participants" do
|
||||
chat_page.visit_channel(channel)
|
||||
channel_page.open_thread_list
|
||||
|
||||
expect(thread_list_page.item_by_id(thread_1.id)).to have_css(
|
||||
".avatar[title='#{current_user.username}']",
|
||||
)
|
||||
expect(thread_list_page.item_by_id(thread_1.id)).to have_css(
|
||||
".avatar[title='#{other_user.username}']",
|
||||
)
|
||||
end
|
||||
|
||||
it "opens a thread" do
|
||||
chat_page.visit_channel(channel)
|
||||
channel_page.open_thread_list
|
||||
|
Loading…
Reference in New Issue
Block a user