projects
/
akkoma
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'fix/cast-and-validate' into 'develop'
[akkoma]
/
lib
/
pleroma
/
notification.ex
diff --git
a/lib/pleroma/notification.ex
b/lib/pleroma/notification.ex
index 41ac5350586beda729b1466b0592aae980caa507..9ee9606becb9fd9bf779d81b6b72a01c5b4595ac 100644
(file)
--- a/
lib/pleroma/notification.ex
+++ b/
lib/pleroma/notification.ex
@@
-30,6
+30,9
@@
defmodule Pleroma.Notification do
schema "notifications" do
field(:seen, :boolean, default: false)
schema "notifications" do
field(:seen, :boolean, default: false)
+ # This is an enum type in the database. If you add a new notification type,
+ # remember to add a migration to add it to the `notifications_type` enum
+ # as well.
field(:type, :string)
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType)
field(:type, :string)
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType)
@@
-58,9
+61,21
@@
defmodule Pleroma.Notification do
|> Repo.aggregate(:count, :id)
end
|> Repo.aggregate(:count, :id)
end
+ @notification_types ~w{
+ favourite
+ follow
+ follow_request
+ mention
+ move
+ pleroma:chat_mention
+ pleroma:emoji_reaction
+ reblog
+ }
+
def changeset(%Notification{} = notification, attrs) do
notification
|> cast(attrs, [:seen, :type])
def changeset(%Notification{} = notification, attrs) do
notification
|> cast(attrs, [:seen, :type])
+ |> validate_inclusion(:type, @notification_types)
end
@spec last_read_query(User.t()) :: Ecto.Queryable.t()
end
@spec last_read_query(User.t()) :: Ecto.Queryable.t()
@@
-151,8
+166,16
@@
defmodule Pleroma.Notification do
query
|> join(:left, [n, a], mutated_activity in Pleroma.Activity,
on:
query
|> join(:left, [n, a], mutated_activity in Pleroma.Activity,
on:
- fragment("?->>'context'", a.data) ==
- fragment("?->>'context'", mutated_activity.data) and
+ fragment(
+ "COALESCE((?->'object')->>'id', ?->>'object')",
+ a.data,
+ a.data
+ ) ==
+ fragment(
+ "COALESCE((?->'object')->>'id', ?->>'object')",
+ mutated_activity.data,
+ mutated_activity.data
+ ) and
fragment("(?->>'type' = 'Like' or ?->>'type' = 'Announce')", a.data, a.data) and
fragment("?->>'type'", mutated_activity.data) == "Create",
as: :mutated_activity
fragment("(?->>'type' = 'Like' or ?->>'type' = 'Announce')", a.data, a.data) and
fragment("?->>'type'", mutated_activity.data) == "Create",
as: :mutated_activity
@@
-314,30
+337,34
@@
defmodule Pleroma.Notification do
end
end
end
end
- def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = activity) do
+ def create_notifications(activity, options \\ [])
+
+ def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = activity, options) do
object = Object.normalize(activity, false)
if object && object.data["type"] == "Answer" do
{:ok, []}
else
object = Object.normalize(activity, false)
if object && object.data["type"] == "Answer" do
{:ok, []}
else
- do_create_notifications(activity)
+ do_create_notifications(activity
, options
)
end
end
end
end
- def create_notifications(%Activity{data: %{"type" => type}} = activity)
+ def create_notifications(%Activity{data: %{"type" => type}} = activity
, options
)
when type in ["Follow", "Like", "Announce", "Move", "EmojiReact"] do
when type in ["Follow", "Like", "Announce", "Move", "EmojiReact"] do
- do_create_notifications(activity)
+ do_create_notifications(activity
, options
)
end
end
- def create_notifications(_), do: {:ok, []}
+ def create_notifications(_, _), do: {:ok, []}
+
+ defp do_create_notifications(%Activity{} = activity, options) do
+ do_send = Keyword.get(options, :do_send, true)
- defp do_create_notifications(%Activity{} = activity) do
{enabled_receivers, disabled_receivers} = get_notified_from_activity(activity)
potential_receivers = enabled_receivers ++ disabled_receivers
notifications =
Enum.map(potential_receivers, fn user ->
{enabled_receivers, disabled_receivers} = get_notified_from_activity(activity)
potential_receivers = enabled_receivers ++ disabled_receivers
notifications =
Enum.map(potential_receivers, fn user ->
- do_send = user in enabled_receivers
+ do_send =
do_send &&
user in enabled_receivers
create_notification(activity, user, do_send)
end)
create_notification(activity, user, do_send)
end)
@@
-365,6
+392,10
@@
defmodule Pleroma.Notification do
"EmojiReact" ->
"pleroma:emoji_reaction"
"EmojiReact" ->
"pleroma:emoji_reaction"
+ # Compatibility with old reactions
+ "EmojiReaction" ->
+ "pleroma:emoji_reaction"
+
"Create" ->
activity
|> type_from_activity_object()
"Create" ->
activity
|> type_from_activity_object()
@@
-374,10
+405,12
@@
defmodule Pleroma.Notification do
end
end
end
end
+ defp type_from_activity_object(%{data: %{"type" => "Create", "object" => %{}}}), do: "mention"
+
defp type_from_activity_object(%{data: %{"type" => "Create"}} = activity) do
defp type_from_activity_object(%{data: %{"type" => "Create"}} = activity) do
- object = Object.
normalize(activity, false
)
+ object = Object.
get_by_ap_id(activity.data["object"]
)
- case object.data["type"] do
+ case object
&& object
.data["type"] do
"ChatMessage" -> "pleroma:chat_mention"
_ -> "mention"
end
"ChatMessage" -> "pleroma:chat_mention"
_ -> "mention"
end
@@
-516,6
+549,7
@@
defmodule Pleroma.Notification do
def skip?(%Activity{} = activity, %User{} = user) do
[
:self,
def skip?(%Activity{} = activity, %User{} = user) do
[
:self,
+ :invisible,
:followers,
:follows,
:non_followers,
:followers,
:follows,
:non_followers,
@@
-532,6
+566,12
@@
defmodule Pleroma.Notification do
activity.data["actor"] == user.ap_id
end
activity.data["actor"] == user.ap_id
end
+ def skip?(:invisible, %Activity{} = activity, _) do
+ actor = activity.data["actor"]
+ user = User.get_cached_by_ap_id(actor)
+ User.invisible?(user)
+ end
+
def skip?(
:followers,
%Activity{} = activity,
def skip?(
:followers,
%Activity{} = activity,
@@
-584,4
+624,12
@@
defmodule Pleroma.Notification do
end
def skip?(_, _, _), do: false
end
def skip?(_, _, _), do: false
+
+ def for_user_and_activity(user, activity) do
+ from(n in __MODULE__,
+ where: n.user_id == ^user.id,
+ where: n.activity_id == ^activity.id
+ )
+ |> Repo.one()
+ end
end
end