Change emoji reactions to be grouped by shortcode

This commit is contained in:
noellabo 2021-09-13 01:24:47 +09:00
parent 056f24fdc8
commit eb941f5b01
4 changed files with 12 additions and 20 deletions

View file

@ -50,7 +50,7 @@ const deleteStatus = (state, id, references, quotes) => {
const updateEmojiReaction = (state, id, name, domain, url, static_url, updater) => state.update(id, status => { const updateEmojiReaction = (state, id, name, domain, url, static_url, updater) => state.update(id, status => {
return status.update('emoji_reactions', emojiReactions => { 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) { if (idx > -1) {
return emojiReactions.update(idx, emojiReactions => updater(emojiReactions)); 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 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(); const initialState = ImmutableMap();

View file

@ -40,7 +40,7 @@ class EmojiReaction < ApplicationRecord
private private
def queue_publish 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 end
def refresh_status def refresh_status

View file

@ -310,7 +310,7 @@ class Status < ApplicationRecord
end end
def generate_grouped_emoji_reactions 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)) Oj.dump(ActiveModelSerializers::SerializableResource.new(records, each_serializer: REST::EmojiReactionSerializer, scope: nil, scope_name: :current_user))
end end

View file

@ -5,25 +5,17 @@ class PublishEmojiReactionWorker
include Redisable include Redisable
include RoutingHelper include RoutingHelper
def perform(status_id, name, custom_emoji_id) def perform(status_id, name)
status = Status.find(status_id) status = Status.find(status_id)
custom_emoji = CustomEmoji.find(custom_emoji_id) if custom_emoji_id.present? 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') payload['status_id'] = status_id.to_s
emoji_reaction ||= status.emoji_reactions.new(name: name, custom_emoji_id: custom_emoji_id)
payload = InlineRenderer.render(emoji_reaction, nil, :emoji_reaction).tap { |h| json = Oj.dump(event: :'emoji_reaction', payload: payload)
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)
FeedManager.instance.with_active_accounts do |account| 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 end
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
true true