+ @spec unread_count_query(User.t()) :: Ecto.Queryable.t()
+ def unread_count_query(user) do
+ from(q in Pleroma.Notification,
+ where: q.user_id == ^user.id,
+ where: q.seen == false
+ )
+ end
+
+ @spec last_read_query(User.t()) :: Ecto.Queryable.t()
+ def last_read_query(user) do
+ from(q in Pleroma.Notification,
+ where: q.user_id == ^user.id,
+ where: q.seen == true,
+ select: type(q.id, :string),
+ limit: 1,
+ order_by: [desc: :id]
+ )
+ end
+
+ 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(
+ [n, a],
+ fragment(
+ "? not in (SELECT ap_id FROM users WHERE deactivated = 'true')",
+ a.actor
+ )
+ )
+ |> join(:inner, [n], activity in assoc(n, :activity))
+ |> join(:left, [n, a], object in Object,
+ on: