diff options
Diffstat (limited to 'app/serializers')
28 files changed, 533 insertions, 51 deletions
diff --git a/app/serializers/activitypub/accept_follow_serializer.rb b/app/serializers/activitypub/accept_follow_serializer.rb index ce900bc78..3e23591a5 100644 --- a/app/serializers/activitypub/accept_follow_serializer.rb +++ b/app/serializers/activitypub/accept_follow_serializer.rb @@ -1,10 +1,14 @@ # frozen_string_literal: true class ActivityPub::AcceptFollowSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor has_one :object, serializer: ActivityPub::FollowSerializer + def id + [ActivityPub::TagManager.instance.uri_for(object.target_account), '#accepts/follows/', object.id].join + end + def type 'Accept' end diff --git a/app/serializers/activitypub/activity_serializer.rb b/app/serializers/activitypub/activity_serializer.rb index 69e2160c5..b252e008b 100644 --- a/app/serializers/activitypub/activity_serializer.rb +++ b/app/serializers/activitypub/activity_serializer.rb @@ -1,22 +1,26 @@ # frozen_string_literal: true class ActivityPub::ActivitySerializer < ActiveModel::Serializer - attributes :id, :type, :actor, :to, :cc + attributes :id, :type, :actor, :published, :to, :cc has_one :proper, key: :object, serializer: ActivityPub::NoteSerializer def id - [ActivityPub::TagManager.instance.uri_for(object), '/activity'].join + [ActivityPub::TagManager.instance.activity_uri_for(object)].join end def type - object.reblog? ? 'Announce' : 'Create' + announce? ? 'Announce' : 'Create' end def actor ActivityPub::TagManager.instance.uri_for(object.account) end + def published + object.created_at.iso8601 + end + def to ActivityPub::TagManager.instance.to(object) end @@ -24,4 +28,8 @@ class ActivityPub::ActivitySerializer < ActiveModel::Serializer def cc ActivityPub::TagManager.instance.cc(object) end + + def announce? + object.reblog? + end end diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index f5e626d73..a11178f5b 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -4,11 +4,41 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer include RoutingHelper attributes :id, :type, :following, :followers, - :inbox, :outbox, :preferred_username, - :name, :summary, :icon, :image + :inbox, :outbox, + :preferred_username, :name, :summary, + :url, :manually_approves_followers has_one :public_key, serializer: ActivityPub::PublicKeySerializer + class ImageSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :type, :url + + def type + 'Image' + end + + def url + full_asset_url(object.url(:original)) + end + end + + class EndpointsSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :shared_inbox + + def shared_inbox + inbox_url + end + end + + has_one :endpoints, serializer: EndpointsSerializer + + has_one :icon, serializer: ImageSerializer, if: :avatar_exists? + has_one :image, serializer: ImageSerializer, if: :header_exists? + def id account_url(object) end @@ -26,13 +56,17 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer end def inbox - nil + account_inbox_url(object) end def outbox account_outbox_url(object) end + def endpoints + object + end + def preferred_username object.username end @@ -46,14 +80,30 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer end def icon - full_asset_url(object.avatar.url(:original)) + object.avatar end def image - full_asset_url(object.header.url(:original)) + object.header end def public_key object end + + def url + short_account_url(object) + end + + def avatar_exists? + object.avatar.exists? + end + + def header_exists? + object.header.exists? + end + + def manually_approves_followers + object.locked + end end diff --git a/app/serializers/activitypub/block_serializer.rb b/app/serializers/activitypub/block_serializer.rb index a001b213b..b3bd9f868 100644 --- a/app/serializers/activitypub/block_serializer.rb +++ b/app/serializers/activitypub/block_serializer.rb @@ -1,9 +1,13 @@ # frozen_string_literal: true class ActivityPub::BlockSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor attribute :virtual_object, key: :object + def id + [ActivityPub::TagManager.instance.uri_for(object.account), '#blocks/', object.id].join + end + def type 'Block' end diff --git a/app/serializers/activitypub/collection_serializer.rb b/app/serializers/activitypub/collection_serializer.rb index d01dead28..9832133fc 100644 --- a/app/serializers/activitypub/collection_serializer.rb +++ b/app/serializers/activitypub/collection_serializer.rb @@ -3,23 +3,38 @@ class ActivityPub::CollectionSerializer < ActiveModel::Serializer def self.serializer_for(model, options) return ActivityPub::ActivitySerializer if model.class.name == 'Status' + return ActivityPub::CollectionSerializer if model.class.name == 'ActivityPub::CollectionPresenter' super end attributes :id, :type, :total_items + attribute :next, if: -> { object.next.present? } + attribute :prev, if: -> { object.prev.present? } + attribute :part_of, if: -> { object.part_of.present? } - has_many :items, key: :ordered_items + has_one :first, if: -> { object.first.present? } + has_many :items, key: :items, if: -> { (object.items.present? || page?) && !ordered? } + has_many :items, key: :ordered_items, if: -> { (object.items.present? || page?) && ordered? } def type - case object.type - when :ordered - 'OrderedCollection' + if page? + ordered? ? 'OrderedCollectionPage' : 'CollectionPage' else - 'Collection' + ordered? ? 'OrderedCollection' : 'Collection' end end def total_items object.size end + + private + + def ordered? + object.type == :ordered + end + + def page? + object.part_of.present? + end end diff --git a/app/serializers/activitypub/delete_serializer.rb b/app/serializers/activitypub/delete_serializer.rb index 77098b1b0..2bb65135f 100644 --- a/app/serializers/activitypub/delete_serializer.rb +++ b/app/serializers/activitypub/delete_serializer.rb @@ -1,8 +1,29 @@ # frozen_string_literal: true class ActivityPub::DeleteSerializer < ActiveModel::Serializer - attributes :type, :actor - attribute :virtual_object, key: :object + class TombstoneSerializer < ActiveModel::Serializer + attributes :id, :type, :atom_uri + + def id + ActivityPub::TagManager.instance.uri_for(object) + end + + def type + 'Tombstone' + end + + def atom_uri + OStatus::TagManager.instance.uri_for(object) + end + end + + attributes :id, :type, :actor + + has_one :object, serializer: TombstoneSerializer + + def id + [ActivityPub::TagManager.instance.uri_for(object), '#delete'].join + end def type 'Delete' @@ -11,8 +32,4 @@ class ActivityPub::DeleteSerializer < ActiveModel::Serializer def actor ActivityPub::TagManager.instance.uri_for(object.account) end - - def virtual_object - ActivityPub::TagManager.instance.uri_for(object) - end end diff --git a/app/serializers/activitypub/follow_serializer.rb b/app/serializers/activitypub/follow_serializer.rb index 1953a2d7b..86c9992fe 100644 --- a/app/serializers/activitypub/follow_serializer.rb +++ b/app/serializers/activitypub/follow_serializer.rb @@ -1,9 +1,13 @@ # frozen_string_literal: true class ActivityPub::FollowSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor attribute :virtual_object, key: :object + def id + [ActivityPub::TagManager.instance.uri_for(object.account), '#follows/', object.id].join + end + def type 'Follow' end diff --git a/app/serializers/activitypub/like_serializer.rb b/app/serializers/activitypub/like_serializer.rb index 4226913f5..c1a7ff6f6 100644 --- a/app/serializers/activitypub/like_serializer.rb +++ b/app/serializers/activitypub/like_serializer.rb @@ -1,9 +1,13 @@ # frozen_string_literal: true class ActivityPub::LikeSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor attribute :virtual_object, key: :object + def id + [ActivityPub::TagManager.instance.uri_for(object.account), '#likes/', object.id].join + end + def type 'Like' end diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index 4c13f8e59..f94c3b9dc 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -3,7 +3,9 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer attributes :id, :type, :summary, :content, :in_reply_to, :published, :url, - :attributed_to, :to, :cc, :sensitive + :attributed_to, :to, :cc, :sensitive, + :atom_uri, :in_reply_to_atom_uri, + :conversation has_many :media_attachments, key: :attachment has_many :virtual_tags, key: :tag @@ -25,7 +27,13 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer end def in_reply_to - ActivityPub::TagManager.instance.uri_for(object.thread) if object.reply? + return unless object.reply? && !object.thread.nil? + + if object.thread.uri.nil? || object.thread.uri.start_with?('http') + ActivityPub::TagManager.instance.uri_for(object.thread) + else + object.thread.url + end end def published @@ -49,7 +57,33 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer end def virtual_tags - object.mentions + object.tags + object.mentions + object.tags + object.emojis + end + + def atom_uri + return unless object.local? + + OStatus::TagManager.instance.uri_for(object) + end + + def in_reply_to_atom_uri + return unless object.reply? && !object.thread.nil? + + OStatus::TagManager.instance.uri_for(object.thread) + end + + def conversation + return if object.conversation.nil? + + if object.conversation.uri? + object.conversation.uri + else + OStatus::TagManager.instance.unique_tag(object.conversation.created_at, object.conversation.id, 'Conversation') + end + end + + def local? + object.account.local? end class MediaAttachmentSerializer < ActiveModel::Serializer @@ -103,4 +137,22 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer "##{object.name}" end end + + class CustomEmojiSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :type, :href, :name + + def type + 'Emoji' + end + + def href + full_asset_url(object.image.url) + end + + def name + ":#{object.shortcode}:" + end + end end diff --git a/app/serializers/activitypub/reject_follow_serializer.rb b/app/serializers/activitypub/reject_follow_serializer.rb index 28584d627..7814f4f57 100644 --- a/app/serializers/activitypub/reject_follow_serializer.rb +++ b/app/serializers/activitypub/reject_follow_serializer.rb @@ -1,10 +1,14 @@ # frozen_string_literal: true class ActivityPub::RejectFollowSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor has_one :object, serializer: ActivityPub::FollowSerializer + def id + [ActivityPub::TagManager.instance.uri_for(object.target_account), '#rejects/follows/', object.id].join + end + def type 'Reject' end diff --git a/app/serializers/activitypub/undo_announce_serializer.rb b/app/serializers/activitypub/undo_announce_serializer.rb new file mode 100644 index 000000000..839847e22 --- /dev/null +++ b/app/serializers/activitypub/undo_announce_serializer.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer + attributes :id, :type, :actor + + has_one :object, serializer: ActivityPub::ActivitySerializer + + def id + [ActivityPub::TagManager.instance.uri_for(object.account), '#announces/', object.id, '/undo'].join + end + + def type + 'Undo' + end + + def actor + ActivityPub::TagManager.instance.uri_for(object.account) + end +end diff --git a/app/serializers/activitypub/undo_block_serializer.rb b/app/serializers/activitypub/undo_block_serializer.rb index f71faa729..2f43d8402 100644 --- a/app/serializers/activitypub/undo_block_serializer.rb +++ b/app/serializers/activitypub/undo_block_serializer.rb @@ -1,10 +1,14 @@ # frozen_string_literal: true class ActivityPub::UndoBlockSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor has_one :object, serializer: ActivityPub::BlockSerializer + def id + [ActivityPub::TagManager.instance.uri_for(object.account), '#blocks/', object.id, '/undo'].join + end + def type 'Undo' end diff --git a/app/serializers/activitypub/undo_follow_serializer.rb b/app/serializers/activitypub/undo_follow_serializer.rb index fe91f5f1c..e5b7f143d 100644 --- a/app/serializers/activitypub/undo_follow_serializer.rb +++ b/app/serializers/activitypub/undo_follow_serializer.rb @@ -1,10 +1,14 @@ # frozen_string_literal: true class ActivityPub::UndoFollowSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor has_one :object, serializer: ActivityPub::FollowSerializer + def id + [ActivityPub::TagManager.instance.uri_for(object.account), '#follows/', object.id, '/undo'].join + end + def type 'Undo' end diff --git a/app/serializers/activitypub/undo_like_serializer.rb b/app/serializers/activitypub/undo_like_serializer.rb index db9cd1d0d..25f4ccaae 100644 --- a/app/serializers/activitypub/undo_like_serializer.rb +++ b/app/serializers/activitypub/undo_like_serializer.rb @@ -1,10 +1,14 @@ # frozen_string_literal: true class ActivityPub::UndoLikeSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor has_one :object, serializer: ActivityPub::LikeSerializer + def id + [ActivityPub::TagManager.instance.uri_for(object.account), '#likes/', object.id, '/undo'].join + end + def type 'Undo' end diff --git a/app/serializers/activitypub/update_serializer.rb b/app/serializers/activitypub/update_serializer.rb index 322305da8..ebc667d96 100644 --- a/app/serializers/activitypub/update_serializer.rb +++ b/app/serializers/activitypub/update_serializer.rb @@ -1,10 +1,14 @@ # frozen_string_literal: true class ActivityPub::UpdateSerializer < ActiveModel::Serializer - attributes :type, :actor + attributes :id, :type, :actor has_one :object, serializer: ActivityPub::ActorSerializer + def id + [ActivityPub::TagManager.instance.uri_for(object), '#updates/', object.updated_at.to_i].join + end + def type 'Update' end diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 0191948b1..e2f15a601 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -4,22 +4,27 @@ class InitialStateSerializer < ActiveModel::Serializer attributes :meta, :compose, :accounts, :media_attachments, :settings, :push_subscription + has_many :custom_emojis, serializer: REST::CustomEmojiSerializer + + def custom_emojis + CustomEmoji.local + end + def meta store = { streaming_api_base_url: Rails.configuration.x.streaming_api_base_url, access_token: object.token, locale: I18n.locale, domain: Rails.configuration.x.local_domain, - admin: object.admin&.id, + admin: object.admin&.id&.to_s, } if object.current_account - store[:me] = object.current_account.id + store[:me] = object.current_account.id.to_s store[:unfollow_modal] = object.current_account.user.setting_unfollow_modal store[:boost_modal] = object.current_account.user.setting_boost_modal store[:delete_modal] = object.current_account.user.setting_delete_modal store[:auto_play_gif] = object.current_account.user.setting_auto_play_gif - store[:system_font_ui] = object.current_account.user.setting_system_font_ui end store @@ -29,22 +34,24 @@ class InitialStateSerializer < ActiveModel::Serializer store = {} if object.current_account - store[:me] = object.current_account.id + store[:me] = object.current_account.id.to_s store[:default_privacy] = object.current_account.user.setting_default_privacy store[:default_sensitive] = object.current_account.user.setting_default_sensitive end + store[:text] = object.text if object.text + store end def accounts store = {} - store[object.current_account.id] = ActiveModelSerializers::SerializableResource.new(object.current_account, serializer: REST::AccountSerializer) if object.current_account - store[object.admin.id] = ActiveModelSerializers::SerializableResource.new(object.admin, serializer: REST::AccountSerializer) if object.admin + store[object.current_account.id.to_s] = ActiveModelSerializers::SerializableResource.new(object.current_account, serializer: REST::AccountSerializer) if object.current_account + store[object.admin.id.to_s] = ActiveModelSerializers::SerializableResource.new(object.admin, serializer: REST::AccountSerializer) if object.admin store end def media_attachments - { accept_content_types: MediaAttachment::IMAGE_MIME_TYPES + MediaAttachment::VIDEO_MIME_TYPES } + { accept_content_types: MediaAttachment::IMAGE_FILE_EXTENSIONS + MediaAttachment::VIDEO_FILE_EXTENSIONS + MediaAttachment::IMAGE_MIME_TYPES + MediaAttachment::VIDEO_MIME_TYPES } end end diff --git a/app/serializers/oembed_serializer.rb b/app/serializers/oembed_serializer.rb index 78376d253..0c8350e2d 100644 --- a/app/serializers/oembed_serializer.rb +++ b/app/serializers/oembed_serializer.rb @@ -21,7 +21,7 @@ class OEmbedSerializer < ActiveModel::Serializer end def author_url - account_url(object.account) + short_account_url(object.account) end def provider_name @@ -37,13 +37,15 @@ class OEmbedSerializer < ActiveModel::Serializer end def html - tag :iframe, - src: embed_account_stream_entry_url(object.account, object), - style: 'width: 100%; overflow: hidden', - frameborder: '0', - scrolling: 'no', - width: width, - height: height + attributes = { + src: embed_short_account_status_url(object.account, object), + class: 'mastodon-embed', + style: 'max-width: 100%; border: 0', + width: width, + height: height, + } + + content_tag(:iframe, nil, attributes) + content_tag(:script, nil, src: full_asset_url('embed.js', skip_pipeline: true), async: true) end def width diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index 012a4fd18..65fdb0308 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -7,6 +7,10 @@ class REST::AccountSerializer < ActiveModel::Serializer :note, :url, :avatar, :avatar_static, :header, :header_static, :followers_count, :following_count, :statuses_count + def id + object.id.to_s + end + def note Formatter.instance.simplified_format(object) end diff --git a/app/serializers/rest/application_serializer.rb b/app/serializers/rest/application_serializer.rb index 868a62f1e..a8945f66e 100644 --- a/app/serializers/rest/application_serializer.rb +++ b/app/serializers/rest/application_serializer.rb @@ -4,6 +4,10 @@ class REST::ApplicationSerializer < ActiveModel::Serializer attributes :id, :name, :website, :redirect_uri, :client_id, :client_secret + def id + object.id.to_s + end + def client_id object.uid end diff --git a/app/serializers/rest/custom_emoji_serializer.rb b/app/serializers/rest/custom_emoji_serializer.rb new file mode 100644 index 000000000..b744dd4ec --- /dev/null +++ b/app/serializers/rest/custom_emoji_serializer.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class REST::CustomEmojiSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :shortcode, :url + + def url + full_asset_url(object.image.url) + end +end diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb index 8e32f9cb3..2898011fd 100644 --- a/app/serializers/rest/instance_serializer.rb +++ b/app/serializers/rest/instance_serializer.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class REST::InstanceSerializer < ActiveModel::Serializer + include RoutingHelper + attributes :uri, :title, :description, :email, - :version, :urls + :version, :urls, :stats, :thumbnail def uri Rails.configuration.x.local_domain @@ -24,7 +26,25 @@ class REST::InstanceSerializer < ActiveModel::Serializer Mastodon::Version.to_s end + def thumbnail + full_asset_url(instance_presenter.thumbnail.file.url) if instance_presenter.thumbnail + end + + def stats + { + user_count: instance_presenter.user_count, + status_count: instance_presenter.status_count, + domain_count: instance_presenter.domain_count, + } + end + def urls { streaming_api: Rails.configuration.x.streaming_api_base_url } end + + private + + def instance_presenter + @instance_presenter ||= InstancePresenter.new + end end diff --git a/app/serializers/rest/media_attachment_serializer.rb b/app/serializers/rest/media_attachment_serializer.rb index 9055b8db4..f6e7c79d1 100644 --- a/app/serializers/rest/media_attachment_serializer.rb +++ b/app/serializers/rest/media_attachment_serializer.rb @@ -6,12 +6,24 @@ class REST::MediaAttachmentSerializer < ActiveModel::Serializer attributes :id, :type, :url, :preview_url, :remote_url, :text_url, :meta + def id + object.id.to_s + end + def url - full_asset_url(object.file.url(:original)) + if object.needs_redownload? + media_proxy_url(object.id, :original) + else + full_asset_url(object.file.url(:original)) + end end def preview_url - full_asset_url(object.file.url(:small)) + if object.needs_redownload? + media_proxy_url(object.id, :small) + else + full_asset_url(object.file.url(:small)) + end end def text_url diff --git a/app/serializers/rest/mute_serializer.rb b/app/serializers/rest/mute_serializer.rb new file mode 100644 index 000000000..043a2f059 --- /dev/null +++ b/app/serializers/rest/mute_serializer.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class REST::MuteSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :id, :account, :target_account, :created_at, :hide_notifications + + def account + REST::AccountSerializer.new(object.account) + end + + def target_account + REST::AccountSerializer.new(object.target_account) + end +end \ No newline at end of file diff --git a/app/serializers/rest/notification_serializer.rb b/app/serializers/rest/notification_serializer.rb index f95d099a3..541a6b8b5 100644 --- a/app/serializers/rest/notification_serializer.rb +++ b/app/serializers/rest/notification_serializer.rb @@ -6,6 +6,10 @@ class REST::NotificationSerializer < ActiveModel::Serializer belongs_to :from_account, key: :account, serializer: REST::AccountSerializer belongs_to :target_status, key: :status, if: :status_type?, serializer: REST::StatusSerializer + def id + object.id.to_s + end + def status_type? [:favourite, :reblog, :mention].include?(object.type) end diff --git a/app/serializers/rest/relationship_serializer.rb b/app/serializers/rest/relationship_serializer.rb index 1d431aa1b..998727e37 100644 --- a/app/serializers/rest/relationship_serializer.rb +++ b/app/serializers/rest/relationship_serializer.rb @@ -4,6 +4,10 @@ class REST::RelationshipSerializer < ActiveModel::Serializer attributes :id, :following, :followed_by, :blocking, :muting, :requested, :domain_blocking + def id + object.id.to_s + end + def following instance_options[:relationships].following[object.id] || false end diff --git a/app/serializers/rest/report_serializer.rb b/app/serializers/rest/report_serializer.rb index 0c6bd6556..ecb88d653 100644 --- a/app/serializers/rest/report_serializer.rb +++ b/app/serializers/rest/report_serializer.rb @@ -2,4 +2,8 @@ class REST::ReportSerializer < ActiveModel::Serializer attributes :id, :action_taken + + def id + object.id.to_s + end end diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index 246b12a90..e6270f902 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -8,6 +8,7 @@ class REST::StatusSerializer < ActiveModel::Serializer attribute :favourited, if: :current_user? attribute :reblogged, if: :current_user? attribute :muted, if: :current_user? + attribute :pinned, if: :pinnable? belongs_to :reblog, serializer: REST::StatusSerializer belongs_to :application @@ -16,13 +17,26 @@ class REST::StatusSerializer < ActiveModel::Serializer has_many :media_attachments, serializer: REST::MediaAttachmentSerializer has_many :mentions has_many :tags + has_many :emojis, serializer: REST::CustomEmojiSerializer + + def id + object.id.to_s + end + + def in_reply_to_id + object.in_reply_to_id&.to_s + end + + def in_reply_to_account_id + object.in_reply_to_account_id&.to_s + end def current_user? !current_user.nil? end def uri - TagManager.instance.uri_for(object) + OStatus::TagManager.instance.uri_for(object) end def content @@ -57,6 +71,21 @@ class REST::StatusSerializer < ActiveModel::Serializer end end + def pinned + if instance_options && instance_options[:relationships] + instance_options[:relationships].pins_map[object.id] || false + else + current_user.account.pinned?(object) + end + end + + def pinnable? + current_user? && + current_user.account_id == object.account_id && + !object.reblog? && + %w(public unlisted).include?(object.visibility) + end + class ApplicationSerializer < ActiveModel::Serializer attributes :name, :website end @@ -65,7 +94,7 @@ class REST::StatusSerializer < ActiveModel::Serializer attributes :id, :username, :url, :acct def id - object.account_id + object.account_id.to_s end def username diff --git a/app/serializers/web/notification_serializer.rb b/app/serializers/web/notification_serializer.rb new file mode 100644 index 000000000..e5524fe7a --- /dev/null +++ b/app/serializers/web/notification_serializer.rb @@ -0,0 +1,169 @@ +# frozen_string_literal: true + +class Web::NotificationSerializer < ActiveModel::Serializer + include RoutingHelper + include StreamEntriesHelper + + class DataSerializer < ActiveModel::Serializer + include RoutingHelper + include StreamEntriesHelper + include ActionView::Helpers::SanitizeHelper + + attributes :content, :nsfw, :url, :actions, + :access_token, :message, :dir + + def content + decoder.decode(strip_tags(body)) + end + + def dir + rtl?(body) ? 'rtl' : 'ltr' + end + + def nsfw + return if object.target_status.nil? + object.target_status.spoiler_text.presence + end + + def url + case object.type + when :mention + web_url("statuses/#{object.target_status.id}") + when :follow + web_url("accounts/#{object.from_account.id}") + when :favourite + web_url("statuses/#{object.target_status.id}") + when :reblog + web_url("statuses/#{object.target_status.id}") + end + end + + def actions + return @actions if defined?(@actions) + + @actions = [] + + if object.type == :mention + @actions << expand_action if collapsed? + @actions << favourite_action + @actions << reblog_action if rebloggable? + end + + @actions + end + + def access_token + return if actions.empty? + current_push_subscription.access_token + end + + def message + I18n.t('push_notifications.group.title') + end + + private + + def body + case object.type + when :mention + object.target_status.text + when :follow + object.from_account.note + when :favourite + object.target_status.text + when :reblog + object.target_status.text + end + end + + def decoder + @decoder ||= HTMLEntities.new + end + + def expand_action + { + title: I18n.t('push_notifications.mention.action_expand'), + icon: full_asset_url('web-push-icon_expand.png', skip_pipeline: true), + todo: 'expand', + action: 'expand', + } + end + + def favourite_action + { + title: I18n.t('push_notifications.mention.action_favourite'), + icon: full_asset_url('web-push-icon_favourite.png', skip_pipeline: true), + todo: 'request', + method: 'POST', + action: "/api/v1/statuses/#{object.target_status.id}/favourite", + } + end + + def reblog_action + { + title: I18n.t('push_notifications.mention.action_boost'), + icon: full_asset_url('web-push-icon_reblog.png', skip_pipeline: true), + todo: 'request', + method: 'POST', + action: "/api/v1/statuses/#{object.target_status.id}/reblog", + } + end + + def collapsed? + !object.target_status.nil? && (object.target_status.sensitive? || object.target_status.spoiler_text.present?) + end + + def rebloggable? + !object.target_status.nil? && !object.target_status.hidden? + end + end + + attributes :title, :image, :badge, :tag, + :timestamp, :icon + + has_one :data, serializer: DataSerializer + + def title + case object.type + when :mention + I18n.t('push_notifications.mention.title', name: name) + when :follow + I18n.t('push_notifications.follow.title', name: name) + when :favourite + I18n.t('push_notifications.favourite.title', name: name) + when :reblog + I18n.t('push_notifications.reblog.title', name: name) + end + end + + def image + return if object.target_status.nil? || object.target_status.media_attachments.empty? + full_asset_url(object.target_status.media_attachments.first.file.url(:small)) + end + + def badge + full_asset_url('badge.png', skip_pipeline: true) + end + + def tag + object.id + end + + def timestamp + object.created_at + end + + def icon + object.from_account.avatar_static_url + end + + def data + object + end + + private + + def name + display_name(object.from_account) + end +end |