extend reject MRF to check if originating instance is blocked
[akkoma] / lib / pleroma / web / mastodon_api / views / notification_view.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.MastodonAPI.NotificationView do
6 use Pleroma.Web, :view
7
8 alias Pleroma.Activity
9 alias Pleroma.Notification
10 alias Pleroma.User
11 alias Pleroma.UserRelationship
12 alias Pleroma.Web.AdminAPI.Report
13 alias Pleroma.Web.AdminAPI.ReportView
14 alias Pleroma.Web.CommonAPI
15 alias Pleroma.Web.MediaProxy
16 alias Pleroma.Web.MastodonAPI.AccountView
17 alias Pleroma.Web.MastodonAPI.NotificationView
18 alias Pleroma.Web.MastodonAPI.StatusView
19
20 defp object_id_for(%{data: %{"object" => %{"id" => id}}}) when is_binary(id), do: id
21
22 defp object_id_for(%{data: %{"object" => id}}) when is_binary(id), do: id
23
24 @parent_types ~w{Like Announce EmojiReact Update}
25
26 def render("index.json", %{notifications: notifications, for: reading_user} = opts) do
27 activities = Enum.map(notifications, & &1.activity)
28
29 parent_activities =
30 activities
31 |> Enum.filter(fn
32 %{data: %{"type" => type}} ->
33 type in @parent_types
34 end)
35 |> Enum.map(&object_id_for/1)
36 |> Activity.create_by_object_ap_id()
37 |> Activity.with_preloaded_object(:left)
38 |> Pleroma.Repo.all()
39
40 relationships_opt =
41 cond do
42 Map.has_key?(opts, :relationships) ->
43 opts[:relationships]
44
45 is_nil(reading_user) ->
46 UserRelationship.view_relationships_option(nil, [])
47
48 true ->
49 move_activities_targets =
50 activities
51 |> Enum.filter(&(&1.data["type"] == "Move"))
52 |> Enum.map(&User.get_cached_by_ap_id(&1.data["target"]))
53 |> Enum.filter(& &1)
54
55 actors =
56 activities
57 |> Enum.map(fn a -> User.get_cached_by_ap_id(a.data["actor"]) end)
58 |> Enum.filter(& &1)
59 |> Kernel.++(move_activities_targets)
60
61 UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
62 end
63
64 opts =
65 opts
66 |> Map.put(:parent_activities, parent_activities)
67 |> Map.put(:relationships, relationships_opt)
68
69 safe_render_many(notifications, NotificationView, "show.json", opts)
70 end
71
72 def render(
73 "show.json",
74 %{
75 notification: %Notification{activity: activity} = notification,
76 for: reading_user
77 } = opts
78 ) do
79 actor = User.get_cached_by_ap_id(activity.data["actor"])
80
81 parent_activity_fn = fn ->
82 if opts[:parent_activities] do
83 Activity.Queries.find_by_object_ap_id(opts[:parent_activities], object_id_for(activity))
84 else
85 Activity.get_create_by_object_ap_id(object_id_for(activity))
86 end
87 end
88
89 # Note: :relationships contain user mutes (needed for :muted flag in :status)
90 status_render_opts = %{relationships: opts[:relationships]}
91 account = AccountView.render("show.json", %{user: actor, for: reading_user})
92
93 response = %{
94 id: to_string(notification.id),
95 type: notification.type,
96 created_at: CommonAPI.Utils.to_masto_date(notification.inserted_at),
97 account: account,
98 pleroma: %{
99 is_muted: User.mutes?(reading_user, actor),
100 is_seen: notification.seen
101 }
102 }
103
104 case notification.type do
105 "mention" ->
106 put_status(response, activity, reading_user, status_render_opts)
107
108 "favourite" ->
109 put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
110
111 "reblog" ->
112 put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
113
114 "update" ->
115 put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
116
117 "move" ->
118 put_target(response, activity, reading_user, %{})
119
120 "poll" ->
121 put_status(response, activity, reading_user, status_render_opts)
122
123 "pleroma:emoji_reaction" ->
124 response
125 |> put_status(parent_activity_fn.(), reading_user, status_render_opts)
126 |> put_emoji(activity)
127
128 "pleroma:report" ->
129 put_report(response, activity)
130
131 type when type in ["follow", "follow_request"] ->
132 response
133 end
134 end
135
136 defp put_report(response, activity) do
137 report_render = ReportView.render("show.json", Report.extract_report_info(activity))
138
139 Map.put(response, :report, report_render)
140 end
141
142 defp put_emoji(response, activity) do
143 response
144 |> Map.put(:emoji, activity.data["content"])
145 |> Map.put(:emoji_url, MediaProxy.url(Pleroma.Emoji.emoji_url(activity.data)))
146 end
147
148 defp put_status(response, activity, reading_user, opts) do
149 status_render_opts = Map.merge(opts, %{activity: activity, for: reading_user})
150 status_render = StatusView.render("show.json", status_render_opts)
151
152 Map.put(response, :status, status_render)
153 end
154
155 defp put_target(response, activity, reading_user, opts) do
156 target_user = User.get_cached_by_ap_id(activity.data["target"])
157 target_render_opts = Map.merge(opts, %{user: target_user, for: reading_user})
158 target_render = AccountView.render("show.json", target_render_opts)
159
160 Map.put(response, :target, target_render)
161 end
162 end