logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

notification_view.ex (5969B)


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