Merge pull request 'emoji reaction standardisation' (#14) from emoji-reaction-standar...
authorfloatingghost <hannah@coffee-and-dreams.uk>
Sat, 25 Jun 2022 14:46:32 +0000 (14:46 +0000)
committerfloatingghost <hannah@coffee-and-dreams.uk>
Sat, 25 Jun 2022 14:46:32 +0000 (14:46 +0000)
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/14

lib/pleroma/emoji.ex
lib/pleroma/web/api_spec/operations/emoji_reaction_operation.ex
test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs

index 9e1858ae73308ae333b293af7a999e07a8ceaaa2..ced2ae83d28f1702cf5d8faa55d9005208cdf789 100644 (file)
@@ -159,7 +159,11 @@ defmodule Pleroma.Emoji do
     if is_unicode_emoji?(name) do
       name
     else
-      ":#{name}:"
+      if String.starts_with?(name, ":") do
+        name
+      else
+        ":#{name}:"
+      end
     end
   end
 
index a7b306a30871e349f7fab93daa527e71612a6b15..b254fc57bd6ac07a1093be7dd20e0814453dd6e3 100644 (file)
@@ -43,10 +43,14 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
   def create_operation do
     %Operation{
       tags: ["Emoji reactions"],
-      summary: "React to a post with a unicode emoji",
+      summary: "React to a post with either a unicode or custom emoji",
       parameters: [
         Operation.parameter(:id, :path, FlakeID, "Status ID", required: true),
-        Operation.parameter(:emoji, :path, :string, "A single character unicode emoji",
+        Operation.parameter(
+          :emoji,
+          :path,
+          :string,
+          "A single character unicode emoji, or a \:shortcode\: format emoji name",
           required: true
         )
       ],
@@ -62,10 +66,14 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
   def delete_operation do
     %Operation{
       tags: ["Emoji reactions"],
-      summary: "Remove a reaction to a post with a unicode emoji",
+      summary: "Remove a reaction to a post with either a unicode or custom emoji",
       parameters: [
         Operation.parameter(:id, :path, FlakeID, "Status ID", required: true),
-        Operation.parameter(:emoji, :path, :string, "A single character unicode emoji",
+        Operation.parameter(
+          :emoji,
+          :path,
+          :string,
+          "A single character unicode emoji, or a \:shortcode\: format emoji name",
           required: true
         )
       ],
@@ -81,7 +89,7 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
     Operation.response("Array of Emoji reactions", "application/json", %Schema{
       type: :array,
       items: emoji_reaction(),
-      example: [emoji_reaction().example]
+      example: emoji_reaction().example
     })
   end
 
@@ -93,18 +101,34 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
         name: %Schema{type: :string, description: "Emoji"},
         count: %Schema{type: :integer, description: "Count of reactions with this emoji"},
         me: %Schema{type: :boolean, description: "Did I react with this emoji?"},
+        url: %Schema{
+          type: :string,
+          description: "URL of the emoji if it's custom - otherwise null",
+          nullable: true,
+          format: "url"
+        },
         accounts: %Schema{
           type: :array,
           items: Account,
           description: "Array of accounts reacted with this emoji"
         }
       },
-      example: %{
-        "name" => "😱",
-        "count" => 1,
-        "me" => false,
-        "accounts" => [Account.schema().example]
-      }
+      example: [
+        %{
+          "name" => "😱",
+          "count" => 1,
+          "me" => false,
+          "url" => nil,
+          "accounts" => [Account.schema().example]
+        },
+        %{
+          "name" => "dinosaur",
+          "count" => 1,
+          "me" => false,
+          "url" => "https://akkoma.dev/emoji/dinosaur.png",
+          "accounts" => [Account.schema().example]
+        }
+      ]
     }
   end
 end
index 3f47ceb755939c1832485b56034b0c0deda010fa..65bb22e274b8824ac18afa87d1b52ea9b5315929 100644 (file)
@@ -34,6 +34,30 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
              %{"name" => "☕", "count" => 1, "me" => true, "url" => nil}
            ]
 
+    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
+
+    ObanHelpers.perform_all()
+    # Reacting with a custom emoji
+    result =
+      conn
+      |> assign(:user, other_user)
+      |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
+      |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/:dinosaur:")
+      |> json_response_and_validate_schema(200)
+
+    # We return the status, but this our implementation detail.
+    assert %{"id" => id} = result
+    assert to_string(activity.id) == id
+
+    assert result["pleroma"]["emoji_reactions"] == [
+             %{
+               "name" => "dinosaur",
+               "count" => 1,
+               "me" => true,
+               "url" => "http://localhost:4001/emoji/dino walking.gif"
+             }
+           ]
+
     # Reacting with a non-emoji
     assert conn
            |> assign(:user, other_user)
@@ -48,6 +72,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
 
     {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
     {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
+    {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, ":dinosaur:")
 
     ObanHelpers.perform_all()
 
@@ -60,6 +85,17 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
     assert %{"id" => id} = json_response_and_validate_schema(result, 200)
     assert to_string(activity.id) == id
 
+    # Remove custom emoji
+
+    result =
+      conn
+      |> assign(:user, other_user)
+      |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
+      |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/:dinosaur:")
+
+    assert %{"id" => id} = json_response_and_validate_schema(result, 200)
+    assert to_string(activity.id) == id
+
     ObanHelpers.perform_all()
 
     object = Object.get_by_ap_id(activity.data["object"])