discourse/plugins/chat/app/services/chat/trash_message.rb
Martin Brennan f75ac9da30
FEATURE: Thread indicator improvements and participants (#21909)
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>
2023-06-15 10:49:27 +10:00

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