From 477d427f1d6d49fbd080470e0b9248e1f0a271f1 Mon Sep 17 00:00:00 2001 From: KMY Date: Tue, 12 Sep 2023 13:54:24 +0900 Subject: [PATCH] Hide blocking domains/suspended/silenced emoji reactions and streaming --- app/lib/activitypub/activity/like.rb | 2 +- app/lib/activitypub/activity/undo.rb | 2 +- app/lib/status_cache_hydrator.rb | 4 ++++ app/models/status.rb | 8 ++++++++ app/services/emoji_react_service.rb | 2 +- app/services/un_emoji_react_service.rb | 2 +- app/validators/emoji_reaction_validator.rb | 6 +++--- app/workers/delivery_emoji_reaction_worker.rb | 12 +++++++++--- 8 files changed, 28 insertions(+), 10 deletions(-) diff --git a/app/lib/activitypub/activity/like.rb b/app/lib/activitypub/activity/like.rb index c5524033461319..7765f7ed271985 100644 --- a/app/lib/activitypub/activity/like.rb +++ b/app/lib/activitypub/activity/like.rb @@ -109,7 +109,7 @@ def write_stream(emoji_reaction) emoji_group = @original_status.emoji_reactions_grouped_by_name .find { |reaction_group| reaction_group['name'] == emoji_reaction.name && (!reaction_group.key?(:domain) || reaction_group['domain'] == emoji_reaction.custom_emoji&.domain) } emoji_group['status_id'] = @original_status.id.to_s - DeliveryEmojiReactionWorker.perform_async(render_emoji_reaction(emoji_group), @original_status.id, emoji_reaction.account_id) + DeliveryEmojiReactionWorker.perform_async(render_emoji_reaction(emoji_group), emoji_reaction.id, emoji_reaction.account_id) end def render_emoji_reaction(emoji_group) diff --git a/app/lib/activitypub/activity/undo.rb b/app/lib/activitypub/activity/undo.rb index c1862cc36d16fc..cad1fc4368c93d 100644 --- a/app/lib/activitypub/activity/undo.rb +++ b/app/lib/activitypub/activity/undo.rb @@ -149,7 +149,7 @@ def write_stream(emoji_reaction) emoji_group = { 'name' => emoji_reaction.name, 'count' => 0, 'account_ids' => [], 'status_id' => @original_status.id.to_s } emoji_group['domain'] = emoji_reaction.custom_emoji.domain if emoji_reaction.custom_emoji end - DeliveryEmojiReactionWorker.perform_async(render_emoji_reaction(emoji_group), @original_status.id, emoji_reaction.account_id) + DeliveryEmojiReactionWorker.perform_async(render_emoji_reaction(emoji_group), emoji_reaction.id, emoji_reaction.account_id) end def render_emoji_reaction(emoji_group) diff --git a/app/lib/status_cache_hydrator.rb b/app/lib/status_cache_hydrator.rb index 74b1b6f11c4800..f6448b15acceeb 100644 --- a/app/lib/status_cache_hydrator.rb +++ b/app/lib/status_cache_hydrator.rb @@ -6,6 +6,8 @@ def initialize(status) end def hydrate(account_id) + account = Account.find(account_id) + # The cache of the serialized hash is generated by the fan-out-on-write service payload = Rails.cache.fetch("fan-out/#{@status.id}") { InlineRenderer.render(@status, nil, :status) } @@ -33,6 +35,7 @@ def hydrate(account_id) payload[:reblog][:bookmarked] = Bookmark.where(account_id: account_id, status_id: @status.reblog_of_id).exists? payload[:reblog][:pinned] = StatusPin.where(account_id: account_id, status_id: @status.reblog_of_id).exists? if @status.reblog.account_id == account_id payload[:reblog][:filtered] = payload[:filtered] + payload[:reblog][:emoji_reactions] = @status.emoji_reactions_grouped_by_name(account) if payload[:reblog][:poll] if @status.reblog.account_id == account_id @@ -56,6 +59,7 @@ def hydrate(account_id) payload[:filtered] = CustomFilter .apply_cached_filters(CustomFilter.cached_filters_for(account_id), @status, following?(account_id)) .map { |filter| serialized_filter(filter) } + payload[:emoji_reactions] = @status.emoji_reactions_grouped_by_name(account) if payload[:poll] payload[:poll][:voted] = @status.account_id == account_id diff --git a/app/models/status.rb b/app/models/status.rb index 45e221d71c27a1..2333470c72a8b7 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -352,11 +352,19 @@ def add_status_referred_by_count!(diff) def emoji_reactions_grouped_by_name(account = nil) (Oj.load(status_stat&.emoji_reactions || '', mode: :strict) || []).tap do |emoji_reactions| if account.present? + remove_emoji_reactions = [] emoji_reactions.each do |emoji_reaction| emoji_reaction['me'] = emoji_reaction['account_ids'].include?(account.id.to_s) emoji_reaction['account_ids'] -= account.excluded_from_timeline_account_ids.map(&:to_s) + + accounts = Account.where(id: emoji_reaction['account_ids'], silenced_at: nil, suspended_at: nil) + accounts = accounts.where.not(domain: account.excluded_from_timeline_domains) if account.excluded_from_timeline_domains.size.positive? + emoji_reaction['account_ids'] = accounts.pluck(:id).map(&:to_s) + emoji_reaction['count'] = emoji_reaction['account_ids'].size + remove_emoji_reactions << emoji_reaction if emoji_reaction['count'] <= 0 end + emoji_reactions - remove_emoji_reactions end end end diff --git a/app/services/emoji_react_service.rb b/app/services/emoji_react_service.rb index 0dfefa6f0b71b6..8cdd30cd8b2ab3 100644 --- a/app/services/emoji_react_service.rb +++ b/app/services/emoji_react_service.rb @@ -68,7 +68,7 @@ def write_stream(emoji_reaction) emoji_group = emoji_reaction.status.emoji_reactions_grouped_by_name .find { |reaction_group| reaction_group['name'] == emoji_reaction.name && (!reaction_group.key?(:domain) || reaction_group['domain'] == emoji_reaction.custom_emoji&.domain) } emoji_group['status_id'] = emoji_reaction.status_id.to_s - DeliveryEmojiReactionWorker.perform_async(render_emoji_reaction(emoji_group), emoji_reaction.status_id, emoji_reaction.account_id) + DeliveryEmojiReactionWorker.perform_async(render_emoji_reaction(emoji_group), emoji_reaction.id, emoji_reaction.account_id) end def bump_potential_friendship(account, status) diff --git a/app/services/un_emoji_react_service.rb b/app/services/un_emoji_react_service.rb index b473d43459df82..fa0b54ca2f0257 100644 --- a/app/services/un_emoji_react_service.rb +++ b/app/services/un_emoji_react_service.rb @@ -48,7 +48,7 @@ def write_stream(emoji_reaction) emoji_group = { 'name' => emoji_reaction.name, 'count' => 0, 'account_ids' => [], 'status_id' => @status.id.to_s } emoji_group['domain'] = emoji_reaction.custom_emoji.domain if emoji_reaction.custom_emoji end - DeliveryEmojiReactionWorker.perform_async(render_emoji_reaction(emoji_group), @status.id, emoji_reaction.account_id) + DeliveryEmojiReactionWorker.perform_async(render_emoji_reaction(emoji_group), emoji_reaction.id, emoji_reaction.account_id) end def build_json(emoji_reaction) diff --git a/app/validators/emoji_reaction_validator.rb b/app/validators/emoji_reaction_validator.rb index e7da9d07247ef8..fb6ef325654a01 100644 --- a/app/validators/emoji_reaction_validator.rb +++ b/app/validators/emoji_reaction_validator.rb @@ -30,14 +30,14 @@ def deny_emoji_reactions?(emoji_reaction) end def deny_from_all?(emoji_reaction) - emoji_reaction.status.account.user.settings['emoji_reactions.deny_from_all'] + emoji_reaction.status.account.emoji_reactions_deny_from_all? end def non_following?(emoji_reaction) - emoji_reaction.status.account.user.settings['emoji_reactions.must_be_following'] && !emoji_reaction.status.account.following?(emoji_reaction.account) + emoji_reaction.status.account.emoji_reactions_must_following? && !emoji_reaction.status.account.following?(emoji_reaction.account) end def non_follower?(emoji_reaction) - emoji_reaction.status.account.user.settings['emoji_reactions.must_be_follower'] && !emoji_reaction.account.following?(emoji_reaction.status.account) + emoji_reaction.status.account.emoji_reactions_must_follower? && !emoji_reaction.account.following?(emoji_reaction.status.account) end end diff --git a/app/workers/delivery_emoji_reaction_worker.rb b/app/workers/delivery_emoji_reaction_worker.rb index af67d43a4f70ea..fa33106cedc91a 100644 --- a/app/workers/delivery_emoji_reaction_worker.rb +++ b/app/workers/delivery_emoji_reaction_worker.rb @@ -6,12 +6,18 @@ class DeliveryEmojiReactionWorker include Lockable include AccountScope - def perform(payload_json, status_id, _my_account_id = nil) - status = Status.find(status_id.to_i) + def perform(payload_json, emoji_reaction_id, _status_id, _my_account_id = nil) + emoji_reaction = EmojiReaction.find(emoji_reaction_id) + status = emoji_reaction&.status if status.present? + return if status.account.excluded_from_timeline_domains.include?(emoji_reaction.account.domain) + scope_status(status).includes(:user).find_each do |account| - redis.publish("timeline:#{account.id}", payload_json) if (account.user.nil? || (!account.user&.setting_stop_emoji_reaction_streaming && !account.user&.setting_enable_emoji_reaction)) && redis.exists?("subscribed:timeline:#{account.id}") + next unless (account.user.nil? || (!account.user&.setting_stop_emoji_reaction_streaming && !account.user&.setting_enable_emoji_reaction)) && redis.exists?("subscribed:timeline:#{account.id}") + next if account.excluded_from_timeline_domains.include?(emoji_reaction.account.domain) + + redis.publish("timeline:#{account.id}", payload_json) end end