discourse/plugins/chat/lib/chat_message_updater.rb
Gerhard Schlager 7ef482a292
REFACTOR: Fix pluralized strings in chat plugin (#20357)
* FIX: Use pluralized string

* REFACTOR: Fix misuse of pluralized string

* REFACTOR: Fix misuse of pluralized string

* DEV: Remove linting of `one` key in MessageFormat string, it doesn't work

* REFACTOR: Fix misuse of pluralized string

This also ensures that the URL works on subfolder and shows the site setting link only for admins instead of staff. The string is quite complicated, so the best option was to switch to MessageFormat.

* REFACTOR: Fix misuse of pluralized string

* FIX: Use pluralized string

This also ensures that the URL works on subfolder and shows the site setting link only for admins instead of staff.

* REFACTOR: Correctly pluralize reaction tooltips in chat

This also ensures that maximum 5 usernames are shown and fixes the number of "others" which was off by 1 if the current user reacted on a message.

* REFACTOR: Use translatable string as comma separator

* DEV: Add comment to translation to clarify the meaning of `%{identifier}`

* REFACTOR: Use translatable comma separator and use explicit interpolation keys

* REFACTOR: Don't interpolate lowercase channel status

* REFACTOR: Fix misuse of pluralized string

* REFACTOR: Don't interpolate channel status

* REFACTOR: Use %{count} interpolation key

* REFACTOR: Fix misuse of pluralized string

* REFACTOR: Correctly pluralize DM chat channel titles
2023-02-20 10:31:02 +01:00

96 lines
2.9 KiB
Ruby

# frozen_string_literal: true
class Chat::ChatMessageUpdater
attr_reader :error
def self.update(opts)
instance = new(**opts)
instance.update
instance
end
def initialize(guardian:, chat_message:, new_content:, upload_ids: nil)
@guardian = guardian
@user = guardian.user
@chat_message = chat_message
@old_message_content = chat_message.message
@chat_channel = @chat_message.chat_channel
@new_content = new_content
@upload_ids = upload_ids
@error = nil
end
def update
begin
validate_channel_status!
@guardian.ensure_can_edit_chat!(@chat_message)
@chat_message.message = @new_content
@chat_message.last_editor_id = @user.id
upload_info = get_upload_info
validate_message!(has_uploads: upload_info[:uploads].any?)
@chat_message.cook
@chat_message.save!
update_uploads(upload_info)
revision = save_revision!
@chat_message.reload
ChatPublisher.publish_edit!(@chat_channel, @chat_message)
Jobs.enqueue(:process_chat_message, { chat_message_id: @chat_message.id })
Chat::ChatNotifier.notify_edit(chat_message: @chat_message, timestamp: revision.created_at)
DiscourseEvent.trigger(:chat_message_edited, @chat_message, @chat_channel, @user)
rescue => error
@error = error
end
end
def failed?
@error.present?
end
private
def validate_channel_status!
return if @guardian.can_modify_channel_message?(@chat_channel)
raise StandardError.new(
I18n.t("chat.errors.channel_modify_message_disallowed.#{@chat_channel.status}"),
)
end
def validate_message!(has_uploads:)
@chat_message.validate_message(has_uploads: has_uploads)
if @chat_message.errors.present?
raise StandardError.new(@chat_message.errors.map(&:full_message).join(", "))
end
end
def get_upload_info
return { uploads: [] } if @upload_ids.nil? || !SiteSetting.chat_allow_uploads
uploads = Upload.where(id: @upload_ids, user_id: @user.id)
if uploads.count != @upload_ids.count
# User is passing upload_ids for uploads that they don't own. Don't change anything.
return { uploads: @chat_message.uploads, changed: false }
end
new_upload_ids = uploads.map(&:id)
existing_upload_ids = @chat_message.upload_ids
difference = (existing_upload_ids + new_upload_ids) - (existing_upload_ids & new_upload_ids)
{ uploads: uploads, changed: difference.any? }
end
def update_uploads(upload_info)
return unless upload_info[:changed]
DB.exec("DELETE FROM chat_uploads WHERE chat_message_id = #{@chat_message.id}")
UploadReference.where(target: @chat_message).destroy_all
@chat_message.attach_uploads(upload_info[:uploads])
end
def save_revision!
@chat_message.revisions.create!(
old_message: @old_message_content,
new_message: @chat_message.message,
user_id: @user.id,
)
end
end