Add emoji_reactions property to status api object

This commit is contained in:
KMY 2023-02-23 20:32:27 +09:00
parent 0ebf8b302d
commit 092f9916b0
7 changed files with 73 additions and 2 deletions

View file

@ -62,6 +62,7 @@ class Status < ApplicationRecord
belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true
has_many :favourites, inverse_of: :status, dependent: :destroy has_many :favourites, inverse_of: :status, dependent: :destroy
has_many :emoji_reactions, inverse_of: :status, dependent: :destroy
has_many :bookmarks, inverse_of: :status, dependent: :destroy has_many :bookmarks, inverse_of: :status, dependent: :destroy
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy
has_many :reblogged_by_accounts, through: :reblogs, class_name: 'Account', source: :account has_many :reblogged_by_accounts, through: :reblogs, class_name: 'Account', source: :account
@ -288,6 +289,29 @@ class Status < ApplicationRecord
update_status_stat!(key => [public_send(key) - 1, 0].max) update_status_stat!(key => [public_send(key) - 1, 0].max)
end end
def emoji_reactions_grouped_by_name(account = nil)
(Oj.load(status_stat&.emoji_reactions || '', mode: :strict) || []).tap do |emoji_reactions|
if account.present?
emoji_reactions.each do |emoji_reaction|
emoji_reaction['me'] = emoji_reaction['account_ids'].include?(account.id.to_s)
emoji_reaction['count'] = emoji_reaction['account_ids'].size
emoji_reaction['account_ids'] -= account.excluded_from_timeline_account_ids.map(&:to_s)
end
end
end
end
def generate_emoji_reactions_grouped_by_name
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::EmojiReactionsGroupedByNameSerializer, scope: nil, scope_name: :current_user))
end
def refresh_emoji_reactions_grouped_by_name!
generate_emoji_reactions_grouped_by_name.tap do |emoji_reactions|
update_status_stat!(emoji_reactions: emoji_reactions)
end
end
def trendable? def trendable?
if attributes['trendable'].nil? if attributes['trendable'].nil?
account.trendable? account.trendable?

View file

@ -9,6 +9,7 @@
# replies_count :bigint(8) default(0), not null # replies_count :bigint(8) default(0), not null
# reblogs_count :bigint(8) default(0), not null # reblogs_count :bigint(8) default(0), not null
# favourites_count :bigint(8) default(0), not null # favourites_count :bigint(8) default(0), not null
# emoji_reactions :string
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# #
@ -30,6 +31,10 @@ class StatusStat < ApplicationRecord
[attributes['favourites_count'], 0].max [attributes['favourites_count'], 0].max
end end
def emoji_reactions
attributes['emoji_reactions'] || ''
end
private private
def reset_parent_cache def reset_parent_cache

View file

@ -0,0 +1,31 @@
# frozen_string_literal: true
# name: string,
#count: number,
#account_ids: Array<string>,
#me: boolean,
#url: string,
#domain: string
class REST::EmojiReactionsGroupedByNameSerializer < ActiveModel::Serializer
attributes :name, :count
attribute :me, if: :current_user?
attribute :url, if: :custom_emoji?
attribute :static_url, if: :custom_emoji?
attribute :domain, if: :custom_emoji?
attribute :account_ids, if: :has_account_ids?
def current_user?
!current_user.nil?
end
def custom_emoji?
object.respond_to?(:custom_emoji)
end
def has_account_ids?
object.respond_to?(:account_ids)
end
end

View file

@ -6,7 +6,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id,
:sensitive, :spoiler_text, :visibility, :language, :sensitive, :spoiler_text, :visibility, :language,
:uri, :url, :replies_count, :reblogs_count, :uri, :url, :replies_count, :reblogs_count,
:favourites_count, :edited_at :favourites_count, :emoji_reactions, :edited_at
attribute :favourited, if: :current_user? attribute :favourited, if: :current_user?
attribute :reblogged, if: :current_user? attribute :reblogged, if: :current_user?
@ -89,6 +89,10 @@ class REST::StatusSerializer < ActiveModel::Serializer
end end
end end
def emoji_reactions
object.emoji_reactions_grouped_by_name(current_user&.account)
end
def reblogged def reblogged
if instance_options && instance_options[:relationships] if instance_options && instance_options[:relationships]
instance_options[:relationships].reblogs_map[object.id] || false instance_options[:relationships].reblogs_map[object.id] || false

View file

@ -0,0 +1,5 @@
class AddEmojiReactionsToStatusStats < ActiveRecord::Migration[6.1]
def change
add_column :status_stats, :emoji_reactions, :string
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2023_02_22_235218) do ActiveRecord::Schema.define(version: 2023_02_23_102416) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -914,6 +914,7 @@ ActiveRecord::Schema.define(version: 2023_02_22_235218) do
t.bigint "favourites_count", default: 0, null: false t.bigint "favourites_count", default: 0, null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "emoji_reactions"
t.index ["status_id"], name: "index_status_stats_on_status_id", unique: true t.index ["status_id"], name: "index_status_stats_on_status_id", unique: true
end end

View file

@ -45,6 +45,7 @@ module Mastodon
status_stat.replies_count = status.replies.where.not(visibility: :direct).count status_stat.replies_count = status.replies.where.not(visibility: :direct).count
status_stat.reblogs_count = status.reblogs.count status_stat.reblogs_count = status.reblogs.count
status_stat.favourites_count = status.favourites.count status_stat.favourites_count = status.favourites.count
status_stat.emoji_reactions = status.generate_emoji_reactions_grouped_by_name
status_stat.save if status_stat.changed? status_stat.save if status_stat.changed?
end end