Remove _misskey_reaction matching (#500)
[akkoma] / lib / pleroma / emoji.ex
index f484f96a0e9ea8f4154af735038b0fe7de270a50..933f4275af1d6cec7625b52ad00c9491b620798e 100644 (file)
@@ -9,6 +9,7 @@ defmodule Pleroma.Emoji do
   """
   use GenServer
 
+  alias Pleroma.Emoji.Combinations
   alias Pleroma.Emoji.Loader
 
   require Logger
@@ -20,6 +21,7 @@ defmodule Pleroma.Emoji do
     :named_table,
     {:read_concurrency, true}
   ]
+  @emoji_regex ~r/:[A-Za-z0-9_-]+(@.+)?:/
 
   defstruct [:code, :file, :tags, :safe_code, :safe_file]
 
@@ -50,13 +52,14 @@ defmodule Pleroma.Emoji do
   @doc "Returns the path of the emoji `name`."
   @spec get(String.t()) :: String.t() | nil
   def get(name) do
-    name = if String.starts_with?(name, ":") do
-      name
-      |> String.replace_leading(":", "")
-      |> String.replace_trailing(":", "")
-    else
-      name
-    end
+    name =
+      if String.starts_with?(name, ":") do
+        name
+        |> String.replace_leading(":", "")
+        |> String.replace_trailing(":", "")
+      else
+        name
+      end
 
     case :ets.lookup(@ets, name) do
       [{_, path}] -> path
@@ -123,7 +126,7 @@ defmodule Pleroma.Emoji do
     |> String.split("\n")
     |> Enum.filter(fn line ->
       line != "" and not String.starts_with?(line, "#") and
-        String.contains?(line, "qualified")
+        String.contains?(line, "fully-qualified")
     end)
     |> Enum.map(fn line ->
       line
@@ -145,4 +148,65 @@ defmodule Pleroma.Emoji do
   end
 
   def is_unicode_emoji?(_), do: false
+
+  def stripped_name(name) when is_binary(name) do
+    name
+    |> String.replace_leading(":", "")
+    |> String.replace_trailing(":", "")
+  end
+
+  def stripped_name(name), do: name
+
+  def maybe_quote(name) when is_binary(name) do
+    if is_unicode_emoji?(name) do
+      name
+    else
+      if String.starts_with?(name, ":") do
+        name
+      else
+        ":#{name}:"
+      end
+    end
+  end
+
+  def maybe_quote(name), do: name
+
+  def emoji_url(%{"type" => "EmojiReact", "content" => _, "tag" => []}), do: nil
+
+  def emoji_url(%{"type" => "EmojiReact", "content" => emoji, "tag" => tags}) do
+    tag =
+      tags
+      |> Enum.find(fn tag -> tag["type"] == "Emoji" && tag["name"] == stripped_name(emoji) end)
+
+    if is_nil(tag) do
+      nil
+    else
+      tag
+      |> Map.get("icon")
+      |> Map.get("url")
+    end
+  end
+
+  def emoji_url(_), do: nil
+
+  def emoji_name_with_instance(name, url) do
+    url = url |> URI.parse() |> Map.get(:host)
+    "#{name}@#{url}"
+  end
+
+  emoji_qualification_map =
+    emojis
+    |> Enum.filter(&String.contains?(&1, "\uFE0F"))
+    |> Combinations.variate_emoji_qualification()
+
+  for {qualified, unqualified_list} <- emoji_qualification_map do
+    for unqualified <- unqualified_list do
+      def fully_qualify_emoji(unquote(unqualified)), do: unquote(qualified)
+    end
+  end
+
+  def fully_qualify_emoji(emoji), do: emoji
+
+  def matches_shortcode?(nil), do: false
+  def matches_shortcode?(s), do: Regex.match?(@emoji_regex, s)
 end