add remote user count for the heck of it
[akkoma] / lib / pleroma / notification.ex
index 4a6e5d3f931c58b67dbcfcdd80a2cb18203243ba..3995be01f7a2d8d217704c99e32d921108aa8883 100644 (file)
@@ -68,7 +68,6 @@ defmodule Pleroma.Notification do
     follow_request
     mention
     move
-    pleroma:chat_mention
     pleroma:emoji_reaction
     pleroma:report
     reblog
@@ -128,6 +127,7 @@ defmodule Pleroma.Notification do
     |> where([user_actor: user_actor], user_actor.is_active)
     |> exclude_notification_muted(user, exclude_notification_muted_opts)
     |> exclude_blocked(user, exclude_blocked_opts)
+    |> exclude_blockers(user)
     |> exclude_filtered(user)
     |> exclude_visibility(opts)
   end
@@ -138,7 +138,35 @@ defmodule Pleroma.Notification do
 
     query
     |> where([n, a], a.actor not in ^blocked_ap_ids)
-    |> FollowingRelationship.keep_following_or_not_domain_blocked(user)
+    |> restrict_domain_blocked(user)
+  end
+
+  defp restrict_domain_blocked(query, user) do
+    where(
+      query,
+      [_, activity],
+      fragment(
+        # "(actor's domain NOT in domain_blocks)"
+        """
+        NOT (
+          substring(? from '.*://([^/]*)') = ANY(?)
+        )
+        """,
+        activity.actor,
+        ^user.domain_blocks
+      )
+    )
+  end
+
+  defp exclude_blockers(query, user) do
+    if Pleroma.Config.get([:activitypub, :blockers_visible]) == true do
+      query
+    else
+      blocker_ap_ids = User.incoming_relationships_ungrouped_ap_ids(user, [:block])
+
+      query
+      |> where([n, a], a.actor not in ^blocker_ap_ids)
+    end
   end
 
   defp exclude_notification_muted(query, _, %{@include_muted_option => true}) do
@@ -329,6 +357,14 @@ defmodule Pleroma.Notification do
     |> Repo.delete_all()
   end
 
+  def destroy_multiple_from_types(%{id: user_id}, types) do
+    from(n in Notification,
+      where: n.user_id == ^user_id,
+      where: n.type in ^types
+    )
+    |> Repo.delete_all()
+  end
+
   def dismiss(%Pleroma.Activity{} = activity) do
     Notification
     |> where([n], n.activity_id == ^activity.id)
@@ -365,7 +401,7 @@ defmodule Pleroma.Notification do
   end
 
   def create_notifications(%Activity{data: %{"type" => type}} = activity, options)
-      when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag"] do
+      when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag", "Update"] do
     do_create_notifications(activity, options)
   end
 
@@ -419,21 +455,15 @@ defmodule Pleroma.Notification do
         activity
         |> type_from_activity_object()
 
+      "Update" ->
+        "update"
+
       t ->
         raise "No notification type for activity type #{t}"
     end
   end
 
-  defp type_from_activity_object(%{data: %{"type" => "Create", "object" => %{}}}), do: "mention"
-
-  defp type_from_activity_object(%{data: %{"type" => "Create"}} = activity) do
-    object = Object.get_by_ap_id(activity.data["object"])
-
-    case object && object.data["type"] do
-      "ChatMessage" -> "pleroma:chat_mention"
-      _ -> "mention"
-    end
-  end
+  defp type_from_activity_object(%{data: %{"type" => "Create"}}), do: "mention"
 
   # TODO move to sql, too.
   def create_notification(%Activity{} = activity, %User{} = user, opts \\ []) do
@@ -471,9 +501,11 @@ defmodule Pleroma.Notification do
         end
 
       notifications =
-        Enum.map([actor | voters], fn ap_id ->
-          with %User{} = user <- User.get_by_ap_id(ap_id) do
-            create_notification(activity, user, type: "poll")
+        Enum.reduce([actor | voters], [], fn ap_id, acc ->
+          with %User{local: true} = user <- User.get_by_ap_id(ap_id) do
+            [create_notification(activity, user, type: "poll") | acc]
+          else
+            _ -> acc
           end
         end)
 
@@ -491,7 +523,16 @@ defmodule Pleroma.Notification do
   def get_notified_from_activity(activity, local_only \\ true)
 
   def get_notified_from_activity(%Activity{data: %{"type" => type}} = activity, local_only)
-      when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact", "Flag"] do
+      when type in [
+             "Create",
+             "Like",
+             "Announce",
+             "Follow",
+             "Move",
+             "EmojiReact",
+             "Flag",
+             "Update"
+           ] do
     potential_receiver_ap_ids = get_potential_receiver_ap_ids(activity)
 
     potential_receivers =
@@ -531,6 +572,21 @@ defmodule Pleroma.Notification do
     (User.all_superusers() |> Enum.map(fn user -> user.ap_id end)) -- [actor]
   end
 
+  # Update activity: notify all who repeated this
+  def get_potential_receiver_ap_ids(%{data: %{"type" => "Update", "actor" => actor}} = activity) do
+    with %Object{data: %{"id" => object_id}} <- Object.normalize(activity, fetch: false) do
+      repeaters =
+        Activity.Queries.by_type("Announce")
+        |> Activity.Queries.by_object_id(object_id)
+        |> Activity.with_joined_user_actor()
+        |> where([a, u], u.local)
+        |> select([a, u], u.ap_id)
+        |> Repo.all()
+
+      repeaters -- [actor]
+    end
+  end
+
   def get_potential_receiver_ap_ids(activity) do
     []
     |> Utils.maybe_notify_to_recipients(activity)