{:ok, data, []}
end
+ defp unicode_emoji_react(_object, data, emoji) do
+ data
+ |> Map.put("content", emoji)
+ |> Map.put("type", "EmojiReact")
+ end
+
+ 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
+
+ defp remote_custom_emoji_react(
+ %{data: %{"reactions" => existing_reactions}},
+ data,
+ emoji
+ ) do
+ [emoji_code, instance] = String.split(Emoji.stripped_name(emoji), "@")
+
+ 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 remote_custom_emoji_react(_object, _data, _emoji) do
+ {:error, "Could not react"}
+ 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
+
@spec emoji_react(User.t(), Object.t(), String.t()) :: {:ok, map(), keyword()}
def emoji_react(actor, object, emoji) do
with {:ok, data, meta} <- object_action(actor, object) do
data =
if Emoji.is_unicode_emoji?(emoji) do
- data
- |> Map.put("content", emoji)
- |> Map.put("type", "EmojiReact")
+ unicode_emoji_react(object, data, emoji)
else
- with %{} = emojo <- Emoji.get(emoji) do
- path = emojo |> Map.get(:file)
- url = "#{Endpoint.url()}#{path}"
-
- 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
+ custom_emoji_react(object, data, emoji)
end
{:ok, data, meta}
"tag" => Keyword.values(draft.tags) |> Enum.uniq()
}
|> add_in_reply_to(draft.in_reply_to)
+ |> add_quote(draft.quote)
|> Map.merge(draft.extra)
{:ok, data, []}
end
end
+ defp add_quote(object, nil), do: object
+
+ defp add_quote(object, quote) do
+ with %Object{} = quote_object <- Object.normalize(quote, fetch: false) do
+ Map.put(object, "quoteUri", quote_object.data["id"])
+ else
+ _ -> object
+ end
+ end
+
def answer(user, object, name) do
{:ok,
%{
end
end
- # Retricted to user updates for now, always public
@spec update(User.t(), Object.t()) :: {:ok, map(), keyword()}
def update(actor, object) do
- to = [Pleroma.Constants.as_public(), actor.follower_address]
+ {to, cc} =
+ if object["type"] in Pleroma.Constants.actor_types() do
+ # User updates, always public
+ {[Pleroma.Constants.as_public(), actor.follower_address], []}
+ else
+ # Status updates, follow the recipients in the object
+ {object["to"] || [], object["cc"] || []}
+ end
{:ok,
%{
"type" => "Update",
"actor" => actor.ap_id,
"object" => object,
- "to" => to
+ "to" => to,
+ "cc" => cc
}, []}
end