1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.MastodonAPI.NotificationView do
9 alias Pleroma.Chat.MessageReference
10 alias Pleroma.Notification
13 alias Pleroma.UserRelationship
14 alias Pleroma.Web.AdminAPI.Report
15 alias Pleroma.Web.AdminAPI.ReportView
16 alias Pleroma.Web.CommonAPI
17 alias Pleroma.Web.MastodonAPI.AccountView
18 alias Pleroma.Web.MastodonAPI.NotificationView
19 alias Pleroma.Web.MastodonAPI.StatusView
20 alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
22 defp object_id_for(%{data: %{"object" => %{"id" => id}}}) when is_binary(id), do: id
24 defp object_id_for(%{data: %{"object" => id}}) when is_binary(id), do: id
26 @parent_types ~w{Like Announce EmojiReact Update}
28 def render("index.json", %{notifications: notifications, for: reading_user} = opts) do
29 activities = Enum.map(notifications, & &1.activity)
34 %{data: %{"type" => type}} ->
37 |> Enum.map(&object_id_for/1)
38 |> Activity.create_by_object_ap_id()
39 |> Activity.with_preloaded_object(:left)
44 Map.has_key?(opts, :relationships) ->
47 is_nil(reading_user) ->
48 UserRelationship.view_relationships_option(nil, [])
51 move_activities_targets =
53 |> Enum.filter(&(&1.data["type"] == "Move"))
54 |> Enum.map(&User.get_cached_by_ap_id(&1.data["target"]))
59 |> Enum.map(fn a -> User.get_cached_by_ap_id(a.data["actor"]) end)
61 |> Kernel.++(move_activities_targets)
63 UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
68 |> Map.put(:parent_activities, parent_activities)
69 |> Map.put(:relationships, relationships_opt)
71 safe_render_many(notifications, NotificationView, "show.json", opts)
77 notification: %Notification{activity: activity} = notification,
81 actor = User.get_cached_by_ap_id(activity.data["actor"])
83 parent_activity_fn = fn ->
84 if opts[:parent_activities] do
85 Activity.Queries.find_by_object_ap_id(opts[:parent_activities], object_id_for(activity))
87 Activity.get_create_by_object_ap_id(object_id_for(activity))
91 # Note: :relationships contain user mutes (needed for :muted flag in :status)
92 status_render_opts = %{relationships: opts[:relationships]}
93 account = AccountView.render("show.json", %{user: actor, for: reading_user})
96 id: to_string(notification.id),
97 type: notification.type,
98 created_at: CommonAPI.Utils.to_masto_date(notification.inserted_at),
101 is_muted: User.mutes?(reading_user, actor),
102 is_seen: notification.seen
106 case notification.type do
108 put_status(response, activity, reading_user, status_render_opts)
111 put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
114 put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
117 put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
120 put_target(response, activity, reading_user, %{})
123 put_status(response, activity, reading_user, status_render_opts)
125 "pleroma:emoji_reaction" ->
127 |> put_status(parent_activity_fn.(), reading_user, status_render_opts)
128 |> put_emoji(activity)
130 "pleroma:chat_mention" ->
131 put_chat_message(response, activity, reading_user, status_render_opts)
134 put_report(response, activity)
136 type when type in ["follow", "follow_request"] ->
141 defp put_report(response, activity) do
142 report_render = ReportView.render("show.json", Report.extract_report_info(activity))
144 Map.put(response, :report, report_render)
147 defp put_emoji(response, activity) do
148 Map.put(response, :emoji, activity.data["content"])
151 defp put_chat_message(response, activity, reading_user, opts) do
152 object = Object.normalize(activity, fetch: false)
153 author = User.get_cached_by_ap_id(object.data["actor"])
154 chat = Pleroma.Chat.get(reading_user.id, author.ap_id)
155 cm_ref = MessageReference.for_chat_and_object(chat, object)
156 render_opts = Map.merge(opts, %{for: reading_user, chat_message_reference: cm_ref})
157 chat_message_render = MessageReferenceView.render("show.json", render_opts)
159 Map.put(response, :chat_message, chat_message_render)
162 defp put_status(response, activity, reading_user, opts) do
163 status_render_opts = Map.merge(opts, %{activity: activity, for: reading_user})
164 status_render = StatusView.render("show.json", status_render_opts)
166 Map.put(response, :status, status_render)
169 defp put_target(response, activity, reading_user, opts) do
170 target_user = User.get_cached_by_ap_id(activity.data["target"])
171 target_render_opts = Map.merge(opts, %{user: target_user, for: reading_user})
172 target_render = AccountView.render("show.json", target_render_opts)
174 Map.put(response, :target, target_render)