Allow reacting with remote emoji when they exist on the post (#200)
Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk> Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/200
This commit is contained in:
parent
714bf0cb23
commit
787e30c5fd
7 changed files with 363 additions and 41 deletions
|
|
@ -325,21 +325,29 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
{:ok, Object.t()} | {:error, Ecto.Changeset.t()}
|
||||
|
||||
def add_emoji_reaction_to_object(
|
||||
%Activity{data: %{"content" => emoji, "actor" => actor}},
|
||||
%Activity{data: %{"content" => emoji, "actor" => actor}} = activity,
|
||||
object
|
||||
) do
|
||||
reactions = get_cached_emoji_reactions(object)
|
||||
emoji = Pleroma.Emoji.stripped_name(emoji)
|
||||
url = emoji_url(emoji, activity)
|
||||
|
||||
new_reactions =
|
||||
case Enum.find_index(reactions, fn [candidate, _] -> emoji == candidate end) do
|
||||
case Enum.find_index(reactions, fn [candidate, _, candidate_url] ->
|
||||
if is_nil(candidate_url) do
|
||||
emoji == candidate
|
||||
else
|
||||
url == candidate_url
|
||||
end
|
||||
end) do
|
||||
nil ->
|
||||
reactions ++ [[emoji, [actor]]]
|
||||
reactions ++ [[emoji, [actor], url]]
|
||||
|
||||
index ->
|
||||
List.update_at(
|
||||
reactions,
|
||||
index,
|
||||
fn [emoji, users] -> [emoji, Enum.uniq([actor | users])] end
|
||||
fn [emoji, users, url] -> [emoji, Enum.uniq([actor | users]), url] end
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -348,18 +356,40 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
update_element_in_object("reaction", new_reactions, object, count)
|
||||
end
|
||||
|
||||
defp emoji_url(
|
||||
name,
|
||||
%Activity{
|
||||
data: %{
|
||||
"tag" => [
|
||||
%{"type" => "Emoji", "name" => name, "icon" => %{"url" => url}}
|
||||
]
|
||||
}
|
||||
}
|
||||
),
|
||||
do: url
|
||||
|
||||
defp emoji_url(_, _), do: nil
|
||||
|
||||
def emoji_count(reactions_list) do
|
||||
Enum.reduce(reactions_list, 0, fn [_, users], acc -> acc + length(users) end)
|
||||
Enum.reduce(reactions_list, 0, fn [_, users, _], acc -> acc + length(users) end)
|
||||
end
|
||||
|
||||
def remove_emoji_reaction_from_object(
|
||||
%Activity{data: %{"content" => emoji, "actor" => actor}},
|
||||
%Activity{data: %{"content" => emoji, "actor" => actor}} = activity,
|
||||
object
|
||||
) do
|
||||
emoji = Pleroma.Emoji.stripped_name(emoji)
|
||||
reactions = get_cached_emoji_reactions(object)
|
||||
url = emoji_url(emoji, activity)
|
||||
|
||||
new_reactions =
|
||||
case Enum.find_index(reactions, fn [candidate, _] -> emoji == candidate end) do
|
||||
case Enum.find_index(reactions, fn [candidate, _, candidate_url] ->
|
||||
if is_nil(candidate_url) do
|
||||
emoji == candidate
|
||||
else
|
||||
url == candidate_url
|
||||
end
|
||||
end) do
|
||||
nil ->
|
||||
reactions
|
||||
|
||||
|
|
@ -367,9 +397,9 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
List.update_at(
|
||||
reactions,
|
||||
index,
|
||||
fn [emoji, users] -> [emoji, List.delete(users, actor)] end
|
||||
fn [emoji, users, url] -> [emoji, List.delete(users, actor), url] end
|
||||
)
|
||||
|> Enum.reject(fn [_, users] -> Enum.empty?(users) end)
|
||||
|> Enum.reject(fn [_, users, _] -> Enum.empty?(users) end)
|
||||
end
|
||||
|
||||
count = emoji_count(new_reactions)
|
||||
|
|
@ -489,17 +519,37 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
|
||||
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)
|
||||
emoji = Pleroma.Emoji.maybe_quote(emoji)
|
||||
|
||||
"EmojiReact"
|
||||
|> Activity.Queries.by_type()
|
||||
|> where(actor: ^ap_id)
|
||||
|> where([activity], fragment("?->>'content' = ?", activity.data, ^emoji))
|
||||
|> custom_emoji_discriminator(emoji)
|
||||
|> Activity.Queries.by_object_id(object_ap_id)
|
||||
|> order_by([activity], fragment("? desc nulls last", activity.id))
|
||||
|> limit(1)
|
||||
|> Repo.one()
|
||||
end
|
||||
|
||||
defp custom_emoji_discriminator(query, emoji) do
|
||||
if String.contains?(emoji, "@") do
|
||||
stripped = Pleroma.Emoji.stripped_name(emoji)
|
||||
[name, domain] = String.split(stripped, "@")
|
||||
domain_pattern = "%" <> domain <> "%"
|
||||
emoji_pattern = Pleroma.Emoji.maybe_quote(name)
|
||||
|
||||
query
|
||||
|> where([activity], fragment("?->>'content' = ?
|
||||
AND EXISTS (
|
||||
SELECT FROM jsonb_array_elements(?->'tag') elem
|
||||
WHERE elem->>'id' ILIKE ?
|
||||
)", activity.data, ^emoji_pattern, activity.data, ^domain_pattern))
|
||||
else
|
||||
query
|
||||
|> where([activity], fragment("?->>'content' = ?", activity.data, ^emoji))
|
||||
end
|
||||
end
|
||||
|
||||
#### Announce-related helpers
|
||||
|
||||
@doc """
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue