1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 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.MediaProxy
18 alias Pleroma.Web.MastodonAPI.AccountView
19 alias Pleroma.Web.MastodonAPI.NotificationView
20 alias Pleroma.Web.MastodonAPI.StatusView
21 alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
23 @parent_types ~w{Like Announce EmojiReact}
25 def render("index.json", %{notifications: notifications, for: reading_user} = opts) do
26 activities = Enum.map(notifications, & &1.activity)
31 %{data: %{"type" => type}} ->
34 |> Enum.map(& &1.data["object"])
35 |> Activity.create_by_object_ap_id()
36 |> Activity.with_preloaded_object(:left)
41 Map.has_key?(opts, :relationships) ->
44 is_nil(reading_user) ->
45 UserRelationship.view_relationships_option(nil, [])
48 move_activities_targets =
50 |> Enum.filter(&(&1.data["type"] == "Move"))
51 |> Enum.map(&User.get_cached_by_ap_id(&1.data["target"]))
56 |> Enum.map(fn a -> User.get_cached_by_ap_id(a.data["actor"]) end)
58 |> Kernel.++(move_activities_targets)
60 UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
65 |> Map.put(:parent_activities, parent_activities)
66 |> Map.put(:relationships, relationships_opt)
68 safe_render_many(notifications, NotificationView, "show.json", opts)
74 notification: %Notification{activity: activity} = notification,
78 actor = User.get_cached_by_ap_id(activity.data["actor"])
80 parent_activity_fn = fn ->
81 if opts[:parent_activities] do
82 Activity.Queries.find_by_object_ap_id(opts[:parent_activities], activity.data["object"])
84 Activity.get_create_by_object_ap_id(activity.data["object"])
88 # Note: :relationships contain user mutes (needed for :muted flag in :status)
89 status_render_opts = %{relationships: opts[:relationships]}
90 account = AccountView.render("show.json", %{user: actor, for: reading_user})
93 id: to_string(notification.id),
94 type: notification.type,
95 created_at: CommonAPI.Utils.to_masto_date(notification.inserted_at),
98 is_muted: User.mutes?(reading_user, actor),
99 is_seen: notification.seen
103 case notification.type do
105 put_status(response, activity, reading_user, status_render_opts)
108 put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
111 put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
114 put_target(response, activity, reading_user, %{})
117 put_status(response, activity, reading_user, status_render_opts)
119 "pleroma:emoji_reaction" ->
121 |> put_status(parent_activity_fn.(), reading_user, status_render_opts)
122 |> put_emoji(activity)
124 "pleroma:chat_mention" ->
125 put_chat_message(response, activity, reading_user, status_render_opts)
128 put_report(response, activity)
130 type when type in ["follow", "follow_request"] ->
135 defp put_report(response, activity) do
136 report_render = ReportView.render("show.json", Report.extract_report_info(activity))
138 Map.put(response, :report, report_render)
141 defp put_emoji(response, activity) do
143 |> Map.put(:emoji, activity.data["content"])
144 |> Map.put(:emoji_url, MediaProxy.url(Pleroma.Emoji.emoji_url(activity.data)))
147 defp put_chat_message(response, activity, reading_user, opts) do
148 object = Object.normalize(activity, fetch: false)
149 author = User.get_cached_by_ap_id(object.data["actor"])
150 chat = Pleroma.Chat.get(reading_user.id, author.ap_id)
151 cm_ref = MessageReference.for_chat_and_object(chat, object)
152 render_opts = Map.merge(opts, %{for: reading_user, chat_message_reference: cm_ref})
153 chat_message_render = MessageReferenceView.render("show.json", render_opts)
155 Map.put(response, :chat_message, chat_message_render)
158 defp put_status(response, activity, reading_user, opts) do
159 status_render_opts = Map.merge(opts, %{activity: activity, for: reading_user})
160 status_render = StatusView.render("show.json", status_render_opts)
162 Map.put(response, :status, status_render)
165 defp put_target(response, activity, reading_user, opts) do
166 target_user = User.get_cached_by_ap_id(activity.data["target"])
167 target_render_opts = Map.merge(opts, %{user: target_user, for: reading_user})
168 target_render = AccountView.render("show.json", target_render_opts)
170 Map.put(response, :target, target_render)