X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fnotification.ex;h=66e91fcef08272489133150458023012336c9fc1;hb=6813c0302c2b665d337d5f5831d2df6312b6b277;hp=f37e7ec671ee88c39848cc92a7f715621766999e;hpb=13926537b644c3a4f1904c2fcd5d25fe0f284663;p=akkoma diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index f37e7ec67..66e91fcef 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -21,6 +21,8 @@ defmodule Pleroma.Notification do @type t :: %__MODULE__{} + @include_muted_option :with_muted + schema "notifications" do field(:seen, :boolean, default: false) belongs_to(:user, User, type: FlakeId.Ecto.CompatType) @@ -34,7 +36,25 @@ defmodule Pleroma.Notification do |> cast(attrs, [:seen]) end - def for_user_query(user, opts \\ []) do + defp for_user_query_ap_id_opts(user, opts) do + ap_id_relations = + [:block] ++ + if opts[@include_muted_option], do: [], else: [:notification_mute] + + preloaded_ap_ids = User.outgoing_relations_ap_ids(user, ap_id_relations) + + exclude_blocked_opts = Map.merge(%{blocked_users_ap_ids: preloaded_ap_ids[:block]}, opts) + + exclude_notification_muted_opts = + Map.merge(%{notification_muted_users_ap_ids: preloaded_ap_ids[:notification_mute]}, opts) + + {exclude_blocked_opts, exclude_notification_muted_opts} + end + + def for_user_query(user, opts \\ %{}) do + {exclude_blocked_opts, exclude_notification_muted_opts} = + for_user_query_ap_id_opts(user, opts) + Notification |> where(user_id: ^user.id) |> where( @@ -54,43 +74,75 @@ defmodule Pleroma.Notification do ) ) |> preload([n, a, o], activity: {a, object: o}) - |> exclude_muted(user, opts) - |> exclude_blocked(user) + |> exclude_notification_muted(user, exclude_notification_muted_opts) + |> exclude_blocked(user, exclude_blocked_opts) |> exclude_visibility(opts) + |> exclude_move(opts) end - defp exclude_blocked(query, user) do + defp exclude_blocked(query, user, opts) do + blocked_ap_ids = opts[:blocked_users_ap_ids] || User.blocked_users_ap_ids(user) + query - |> where([n, a], a.actor not in ^user.blocks) + |> where([n, a], a.actor not in ^blocked_ap_ids) |> where( [n, a], fragment("substring(? from '.*://([^/]*)')", a.actor) not in ^user.domain_blocks ) end - defp exclude_muted(query, _, %{with_muted: true}) do + defp exclude_notification_muted(query, _, %{@include_muted_option => true}) do query end - defp exclude_muted(query, user, _opts) do + defp exclude_notification_muted(query, user, opts) do + notification_muted_ap_ids = + opts[:notification_muted_users_ap_ids] || User.notification_muted_users_ap_ids(user) + query - |> where([n, a], a.actor not in ^user.muted_notifications) + |> where([n, a], a.actor not in ^notification_muted_ap_ids) |> join(:left, [n, a], tm in Pleroma.ThreadMute, on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data) ) |> where([n, a, o, tm], is_nil(tm.user_id)) end + defp exclude_move(query, %{with_move: true}) do + query + end + + defp exclude_move(query, _opts) do + where(query, [n, a], fragment("?->>'type' != 'Move'", a.data)) + end + @valid_visibilities ~w[direct unlisted public private] defp exclude_visibility(query, %{exclude_visibilities: visibility}) when is_list(visibility) do if Enum.all?(visibility, &(&1 in @valid_visibilities)) do query + |> join(:left, [n, a], mutated_activity in Pleroma.Activity, + on: + fragment("?->>'context'", a.data) == + fragment("?->>'context'", mutated_activity.data) and + fragment("(?->>'type' = 'Like' or ?->>'type' = 'Announce')", a.data, a.data) and + fragment("?->>'type'", mutated_activity.data) == "Create", + as: :mutated_activity + ) |> where( - [n, a], + [n, a, mutated_activity: mutated_activity], not fragment( - "activity_visibility(?, ?, ?) = ANY (?)", + """ + CASE WHEN (?->>'type') = 'Like' or (?->>'type') = 'Announce' + THEN (activity_visibility(?, ?, ?) = ANY (?)) + ELSE (activity_visibility(?, ?, ?) = ANY (?)) END + """, + a.data, + a.data, + mutated_activity.actor, + mutated_activity.recipients, + mutated_activity.data, + ^visibility, a.actor, a.recipients, a.data, @@ -105,17 +157,7 @@ defmodule Pleroma.Notification do defp exclude_visibility(query, %{exclude_visibilities: visibility}) when visibility in @valid_visibilities do - query - |> where( - [n, a], - not fragment( - "activity_visibility(?, ?, ?) = (?)", - a.actor, - a.recipients, - a.data, - ^visibility - ) - ) + exclude_visibility(query, [visibility]) end defp exclude_visibility(query, %{exclude_visibilities: visibility}) @@ -252,7 +294,7 @@ defmodule Pleroma.Notification do end def create_notifications(%Activity{data: %{"type" => type}} = activity) - when type in ["Like", "Announce", "Follow", "Move"] do + when type in ["Like", "Announce", "Follow", "Move", "EmojiReact"] do notifications = activity |> get_notified_from_activity() @@ -280,7 +322,7 @@ 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"] do + when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact"] do [] |> Utils.maybe_notify_to_recipients(activity) |> Utils.maybe_notify_mentioned_recipients(activity) @@ -313,7 +355,7 @@ defmodule Pleroma.Notification do def skip?( :followers, activity, - %{notification_settings: %{"followers" => false}} = user + %{notification_settings: %{followers: false}} = user ) do actor = activity.data["actor"] follower = User.get_cached_by_ap_id(actor) @@ -323,14 +365,14 @@ defmodule Pleroma.Notification do def skip?( :non_followers, activity, - %{notification_settings: %{"non_followers" => false}} = user + %{notification_settings: %{non_followers: false}} = user ) do actor = activity.data["actor"] follower = User.get_cached_by_ap_id(actor) !User.following?(follower, user) end - def skip?(:follows, activity, %{notification_settings: %{"follows" => false}} = user) do + def skip?(:follows, activity, %{notification_settings: %{follows: false}} = user) do actor = activity.data["actor"] followed = User.get_cached_by_ap_id(actor) User.following?(user, followed) @@ -339,7 +381,7 @@ defmodule Pleroma.Notification do def skip?( :non_follows, activity, - %{notification_settings: %{"non_follows" => false}} = user + %{notification_settings: %{non_follows: false}} = user ) do actor = activity.data["actor"] followed = User.get_cached_by_ap_id(actor)