summaryrefslogtreecommitdiff
path: root/lib/pleroma/web/activity_pub/utils.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/web/activity_pub/utils.ex')
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex93
1 files changed, 92 insertions, 1 deletions
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index d812fd734..91cfa2194 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -255,6 +255,16 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|> Repo.one()
end
+ @doc """
+ Returns like activities targeting an object
+ """
+ def get_object_likes(%{data: %{"id" => id}}) do
+ id
+ |> Activity.Queries.by_object_id()
+ |> Activity.Queries.by_type("Like")
+ |> Repo.all()
+ end
+
@spec make_like_data(User.t(), map(), String.t()) :: map()
def make_like_data(
%User{ap_id: ap_id} = actor,
@@ -286,13 +296,30 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|> maybe_put("id", activity_id)
end
+ def make_emoji_reaction_data(user, object, emoji, activity_id) do
+ make_like_data(user, object, activity_id)
+ |> Map.put("type", "EmojiReaction")
+ |> Map.put("content", emoji)
+ end
+
@spec update_element_in_object(String.t(), list(any), Object.t()) ::
{:ok, Object.t()} | {:error, Ecto.Changeset.t()}
def update_element_in_object(property, element, object) do
+ length =
+ if is_map(element) do
+ element
+ |> Map.values()
+ |> List.flatten()
+ |> length()
+ else
+ element
+ |> length()
+ end
+
data =
Map.merge(
object.data,
- %{"#{property}_count" => length(element), "#{property}s" => element}
+ %{"#{property}_count" => length, "#{property}s" => element}
)
object
@@ -300,6 +327,38 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|> Object.update_and_set_cache()
end
+ @spec add_emoji_reaction_to_object(Activity.t(), Object.t()) ::
+ {:ok, Object.t()} | {:error, Ecto.Changeset.t()}
+
+ def add_emoji_reaction_to_object(
+ %Activity{data: %{"content" => emoji, "actor" => actor}},
+ object
+ ) do
+ reactions = object.data["reactions"] || %{}
+ emoji_actors = reactions[emoji] || []
+ new_emoji_actors = [actor | emoji_actors] |> Enum.uniq()
+ new_reactions = Map.put(reactions, emoji, new_emoji_actors)
+ update_element_in_object("reaction", new_reactions, object)
+ end
+
+ def remove_emoji_reaction_from_object(
+ %Activity{data: %{"content" => emoji, "actor" => actor}},
+ object
+ ) do
+ reactions = object.data["reactions"] || %{}
+ emoji_actors = reactions[emoji] || []
+ new_emoji_actors = List.delete(emoji_actors, actor)
+
+ new_reactions =
+ if new_emoji_actors == [] do
+ Map.delete(reactions, emoji)
+ else
+ Map.put(reactions, emoji, new_emoji_actors)
+ end
+
+ update_element_in_object("reaction", new_reactions, object)
+ end
+
@spec add_like_to_object(Activity.t(), Object.t()) ::
{:ok, Object.t()} | {:error, Ecto.Changeset.t()}
def add_like_to_object(%Activity{data: %{"actor" => actor}}, object) do
@@ -397,6 +456,19 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|> Repo.one()
end
+ def get_latest_reaction(internal_activity_id, %{ap_id: ap_id}, emoji) do
+ %{data: %{"object" => object_ap_id}} = Activity.get_by_id(internal_activity_id)
+
+ "EmojiReaction"
+ |> Activity.Queries.by_type()
+ |> where(actor: ^ap_id)
+ |> where([activity], fragment("?->>'content' = ?", activity.data, ^emoji))
+ |> Activity.Queries.by_object_id(object_ap_id)
+ |> order_by([activity], fragment("? desc nulls last", activity.id))
+ |> limit(1)
+ |> Repo.one()
+ end
+
#### Announce-related helpers
@doc """
@@ -489,6 +561,25 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|> maybe_put("id", activity_id)
end
+ def make_undo_data(
+ %User{ap_id: actor, follower_address: follower_address},
+ %Activity{
+ data: %{"id" => undone_activity_id, "context" => context},
+ actor: undone_activity_actor
+ },
+ activity_id \\ nil
+ ) do
+ %{
+ "type" => "Undo",
+ "actor" => actor,
+ "object" => undone_activity_id,
+ "to" => [follower_address, undone_activity_actor],
+ "cc" => [Pleroma.Constants.as_public()],
+ "context" => context
+ }
+ |> maybe_put("id", activity_id)
+ end
+
@spec add_announce_to_object(Activity.t(), Object.t()) ::
{:ok, Object.t()} | {:error, Ecto.Changeset.t()}
def add_announce_to_object(