allow reacting with remote custom emoji

This commit is contained in:
FloatingGhost 2022-08-27 11:13:54 +01:00
parent 439b192829
commit e40d45a585
5 changed files with 72 additions and 31 deletions

View file

@ -55,39 +55,66 @@ def follow(follower, followed) do
{:ok, data, []}
end
defp unicode_emoji_react(object, data, emoji) do
defp unicode_emoji_react(_object, data, emoji) do
data
|> Map.put("content", emoji)
|> Map.put("type", "EmojiReact")
end
defp custom_emoji_react(object, data, emoji) do
if String.contains?("@") do
# Attempt to resolve remote emoji
[emoji_code, instance] = String.split(emoji, "@")
else
with %{} = emojo <- Emoji.get(emoji) do
path = emojo |> Map.get(:file)
url = "#{Endpoint.url()}#{path}"
defp add_emoji_content(data, emoji, url) do
data
|> Map.put("content", Emoji.maybe_quote(emoji))
|> Map.put("type", "EmojiReact")
|> Map.put("tag", [
%{}
|> Map.put("id", url)
|> Map.put("type", "Emoji")
|> Map.put("name", Emoji.maybe_quote(emoji))
|> Map.put(
"icon",
%{}
|> Map.put("type", "Image")
|> Map.put("url", url)
)
])
end
data
|> Map.put("content", emoji)
|> Map.put("type", "EmojiReact")
|> Map.put("tag", [
%{}
|> Map.put("id", url)
|> Map.put("type", "Emoji")
|> Map.put("name", emojo.code)
|> Map.put(
"icon",
%{}
|> Map.put("type", "Image")
|> Map.put("url", url)
)
])
else
_ -> {:error, "Emoji does not exist"}
end
defp remote_custom_emoji_react(object, data, emoji) do
[emoji_code, instance] = String.split(Emoji.stripped_name(emoji), "@")
%{data: %{"reactions" => existing_reactions}} = object
matching_reaction =
Enum.find(
existing_reactions,
fn [name, _, url] ->
url = URI.parse(url)
url.host == instance && name == emoji_code
end
)
if matching_reaction do
[name, _, url] = matching_reaction
add_emoji_content(data, name, url)
else
{:error, "Could not react"}
end
end
defp local_custom_emoji_react(data, emoji) do
with %{} = emojo <- Emoji.get(emoji) do
path = emojo |> Map.get(:file)
url = "#{Endpoint.url()}#{path}"
add_emoji_content(data, emojo.code, url)
else
_ -> {:error, "Emoji does not exist"}
end
end
defp custom_emoji_react(object, data, emoji) do
if String.contains?(emoji, "@") do
remote_custom_emoji_react(object, data, emoji)
else
local_custom_emoji_react(data, emoji)
end
end

View file

@ -13,7 +13,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
@primary_key false
@emoji_regex ~r/:[A-Za-z0-9_-]+:/
@emoji_regex ~r/:[A-Za-z0-9_-]+(@.+)?:/
embedded_schema do
quote do

View file

@ -209,7 +209,9 @@ def react_with_emoji(id, user, emoji) do
{:ok, activity, _} <- Pipeline.common_pipeline(emoji_react, local: true) do
{:ok, activity}
else
_ -> {:error, dgettext("errors", "Could not add reaction emoji")}
e ->
IO.inspect(e)
{:error, dgettext("errors", "Could not add reaction emoji")}
end
end

View file

@ -587,7 +587,7 @@ defp pin_data(%Object{data: %{"id" => object_id}}, %User{pinned_objects: pinned_
defp build_emoji_map(emoji, users, url, current_user) do
%{
name: emoji,
name: Pleroma.Web.PleromaAPI.EmojiReactionView.emoji_name(emoji, url),
count: length(users),
url: MediaProxy.url(url),
me: !!(current_user && current_user.ap_id in users),

View file

@ -8,6 +8,18 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionView do
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MediaProxy
def emoji_name(emoji, nil), do: emoji
def emoji_name(emoji, url) do
url = URI.parse(url)
if url.host == Endpoint.host() do
emoji
else
"#{emoji}@#{url.host}"
end
end
def render("index.json", %{emoji_reactions: emoji_reactions} = opts) do
render_many(emoji_reactions, __MODULE__, "show.json", opts)
end
@ -16,7 +28,7 @@ def render("show.json", %{emoji_reaction: {emoji, user_ap_ids, url}, user: user}
users = fetch_users(user_ap_ids)
%{
name: emoji,
name: emoji_name(emoji, url),
count: length(users),
accounts: render(AccountView, "index.json", users: users, for: user),
url: MediaProxy.url(url),