diff --git a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php new file mode 100644 index 000000000..b06d8ea56 --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php @@ -0,0 +1,42 @@ +domain == null; + $is_admin = !$local ? false : $profile->user->is_admin; + $acct = $local ? $profile->username : substr($profile->username, 1); + $username = $local ? $profile->username : explode('@', $acct)[0]; + return [ + 'id' => (string) $profile->id, + 'username' => $username, + 'acct' => $acct, + 'display_name' => $profile->name, + 'locked' => (bool) $profile->is_private, + 'created_at' => $profile->created_at->format('c'), + 'followers_count' => $profile->followerCount(), + 'following_count' => $profile->followingCount(), + 'statuses_count' => (int) $profile->statusCount(), + 'note' => $profile->bio ?? '', + 'url' => $profile->url(), + 'avatar' => $profile->avatarUrl(), + 'avatar_static' => $profile->avatarUrl(), + 'header' => '', + 'header_static' => '', + 'header_bg' => $profile->header_bg, + 'emojis' => [], + 'moved' => null, + 'fields' => [], + 'bot' => false, + 'website' => $profile->website, + 'software' => 'pixelfed', + 'is_admin' => (bool) $is_admin, + ]; + } +} diff --git a/app/Transformer/Api/Mastodon/v1/HashtagTransformer.php b/app/Transformer/Api/Mastodon/v1/HashtagTransformer.php new file mode 100644 index 000000000..7956a8adc --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/HashtagTransformer.php @@ -0,0 +1,17 @@ + $hashtag->name, + 'url' => $hashtag->url(), + ]; + } +} diff --git a/app/Transformer/Api/Mastodon/v1/MediaTransformer.php b/app/Transformer/Api/Mastodon/v1/MediaTransformer.php new file mode 100644 index 000000000..ceb96abec --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/MediaTransformer.php @@ -0,0 +1,23 @@ + (string) $media->id, + 'type' => lcfirst($media->activityVerb()), + 'url' => $media->url(), + 'remote_url' => null, + 'preview_url' => $media->thumbnailUrl(), + 'text_url' => null, + 'meta' => null, + 'description' => $media->caption + ]; + } +} \ No newline at end of file diff --git a/app/Transformer/Api/Mastodon/v1/MentionTransformer.php b/app/Transformer/Api/Mastodon/v1/MentionTransformer.php new file mode 100644 index 000000000..774f4122e --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/MentionTransformer.php @@ -0,0 +1,19 @@ + (string) $profile->id, + 'url' => $profile->url(), + 'username' => $profile->username, + 'acct' => $profile->username, + ]; + } +} diff --git a/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php new file mode 100644 index 000000000..0f16da9be --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php @@ -0,0 +1,59 @@ + (string) $notification->id, + 'type' => $this->replaceTypeVerb($notification->action), + 'created_at' => (string) $notification->created_at->format('c'), + ]; + } + + public function includeAccount(Notification $notification) + { + return $this->item($notification->actor, new AccountTransformer()); + } + + public function includeStatus(Notification $notification) + { + $item = $notification; + if($item->item_id && $item->item_type == 'App\Status') { + $status = Status::with('media')->find($item->item_id); + if($status) { + return $this->item($status, new StatusTransformer()); + } else { + return null; + } + } else { + return null; + } + } + + public function replaceTypeVerb($verb) + { + $verbs = [ + 'follow' => 'follow', + 'mention' => 'mention', + 'reblog' => 'share', + 'share' => 'share', + 'like' => 'favourite', + 'comment' => 'comment', + ]; + return $verbs[$verb]; + } +} diff --git a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php new file mode 100644 index 000000000..6ddaf468b --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php @@ -0,0 +1,81 @@ + (string) $status->id, + 'uri' => $status->url(), + 'url' => $status->url(), + 'in_reply_to_id' => $status->in_reply_to_id, + 'in_reply_to_account_id' => $status->in_reply_to_profile_id, + 'reblog' => null, + 'content' => $status->rendered ?? $status->caption, + 'created_at' => $status->created_at->format('c'), + 'emojis' => [], + 'reblogs_count' => $status->reblogs_count != 0 ? $status->reblogs_count: $status->shares()->count(), + 'favourites_count' => $status->likes_count != 0 ? $status->likes_count: $status->likes()->count(), + 'reblogged' => null, + 'favourited' => null, + 'muted' => null, + 'sensitive' => (bool) $status->is_nsfw, + 'spoiler_text' => $status->cw_summary ?? '', + 'visibility' => $status->visibility ?? $status->scope, + 'application' => [ + 'name' => 'web', + 'website' => null + ], + 'language' => null, + 'pinned' => null, + 'mentions' => [], + + 'parent' => [], + 'place' => $status->place + ]; + } + + public function includeAccount(Status $status) + { + $account = $status->profile; + + return $this->item($account, new AccountTransformer()); + } + + public function includeMediaAttachments(Status $status) + { + return Cache::remember('status:transformer:media:attachments:'.$status->id, now()->addDays(14), function() use($status) { + if(in_array($status->type, ['photo', 'video', 'photo:album', 'loop', 'photo:video:album'])) { + $media = $status->media()->orderBy('order')->get(); + return $this->collection($media, new MediaTransformer()); + } + }); + } + + public function includeMentions(Status $status) + { + $mentions = $status->mentions; + + return $this->collection($mentions, new MentionTransformer()); + } + + public function includeTags(Status $status) + { + $hashtags = $status->hashtags; + + return $this->collection($hashtags, new HashtagTransformer()); + } +} \ No newline at end of file