From eb941f5b01f06ca4279495017bf594913e9a5147 Mon Sep 17 00:00:00 2001 From: noellabo Date: Mon, 13 Sep 2021 01:24:47 +0900 Subject: [PATCH] Change emoji reactions to be grouped by shortcode --- app/javascript/mastodon/reducers/statuses.js | 6 +++--- app/models/emoji_reaction.rb | 2 +- app/models/status.rb | 2 +- app/workers/publish_emoji_reaction_worker.rb | 22 +++++++------------- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js index 032b0feb2..9405404b0 100644 --- a/app/javascript/mastodon/reducers/statuses.js +++ b/app/javascript/mastodon/reducers/statuses.js @@ -50,7 +50,7 @@ const deleteStatus = (state, id, references, quotes) => { const updateEmojiReaction = (state, id, name, domain, url, static_url, updater) => state.update(id, status => { return status.update('emoji_reactions', emojiReactions => { - const idx = emojiReactions.findIndex(emojiReaction => !domain && !emojiReaction.get('domain') && emojiReaction.get('name') === name || emojiReaction.get('name') === name && emojiReaction.get('domain', null) === domain); + const idx = emojiReactions.findIndex(emojiReaction => emojiReaction.get('name') === name); if (idx > -1) { return emojiReactions.update(idx, emojiReactions => updater(emojiReactions)); @@ -60,11 +60,11 @@ const updateEmojiReaction = (state, id, name, domain, url, static_url, updater) }); }); -const updateEmojiReactionCount = (state, emojiReaction) => updateEmojiReaction(state, emojiReaction.status_id, emojiReaction.name, emojiReaction.domain, emojiReaction.url, emojiReaction.static_url, x => x.set('count', emojiReaction.count)); +const updateEmojiReactionCount = (state, emojiReaction) => updateEmojiReaction(state, emojiReaction.status_id, emojiReaction.name, emojiReaction.domain, emojiReaction.url, emojiReaction.static_url, x => x.set('count', emojiReaction.count).set('account_ids', emojiReaction.account_ids)); const addEmojiReaction = (state, id, name, domain, url, static_url) => updateEmojiReaction(state, id, name, domain, url, static_url, x => x.update('count', y => y + 1).update('account_ids', z => z.push(me))); -const removeEmojiReaction = (state, id, name, domain, url, static_url) => updateEmojiReaction(state, id, name, domain, url, static_url, x => x.update('count', y => y - 1).update('account_ids', z => z.deleteIn([me]))); +const removeEmojiReaction = (state, id, name, domain, url, static_url) => updateEmojiReaction(state, id, name, domain, url, static_url, x => x.update('count', y => y - 1).update('account_ids', z => z.filter(id => id != me))); const initialState = ImmutableMap(); diff --git a/app/models/emoji_reaction.rb b/app/models/emoji_reaction.rb index dd49ed824..11c3acae9 100644 --- a/app/models/emoji_reaction.rb +++ b/app/models/emoji_reaction.rb @@ -40,7 +40,7 @@ class EmojiReaction < ApplicationRecord private def queue_publish - PublishEmojiReactionWorker.perform_async(status_id, name, custom_emoji_id) unless status.destroyed? + PublishEmojiReactionWorker.perform_async(status_id, name) unless status.destroyed? end def refresh_status diff --git a/app/models/status.rb b/app/models/status.rb index 60bdc3b44..6000065d9 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -310,7 +310,7 @@ class Status < ApplicationRecord end def generate_grouped_emoji_reactions - records = emoji_reactions.group(:status_id, :name, :custom_emoji_id).order(Arel.sql('MIN(created_at) ASC')).select('name, custom_emoji_id, count(*) as count, array_agg(account_id::text order by created_at) as account_ids') + records = emoji_reactions.group(:name).order(Arel.sql('MIN(created_at) ASC')).select('name, min(custom_emoji_id) as custom_emoji_id, count(*) as count, array_agg(account_id::text order by created_at) as account_ids') Oj.dump(ActiveModelSerializers::SerializableResource.new(records, each_serializer: REST::EmojiReactionSerializer, scope: nil, scope_name: :current_user)) end diff --git a/app/workers/publish_emoji_reaction_worker.rb b/app/workers/publish_emoji_reaction_worker.rb index 35e147bf5..37d9f4e92 100644 --- a/app/workers/publish_emoji_reaction_worker.rb +++ b/app/workers/publish_emoji_reaction_worker.rb @@ -5,25 +5,17 @@ class PublishEmojiReactionWorker include Redisable include RoutingHelper - def perform(status_id, name, custom_emoji_id) - status = Status.find(status_id) - custom_emoji = CustomEmoji.find(custom_emoji_id) if custom_emoji_id.present? + def perform(status_id, name) + status = Status.find(status_id) + payload = status.grouped_emoji_reactions.find { |emoji_reaction| emoji_reaction['name'] == name } + payload ||= { name: name, count: 0, account_ids: [] } - emoji_reaction, = status.emoji_reactions.where(name: name, custom_emoji_id: custom_emoji_id).group(:status_id, :name, :custom_emoji_id).select('name, custom_emoji_id, count(*) as count, false as me') - emoji_reaction ||= status.emoji_reactions.new(name: name, custom_emoji_id: custom_emoji_id) + payload['status_id'] = status_id.to_s - payload = InlineRenderer.render(emoji_reaction, nil, :emoji_reaction).tap { |h| - h[:status_id] = status_id.to_s - if custom_emoji.present? - h[:url] = full_asset_url(custom_emoji.image.url) - h[:static_url] = full_asset_url(custom_emoji.image.url(:static)) - h[:domain] = custom_emoji.domain - end - } - payload = Oj.dump(event: :'emoji_reaction', payload: payload) + json = Oj.dump(event: :'emoji_reaction', payload: payload) FeedManager.instance.with_active_accounts do |account| - redis.publish("timeline:#{account.id}", payload) if redis.exists?("subscribed:timeline:#{account.id}") + redis.publish("timeline:#{account.id}", json) if redis.exists?("subscribed:timeline:#{account.id}") end rescue ActiveRecord::RecordNotFound true