diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js index a4c1e91153..33ed6b189e 100644 --- a/app/javascript/mastodon/actions/streaming.js +++ b/app/javascript/mastodon/actions/streaming.js @@ -102,6 +102,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti dispatch(updateNotifications(JSON.parse(data.payload), messages, locale)); break; case 'emoji_reaction': + // @ts-expect-error dispatch(updateEmojiReactions(JSON.parse(data.payload), getState().getIn(['meta', 'me']))); break; case 'conversation': diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index da1d7472cc..3da571fb1a 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -400,7 +400,7 @@ "not_signed_in_indicator.not_signed_in": "この機能を使うにはログインする必要があります。", "notification.admin.report": "{name}さんが{target}さんを通報しました", "notification.admin.sign_up": "{name}さんがサインアップしました", - "notification.emoji_reaction": "{name}さんがあなたの投稿に絵文字をつけました", + "notification.emoji_reaction": "{name}さんがあなたの投稿にスタンプをつけました", "notification.favourite": "{name}さんがあなたの投稿をお気に入りに登録しました", "notification.follow": "{name}さんにフォローされました", "notification.follow_request": "{name}さんがあなたにフォローリクエストしました", diff --git a/app/lib/activitypub/activity/undo.rb b/app/lib/activitypub/activity/undo.rb index d74eabb2a0..c1862cc36d 100644 --- a/app/lib/activitypub/activity/undo.rb +++ b/app/lib/activitypub/activity/undo.rb @@ -9,7 +9,7 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity undo_accept when 'Follow' undo_follow - when 'Like' + when 'Like', 'EmojiReaction', 'EmojiReact' undo_like when 'Block' undo_block diff --git a/app/models/concerns/has_user_settings.rb b/app/models/concerns/has_user_settings.rb index dd28d9654e..95c1f7a79a 100644 --- a/app/models/concerns/has_user_settings.rb +++ b/app/models/concerns/has_user_settings.rb @@ -47,6 +47,10 @@ module HasUserSettings settings['stop_emoji_reaction_streaming'] end + def setting_emoji_reaction_streaming_notify_impl2 + settings['emoji_reaction_streaming_notify_impl2'] + end + def setting_unfollow_modal settings['web.unfollow_modal'] end diff --git a/app/models/notification.rb b/app/models/notification.rb index 00f53d2ec5..3e6b10f9c8 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -37,6 +37,7 @@ class Notification < ApplicationRecord follow_request favourite emoji_reaction + reaction poll update admin.sign_up @@ -49,6 +50,7 @@ class Notification < ApplicationRecord mention: [mention: :status], favourite: [favourite: :status], emoji_reaction: [emoji_reaction: :status], + reaction: [emoji_reaction: :status], poll: [poll: :status], update: :status, 'admin.report': [report: :target_account], @@ -85,7 +87,7 @@ class Notification < ApplicationRecord status&.reblog when :favourite favourite&.status - when :emoji_reaction + when :emoji_reaction, :reaction emoji_reaction&.status when :mention mention&.status @@ -136,7 +138,7 @@ class Notification < ApplicationRecord notification.status.reblog = cached_status when :favourite notification.favourite.status = cached_status - when :emoji_reaction + when :emoji_reaction, :reaction notification.emoji_reaction.status = cached_status when :mention notification.mention.status = cached_status @@ -158,7 +160,7 @@ class Notification < ApplicationRecord return unless new_record? case activity_type - when 'Status', 'Follow', 'Favourite', 'EmojiReaction', 'FollowRequest', 'Poll', 'Report' + when 'Status', 'Follow', 'Favourite', 'EmojiReaction', 'EmojiReact', 'FollowRequest', 'Poll', 'Report' self.from_account_id = activity&.account_id when 'Mention' self.from_account_id = activity&.status&.account_id diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb index 9b518d8355..eca07e2f27 100644 --- a/app/models/user_settings.rb +++ b/app/models/user_settings.rb @@ -22,6 +22,7 @@ class UserSettings setting :reject_unlisted_subscription, default: false setting :send_without_domain_blocks, default: false setting :stop_emoji_reaction_streaming, default: false + setting :emoji_reaction_streaming_notify_impl2, default: false namespace :web do setting :crop_images, default: true diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb index ebf2d5be24..01736de74c 100644 --- a/app/serializers/rest/instance_serializer.rb +++ b/app/serializers/rest/instance_serializer.rb @@ -84,6 +84,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer max_reactions: EmojiReaction::EMOJI_REACTION_LIMIT, max_reactions_per_account: EmojiReaction::EMOJI_REACTION_PER_ACCOUNT_LIMIT, }, + + reactions: { + max_reactions: EmojiReaction::EMOJI_REACTION_LIMIT, + }, } end diff --git a/app/serializers/rest/notification_serializer.rb b/app/serializers/rest/notification_serializer.rb index f3235b3b11..793d33b8c5 100644 --- a/app/serializers/rest/notification_serializer.rb +++ b/app/serializers/rest/notification_serializer.rb @@ -13,7 +13,7 @@ class REST::NotificationSerializer < ActiveModel::Serializer end def status_type? - [:favourite, :emoji_reaction, :reblog, :status, :mention, :poll, :update].include?(object.type) + [:favourite, :emoji_reaction, :reaction, :reblog, :status, :mention, :poll, :update].include?(object.type) end def report_type? diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index fec8d32009..c065c817a6 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -6,13 +6,14 @@ class REST::StatusSerializer < ActiveModel::Serializer attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, :sensitive, :spoiler_text, :visibility, :visibility_ex, :language, :uri, :url, :replies_count, :reblogs_count, :searchability, :markdown, - :favourites_count, :emoji_reactions, :emoji_reactions_count, :edited_at + :favourites_count, :emoji_reactions, :emoji_reactions_count, :reactions, :edited_at attribute :favourited, if: :current_user? attribute :reblogged, if: :current_user? attribute :muted, if: :current_user? attribute :bookmarked, if: :current_user? attribute :pinned, if: :pinnable? + attribute :reactions, if: :reactions? has_many :filtered, serializer: REST::FilterResultSerializer, if: :current_user? attribute :content, unless: :source_requested? @@ -103,6 +104,17 @@ class REST::StatusSerializer < ActiveModel::Serializer object.emoji_reactions_grouped_by_name(current_user&.account) end + def reactions + emoji_reactions.tap do |rs| + rs.each do |emoji_reaction| + emoji_reaction['name'] = emoji_reaction['domain'].present? ? "#{emoji_reaction['name']}@#{emoji_reaction['domain']}" : emoji_reaction['name'] + emoji_reaction.delete('account_ids') + emoji_reaction.delete('me') + emoji_reaction.delete('domain') + end + end + end + def reblogged if instance_options && instance_options[:relationships] instance_options[:relationships].reblogs_map[object.id] || false @@ -150,6 +162,10 @@ class REST::StatusSerializer < ActiveModel::Serializer %w(public unlisted public_unlisted private).include?(object.visibility) end + def reactions? + current_user? && current_user.setting_emoji_reaction_streaming_notify_impl2 + end + def source_requested? instance_options[:source_requested] end diff --git a/app/serializers/rest/v1/instance_serializer.rb b/app/serializers/rest/v1/instance_serializer.rb index 1e9b2fa6bc..550dc5df16 100644 --- a/app/serializers/rest/v1/instance_serializer.rb +++ b/app/serializers/rest/v1/instance_serializer.rb @@ -90,6 +90,10 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer max_reactions: EmojiReaction::EMOJI_REACTION_LIMIT, max_reactions_per_account: EmojiReaction::EMOJI_REACTION_PER_ACCOUNT_LIMIT, }, + + reactions: { + max_reactions: EmojiReaction::EMOJI_REACTION_LIMIT, + }, } end diff --git a/app/services/emoji_react_service.rb b/app/services/emoji_react_service.rb index d0b6214a1f..049614b24d 100644 --- a/app/services/emoji_react_service.rb +++ b/app/services/emoji_react_service.rb @@ -39,6 +39,7 @@ class EmojiReactService < BaseService status = emoji_reaction.status if status.account.local? + LocalNotificationWorker.perform_async(status.account_id, emoji_reaction.id, 'EmojiReaction', 'reaction') if status.account.user&.setting_emoji_reaction_streaming_notify_impl2 LocalNotificationWorker.perform_async(status.account_id, emoji_reaction.id, 'EmojiReaction', 'emoji_reaction') elsif status.account.activitypub? ActivityPub::DeliveryWorker.perform_async(build_json(emoji_reaction), emoji_reaction.account_id, status.account.inbox_url) diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index e9613f8cff..2fab9c5d6a 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -39,6 +39,9 @@ .fields-group = ff.input :'web.crop_images', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_crop_images') + .fields-group + = ff.input :emoji_reaction_streaming_notify_impl2, as: :boolean, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_emoji_reaction_streaming_notify_impl2'), hint: I18n.t('simple_form.hints.defaults.setting_emoji_reaction_streaming_notify_impl2') + %h4= t 'appearance.discovery' .fields-group diff --git a/app/views/settings/preferences/notifications/show.html.haml b/app/views/settings/preferences/notifications/show.html.haml index 2444e788ec..2730507922 100644 --- a/app/views/settings/preferences/notifications/show.html.haml +++ b/app/views/settings/preferences/notifications/show.html.haml @@ -34,6 +34,6 @@ = ff.input :'interactions.must_be_following', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following') = ff.input :'interactions.must_be_following_dm', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following_dm') - .fields-group - = f.simple_fields_for :settings, current_user.settings do |ff| + = f.simple_fields_for :settings, current_user.settings do |ff| + .fields-group = ff.input :stop_emoji_reaction_streaming, as: :boolean, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_stop_emoji_reaction_streaming'), hint: I18n.t('simple_form.hints.defaults.setting_stop_emoji_reaction_streaming') diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 9533ba6564..db447b0eb1 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -218,6 +218,7 @@ en: setting_display_media_expand: Show more medias setting_display_media_hide_all: Hide all setting_display_media_show_all: Show all + setting_emoji_reaction_streaming_notify_impl2: Enable stamp notification compat with Nyastodon, Catstodon, glitch-soc setting_expand_spoilers: Always expand posts marked with content warnings setting_hide_network: Hide your social graph setting_noai: Set noai meta tags diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index b2b7aaf14e..a3d848f288 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -59,6 +59,7 @@ ja: setting_display_media_default: 閲覧注意としてマークされたメディアは隠す setting_display_media_hide_all: メディアを常に隠す setting_display_media_show_all: メディアを常に表示する + setting_emoji_reaction_streaming_notify_impl2: 当該サーバーの独自機能に対応したアプリを利用時に、スタンプ機能を利用できます。動作確認していないため(そもそもそのようなアプリ自体を確認できていないため)正しく動かない場合があります setting_hide_network: フォローとフォロワーの情報がプロフィールページで見られないようにします setting_display_media_expand: Misskeyなどは4個を超えて投稿可能です。その追加分を最大16個まで表示します。kmyblueからアップロードはできません setting_noai: AI学習への利用を禁止するメタタグをプロフィールページに追加します。ただし実効性があるとは限りません @@ -224,6 +225,7 @@ ja: setting_display_media_expand: 5個目以降のメディアも表示する (最大16) setting_display_media_hide_all: 非表示 setting_display_media_show_all: 表示 + setting_emoji_reaction_streaming_notify_impl2: Nyastodon, Catstodon, glitch-soc互換のスタンプ機能を有効にする setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する setting_hide_network: 繋がりを隠す setting_noai: 自分のコンテンツのAI学習利用に対して不快感を表明する diff --git a/config/routes/api.rb b/config/routes/api.rb index fd5cabe20a..a929547817 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -34,6 +34,8 @@ namespace :api, format: false do resources :emoji_reactions, only: [:create, :update, :destroy], constraints: { id: %r{[^/]+} } post :emoji_unreaction, to: 'emoji_reactions#destroy' + post :react, to: 'emoji_reactions#create' + post :unreact, to: 'emoji_reactions#destroy' end member do