FEATURE: Improving thread list item and header (#21749)

* Moved the settings cog from thread list to thread and
  put it in a new header component
* Remove thread original message component, no longer needed
  and the list item and thread indicator styles/content
  will be quite different
* Start adding content (unread indicator etc.) to the thread
  list item and changing structure to be more like designs
* Serialize the last thread reply when opening the thread index,
  show in list and update with message bus
This commit is contained in:
Martin Brennan
2023-05-29 09:11:55 +02:00
committed by GitHub
parent 8a9d3b3eed
commit 7a9514922b
45 changed files with 394 additions and 224 deletions

View File

@ -146,6 +146,12 @@ module Chat
PrettyText.excerpt(cooked, max_length)
end
def censored_excerpt(rich: false, max_length: 50)
WordWatcher.censor(
rich ? rich_excerpt(max_length: max_length) : excerpt(max_length: max_length),
)
end
def cooked_for_excerpt
(cooked.blank? && uploads.present?) ? "<p>#{uploads.first.original_filename}</p>" : cooked
end

View File

@ -23,6 +23,7 @@ module Chat
primary_key: :id,
class_name: "Chat::Message"
has_many :user_chat_thread_memberships
has_one :last_reply, -> { order("created_at DESC, id DESC") }, class_name: "Chat::Message"
enum :status, { open: 0, read_only: 1, closed: 2, archived: 3 }, scopes: false

View File

@ -8,7 +8,7 @@ module Chat
attributes :id, :cooked, :excerpt
def excerpt
WordWatcher.censor(object.excerpt)
object.censored_excerpt
end
def user

View File

@ -44,7 +44,7 @@ module Chat
end
def excerpt
WordWatcher.censor(object.excerpt)
object.censored_excerpt
end
def reactions

View File

@ -10,6 +10,7 @@ module Chat
thread,
scope: scope,
membership: object.memberships.find { |m| m.thread_id == thread.id },
include_preview: true,
root: nil,
)
end

View File

@ -3,7 +3,11 @@
module Chat
class ThreadOriginalMessageSerializer < Chat::MessageSerializer
def excerpt
WordWatcher.censor(object.rich_excerpt(max_length: Chat::Thread::EXCERPT_LENGTH))
object.censored_excerpt(rich: true, max_length: Chat::Thread::EXCERPT_LENGTH)
end
def include_available_flags?
false
end
def include_reactions?

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
module Chat
class ThreadPreviewSerializer < ApplicationSerializer
attributes :last_reply_created_at, :last_reply_excerpt, :last_reply_id
def last_reply_created_at
object.last_reply.created_at
end
def last_reply_id
object.last_reply.id
end
def last_reply_excerpt
object.last_reply.censored_excerpt
end
end
end

View File

@ -5,7 +5,14 @@ module Chat
has_one :original_message_user, serializer: BasicUserWithStatusSerializer, embed: :objects
has_one :original_message, serializer: Chat::ThreadOriginalMessageSerializer, embed: :objects
attributes :id, :title, :status, :channel_id, :meta, :reply_count, :current_user_membership
attributes :id,
:title,
:status,
:channel_id,
:meta,
:reply_count,
:current_user_membership,
:preview
def initialize(object, opts)
super(object, opts)
@ -24,6 +31,14 @@ module Chat
object.replies_count_cache || 0
end
def include_preview?
@opts[:include_preview]
end
def preview
Chat::ThreadPreviewSerializer.new(object, scope: scope, root: false).as_json
end
def include_current_user_membership?
@current_user_membership.present?
end

View File

@ -54,6 +54,7 @@ module Chat
Chat::Thread
.includes(
:channel,
:last_reply,
original_message_user: :user_status,
original_message: :chat_webhook_event,
)

View File

@ -72,6 +72,9 @@ module Chat
user_id: chat_message.user.id,
username: chat_message.user.username,
thread_id: chat_message.thread_id,
created_at: chat_message.created_at,
excerpt:
chat_message.censored_excerpt(rich: true, max_length: Chat::Thread::EXCERPT_LENGTH),
},
permissions(chat_channel),
)