X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fmastodon_api%2Fviews%2Fstatus_view.ex;h=715d40766604bf8a8d2dd103728fcb93681c2558;hb=5ea5c58a85b7be56370b151ce8977982d47fde8c;hp=ec582b919c626aa5c8f1e9330a03c0d1afafac8d;hpb=829e99722396c2372770f50d9fc7cfa40c441005;p=akkoma diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index ec582b919..715d40766 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -5,7 +5,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do use Pleroma.Web, :view + require Pleroma.Constants + alias Pleroma.Activity + alias Pleroma.ActivityExpiration + alias Pleroma.Conversation + alias Pleroma.Conversation.Participation alias Pleroma.HTML alias Pleroma.Object alias Pleroma.Repo @@ -19,22 +24,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1] # TODO: Add cached version. + defp get_replied_to_activities([]), do: %{} + defp get_replied_to_activities(activities) do activities |> Enum.map(fn - %{data: %{"type" => "Create", "object" => object}} -> - object = Object.normalize(object) - object.data["inReplyTo"] != "" && object.data["inReplyTo"] + %{data: %{"type" => "Create"}} = activity -> + object = Object.normalize(activity) + object && object.data["inReplyTo"] != "" && object.data["inReplyTo"] _ -> nil end) |> Enum.filter(& &1) - |> Activity.create_by_object_ap_id() + |> Activity.create_by_object_ap_id_with_object() |> Repo.all() |> Enum.reduce(%{}, fn activity, acc -> object = Object.normalize(activity) - Map.put(acc, object.data["id"], activity) + if object, do: Map.put(acc, object.data["id"], activity), else: acc end) end @@ -66,17 +73,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do def render("index.json", opts) do replied_to_activities = get_replied_to_activities(opts.activities) + opts = Map.put(opts, :replied_to_activities, replied_to_activities) - opts.activities - |> safe_render_many( - StatusView, - "status.json", - Map.put(opts, :replied_to_activities, replied_to_activities) - ) + safe_render_many(opts.activities, StatusView, "show.json", opts) end def render( - "status.json", + "show.json", %{activity: %{data: %{"type" => "Announce", "object" => _object}} = activity} = opts ) do user = get_user(activity.data["actor"]) @@ -86,9 +89,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do reblogged_activity = Activity.create_by_object_ap_id(activity_object.data["id"]) |> Activity.with_preloaded_bookmark(opts[:for]) + |> Activity.with_set_thread_muted_field(opts[:for]) |> Repo.one() - reblogged = render("status.json", Map.put(opts, :activity, reblogged_activity)) + reblogged = render("show.json", Map.put(opts, :activity, reblogged_activity)) favorited = opts[:for] && opts[:for].ap_id in (activity_object.data["likes"] || []) @@ -136,10 +140,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do } end - def render("status.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do + def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do object = Object.normalize(activity) user = get_user(activity.data["actor"]) + user_follower_address = user.follower_address like_count = object.data["like_count"] || 0 announcement_count = object.data["announcement_count"] || 0 @@ -147,9 +152,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do tags = object.data["tag"] || [] sensitive = object.data["sensitive"] || Enum.member?(tags, "nsfw") + tag_mentions = + tags + |> Enum.filter(fn tag -> is_map(tag) and tag["type"] == "Mention" end) + |> Enum.map(fn tag -> tag["href"] end) + mentions = - activity.recipients - |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end) + (object.data["to"] ++ tag_mentions) + |> Enum.uniq() + |> Enum.map(fn + Pleroma.Constants.as_public() -> nil + ^user_follower_address -> nil + ap_id -> User.get_cached_by_ap_id(ap_id) + end) |> Enum.filter(& &1) |> Enum.map(fn user -> AccountView.render("mention.json", %{user: user}) end) @@ -157,10 +172,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do bookmarked = Activity.get_bookmark(activity, opts[:for]) != nil + client_posted_this_activity = opts[:for] && user.id == opts[:for].id + + expires_at = + with true <- client_posted_this_activity, + expiration when not is_nil(expiration) <- + ActivityExpiration.get_by_activity_id(activity.id) do + expiration.scheduled_at + end + thread_muted? = case activity.thread_muted? do thread_muted? when is_boolean(thread_muted?) -> thread_muted? - nil -> CommonAPI.thread_muted?(user, activity) + nil -> (opts[:for] && CommonAPI.thread_muted?(opts[:for], activity)) || false end attachment_data = object.data["attachment"] || [] @@ -214,7 +238,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do if user.local do Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, activity) else - object.data["external_url"] || object.data["id"] + object.data["url"] || object.data["external_url"] || object.data["id"] + end + + direct_conversation_id = + with {_, true} <- {:include_id, opts[:with_direct_conversation_id]}, + {_, %User{} = for_user} <- {:for_user, opts[:for]}, + %{data: %{"context" => context}} when is_binary(context) <- activity, + %Conversation{} = conversation <- Conversation.get_for_ap_id(context), + %Participation{id: participation_id} <- + Participation.for_user_and_conversation(for_user, conversation) do + participation_id + else + _e -> + nil end %{ @@ -254,12 +291,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do conversation_id: get_context_id(activity), in_reply_to_account_acct: reply_to_user && reply_to_user.nickname, content: %{"text/plain" => content_plaintext}, - spoiler_text: %{"text/plain" => summary_plaintext} + spoiler_text: %{"text/plain" => summary_plaintext}, + expires_at: expires_at, + direct_conversation_id: direct_conversation_id, + thread_muted: thread_muted? } } end - def render("status.json", _) do + def render("show.json", _) do nil end @@ -339,16 +379,27 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do end if options do - end_time = - (object.data["closed"] || object.data["endTime"]) - |> NaiveDateTime.from_iso8601!() - - expired = - end_time - |> NaiveDateTime.compare(NaiveDateTime.utc_now()) - |> case do - :lt -> true - _ -> false + {end_time, expired} = + case object.data["closed"] || object.data["endTime"] do + end_time when is_binary(end_time) -> + end_time = + (object.data["closed"] || object.data["endTime"]) + |> NaiveDateTime.from_iso8601!() + + expired = + end_time + |> NaiveDateTime.compare(NaiveDateTime.utc_now()) + |> case do + :lt -> true + _ -> false + end + + end_time = Utils.to_masto_date(end_time) + + {end_time, expired} + + _ -> + {nil, false} end voted = @@ -374,8 +425,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do %{ # Mastodon uses separate ids for polls, but an object can't have # more than one poll embedded so object id is fine - id: object.id, - expires_at: Utils.to_masto_date(end_time), + id: to_string(object.id), + expires_at: end_time, expired: expired, multiple: multiple, votes_count: votes_count, @@ -388,6 +439,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do end end + def render("context.json", %{activity: activity, activities: activities, user: user}) do + %{ancestors: ancestors, descendants: descendants} = + activities + |> Enum.reverse() + |> Enum.group_by(fn %{id: id} -> if id < activity.id, do: :ancestors, else: :descendants end) + |> Map.put_new(:ancestors, []) + |> Map.put_new(:descendants, []) + + %{ + ancestors: render("index.json", for: user, activities: ancestors, as: :activity), + descendants: render("index.json", for: user, activities: descendants, as: :activity) + } + end + def get_reply_to(activity, %{replied_to_activities: replied_to_activities}) do object = Object.normalize(activity) @@ -442,7 +507,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do object_tags = for tag when is_binary(tag) <- object_tags, do: tag Enum.reduce(object_tags, [], fn tag, tags -> - tags ++ [%{name: tag, url: "/tag/#{tag}"}] + tags ++ [%{name: tag, url: "/tag/#{URI.encode(tag)}"}] end) end