1
0
Fork 0
forked from gitea/nas

Change emoji reaction duplication check

This commit is contained in:
KMY 2023-07-26 11:33:28 +09:00
parent 3258d09c64
commit c30d4b5162
3 changed files with 22 additions and 10 deletions

View file

@ -1,6 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
class ActivityPub::Activity::Like < ActivityPub::Activity class ActivityPub::Activity::Like < ActivityPub::Activity
include Redisable
include Lockable
def perform def perform
@original_status = status_from_uri(object_uri) @original_status = status_from_uri(object_uri)
@ -44,9 +47,15 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
Trends.statuses.register(@original_status) Trends.statuses.register(@original_status)
end end
return if EmojiReaction.where(account: @account, status: @original_status).count >= EmojiReaction::EMOJI_REACTION_PER_ACCOUNT_LIMIT reaction = nil
with_redis_lock("emoji_reaction:#{@original_status.id}") do
return if EmojiReaction.where(account: @account, status: @original_status).count >= EmojiReaction::EMOJI_REACTION_PER_ACCOUNT_LIMIT
return if EmojiReaction.find_by(account: @account, status: @original_status, name: shortcode)
reaction = @original_status.emoji_reactions.create!(account: @account, name: shortcode, custom_emoji: emoji, uri: @json['id'])
end
reaction = @original_status.emoji_reactions.create!(account: @account, name: shortcode, custom_emoji: emoji, uri: @json['id'])
write_stream(reaction) write_stream(reaction)
if @original_status.account.local? if @original_status.account.local?

View file

@ -28,7 +28,6 @@ class EmojiReaction < ApplicationRecord
has_one :notification, as: :activity, dependent: :destroy has_one :notification, as: :activity, dependent: :destroy
validate :status_same_emoji_reaction
validate :status_emoji_reactions_count validate :status_emoji_reactions_count
validates_with EmojiReactionValidator validates_with EmojiReactionValidator

View file

@ -4,6 +4,7 @@ class EmojiReactService < BaseService
include Authorization include Authorization
include Payloadable include Payloadable
include Redisable include Redisable
include Lockable
# React a status with emoji and notify remote user # React a status with emoji and notify remote user
# @param [Account] account # @param [Account] account
@ -14,17 +15,20 @@ class EmojiReactService < BaseService
status = status.reblog if status.reblog? && !status.reblog.nil? status = status.reblog if status.reblog? && !status.reblog.nil?
authorize_with account, status, :emoji_reaction? authorize_with account, status, :emoji_reaction?
emoji_reaction = EmojiReaction.find_by(account: account, status: status, name: name) emoji_reaction = nil
return emoji_reaction unless emoji_reaction.nil? with_redis_lock("emoji_reaction:#{status.id}") do
emoji_reaction = EmojiReaction.find_by(account: account, status: status, name: name)
raise Mastodon::ValidationError, I18n.t('reactions.errors.duplication') unless emoji_reaction.nil?
shortcode, domain = name.split('@') shortcode, domain = name.split('@')
custom_emoji = CustomEmoji.find_by(shortcode: shortcode, domain: domain)
emoji_reaction = EmojiReaction.create!(account: account, status: status, name: shortcode, custom_emoji: custom_emoji)
custom_emoji = CustomEmoji.find_by(shortcode: shortcode, domain: domain) status.touch # rubocop:disable Rails/SkipsModelValidations
end
emoji_reaction = EmojiReaction.create!(account: account, status: status, name: shortcode, custom_emoji: custom_emoji) raise Mastodon::ValidationError, I18n.t('reactions.errors.duplication') if emoji_reaction.nil?
status.touch # rubocop:disable Rails/SkipsModelValidations
Trends.statuses.register(status) Trends.statuses.register(status)