aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/notification.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/notification.ex')
-rw-r--r--lib/pleroma/notification.ex93
1 files changed, 75 insertions, 18 deletions
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 7efbdc49a..9e0ce0329 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -72,6 +72,7 @@ defmodule Pleroma.Notification do
pleroma:emoji_reaction
pleroma:report
reblog
+ poll
}
def changeset(%Notification{} = notification, attrs) do
@@ -127,6 +128,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
@@ -140,6 +142,17 @@ defmodule Pleroma.Notification do
|> FollowingRelationship.keep_following_or_not_domain_blocked(user)
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
query
end
@@ -379,7 +392,7 @@ defmodule Pleroma.Notification do
notifications =
Enum.map(potential_receivers, fn user ->
do_send = do_send && user in enabled_receivers
- create_notification(activity, user, do_send)
+ create_notification(activity, user, do_send: do_send)
end)
|> Enum.reject(&is_nil/1)
@@ -435,15 +448,18 @@ defmodule Pleroma.Notification do
end
# TODO move to sql, too.
- def create_notification(%Activity{} = activity, %User{} = user, do_send \\ true) do
- unless skip?(activity, user) do
+ def create_notification(%Activity{} = activity, %User{} = user, opts \\ []) do
+ do_send = Keyword.get(opts, :do_send, true)
+ type = Keyword.get(opts, :type, type_from_activity(activity))
+
+ unless skip?(activity, user, opts) do
{:ok, %{notification: notification}} =
Multi.new()
|> Multi.insert(:notification, %Notification{
user_id: user.id,
activity: activity,
seen: mark_as_read?(activity, user),
- type: type_from_activity(activity)
+ type: type
})
|> Marker.multi_set_last_read_id(user, "notifications")
|> Repo.transaction()
@@ -457,6 +473,28 @@ defmodule Pleroma.Notification do
end
end
+ def create_poll_notifications(%Activity{} = activity) do
+ with %Object{data: %{"type" => "Question", "actor" => actor} = data} <-
+ Object.normalize(activity) do
+ voters =
+ case data do
+ %{"voters" => voters} when is_list(voters) -> voters
+ _ -> []
+ end
+
+ notifications =
+ 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)
+
+ {:ok, notifications}
+ end
+ end
+
@doc """
Returns a tuple with 2 elements:
{notification-enabled receivers, currently disabled receivers (blocking / [thread] muting)}
@@ -572,8 +610,10 @@ defmodule Pleroma.Notification do
Enum.uniq(ap_ids) -- thread_muter_ap_ids
end
- @spec skip?(Activity.t(), User.t()) :: boolean()
- def skip?(%Activity{} = activity, %User{} = user) do
+ def skip?(activity, user, opts \\ [])
+
+ @spec skip?(Activity.t(), User.t(), Keyword.t()) :: boolean()
+ def skip?(%Activity{} = activity, %User{} = user, opts) do
[
:self,
:invisible,
@@ -581,17 +621,21 @@ defmodule Pleroma.Notification do
:recently_followed,
:filtered
]
- |> Enum.find(&skip?(&1, activity, user))
+ |> Enum.find(&skip?(&1, activity, user, opts))
end
- def skip?(_, _), do: false
+ def skip?(_activity, _user, _opts), do: false
- @spec skip?(atom(), Activity.t(), User.t()) :: boolean()
- def skip?(:self, %Activity{} = activity, %User{} = user) do
- activity.data["actor"] == user.ap_id
+ @spec skip?(atom(), Activity.t(), User.t(), Keyword.t()) :: boolean()
+ def skip?(:self, %Activity{} = activity, %User{} = user, opts) do
+ cond do
+ opts[:type] == "poll" -> false
+ activity.data["actor"] == user.ap_id -> true
+ true -> false
+ end
end
- def skip?(:invisible, %Activity{} = activity, _) do
+ def skip?(:invisible, %Activity{} = activity, _user, _opts) do
actor = activity.data["actor"]
user = User.get_cached_by_ap_id(actor)
User.invisible?(user)
@@ -600,15 +644,27 @@ defmodule Pleroma.Notification do
def skip?(
:block_from_strangers,
%Activity{} = activity,
- %User{notification_settings: %{block_from_strangers: true}} = user
+ %User{notification_settings: %{block_from_strangers: true}} = user,
+ opts
) do
actor = activity.data["actor"]
follower = User.get_cached_by_ap_id(actor)
- !User.following?(follower, user)
+
+ cond do
+ opts[:type] == "poll" -> false
+ user.ap_id == actor -> false
+ !User.following?(follower, user) -> true
+ true -> false
+ end
end
# To do: consider defining recency in hours and checking FollowingRelationship with a single SQL
- def skip?(:recently_followed, %Activity{data: %{"type" => "Follow"}} = activity, %User{} = user) do
+ def skip?(
+ :recently_followed,
+ %Activity{data: %{"type" => "Follow"}} = activity,
+ %User{} = user,
+ _opts
+ ) do
actor = activity.data["actor"]
Notification.for_user(user)
@@ -618,9 +674,10 @@ defmodule Pleroma.Notification do
end)
end
- def skip?(:filtered, %{data: %{"type" => type}}, _) when type in ["Follow", "Move"], do: false
+ def skip?(:filtered, %{data: %{"type" => type}}, _user, _opts) when type in ["Follow", "Move"],
+ do: false
- def skip?(:filtered, activity, user) do
+ def skip?(:filtered, activity, user, _opts) do
object = Object.normalize(activity, fetch: false)
cond do
@@ -638,7 +695,7 @@ defmodule Pleroma.Notification do
end
end
- def skip?(_, _, _), do: false
+ def skip?(_type, _activity, _user, _opts), do: false
def mark_as_read?(activity, target_user) do
user = Activity.user_actor(activity)