mirror of
https://github.com/discourse/discourse.git
synced 2025-02-13 03:46:16 +08:00
![Martin Brennan](/assets/img/avatar_default.png)
This commit adds the initial part of thread indicator improvements: * Show the reply count, last reply date and excerpt, and the participants of the thread's avatars and count of additional participants * Add a participants component for the thread that can be reused for the list * Add a query class to get the thread participants * Live update the thread indicator more consistently with the last reply and participant details image image In subsequent PRs we will cache the participants since they do not change often, and improve the thread list further with participants. This commit also adds a showPresence boolean (default true) to ChatUserAvatar, since we don't want to show the online indicator for thread participants. --------- Co-authored-by: chapoi <charlie@discourse.org>
83 lines
2.4 KiB
Ruby
83 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Chat
|
|
# Service responsible for trashing a chat message
|
|
# for a channel and ensuring that the client and read state is
|
|
# updated.
|
|
#
|
|
# @example
|
|
# Chat::TrashMessage.call(message_id: 2, channel_id: 1, guardian: guardian)
|
|
#
|
|
class TrashMessage
|
|
include Service::Base
|
|
|
|
# @!method call(message_id:, channel_id:, guardian:)
|
|
# @param [Integer] message_id
|
|
# @param [Integer] channel_id
|
|
# @param [Guardian] guardian
|
|
# @return [Service::Base::Context]
|
|
|
|
contract
|
|
model :message
|
|
policy :invalid_access
|
|
transaction do
|
|
step :trash_message
|
|
step :destroy_notifications
|
|
step :update_tracking_state
|
|
step :update_thread_reply_cache
|
|
end
|
|
step :publish_events
|
|
|
|
# @!visibility private
|
|
class Contract
|
|
attribute :message_id, :integer
|
|
attribute :channel_id, :integer
|
|
validates :message_id, presence: true
|
|
validates :channel_id, presence: true
|
|
end
|
|
|
|
private
|
|
|
|
def fetch_message(contract:, **)
|
|
Chat::Message.includes(chat_channel: :chatable).find_by(
|
|
id: contract.message_id,
|
|
chat_channel_id: contract.channel_id,
|
|
)
|
|
end
|
|
|
|
def invalid_access(guardian:, message:, **)
|
|
guardian.can_delete_chat?(message, message.chat_channel.chatable)
|
|
end
|
|
|
|
def trash_message(message:, **)
|
|
message.trash!
|
|
end
|
|
|
|
def destroy_notifications(message:, **)
|
|
ids = Chat::Mention.where(chat_message: message).pluck(:notification_id)
|
|
Notification.where(id: ids).destroy_all
|
|
Chat::Mention.where(chat_message: message).update_all(notification_id: nil)
|
|
end
|
|
|
|
def update_tracking_state(message:, **)
|
|
::Chat::Action::ResetUserLastReadChannelMessage.call([message.id], [message.chat_channel_id])
|
|
if message.thread_id.present?
|
|
::Chat::Action::ResetUserLastReadThreadMessage.call([message.id], [message.thread_id])
|
|
end
|
|
end
|
|
|
|
def update_thread_reply_cache(message:, **)
|
|
message.thread&.decrement_replies_count_cache
|
|
end
|
|
|
|
def publish_events(guardian:, message:, **)
|
|
DiscourseEvent.trigger(:chat_message_trashed, message, message.chat_channel, guardian.user)
|
|
Chat::Publisher.publish_delete!(message.chat_channel, message)
|
|
|
|
if message.thread.present?
|
|
Chat::Publisher.publish_thread_original_message_metadata!(message.thread)
|
|
end
|
|
end
|
|
end
|
|
end
|