mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FIX: Trashing message should reset last read (#20912)
When a chat message is trashed and the message is used for someone's UserChatChannelMembership#last_read_message_id, the user would end up with some read state issues until someone posted a new message in the channel, since we didn't clear it like we did on bulk message delete. This commit fixes the issue, and also takes the opportunity to start a MessagesController in the API namespace, and move the trash message functionality into the new service format.
This commit is contained in:
@@ -12,19 +12,6 @@ module Chat
|
||||
end
|
||||
end
|
||||
|
||||
def trash_message(message, actor)
|
||||
Chat::Message.transaction do
|
||||
message.trash!(actor)
|
||||
Chat::Mention.where(chat_message: message).destroy_all
|
||||
DiscourseEvent.trigger(:chat_message_trashed, message, message.chat_channel, actor)
|
||||
|
||||
# FIXME: We should do something to prevent the blue/green bubble
|
||||
# of other channel members from getting out of sync when a message
|
||||
# gets deleted.
|
||||
Chat::Publisher.publish_delete!(message.chat_channel, message)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reset_last_read(message_ids)
|
||||
|
||||
70
plugins/chat/app/services/chat/trash_message.rb
Normal file
70
plugins/chat/app/services/chat/trash_message.rb
Normal file
@@ -0,0 +1,70 @@
|
||||
# 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_mentions
|
||||
step :update_tracking_state
|
||||
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_mentions(message:, **)
|
||||
Chat::Mention.where(chat_message: message).destroy_all
|
||||
end
|
||||
|
||||
def update_tracking_state(message:, **)
|
||||
Chat::UserChatChannelMembership.where(last_read_message_id: message.id).update_all(
|
||||
last_read_message_id: nil,
|
||||
)
|
||||
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)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user