diff --git a/changelog.d/profile-image-descriptions.skip b/changelog.d/profile-image-descriptions.skip new file mode 100644 index 000000000..e69de29bb diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 517009253..7a36ece77 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -419,6 +419,11 @@ defmodule Pleroma.User do end end + def image_description(image, default \\ "") + + def image_description(%{"name" => name}, _default), do: name + def image_description(_, default), do: default + # Should probably be renamed or removed @spec ap_id(User.t()) :: String.t() def ap_id(%User{nickname: nickname}), do: "#{Endpoint.url()}/users/#{nickname}" diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index a2a94a0ff..df8795fe4 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1542,16 +1542,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp get_actor_url(_url), do: nil - defp normalize_image(%{"url" => url}) do + defp normalize_image(%{"url" => url} = data) do %{ "type" => "Image", "url" => [%{"href" => url}] } + |> maybe_put_description(data) end defp normalize_image(urls) when is_list(urls), do: urls |> List.first() |> normalize_image() defp normalize_image(_), do: nil + defp maybe_put_description(map, %{"name" => description}) when is_binary(description) do + Map.put(map, "name", description) + end + + defp maybe_put_description(map, _), do: map + defp object_to_user_data(data, additional) do fields = data diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 937e4fd67..cd485ed64 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -129,8 +129,22 @@ defmodule Pleroma.Web.ActivityPub.UserView do "vcard:bday" => birthday, "webfinger" => "acct:#{User.full_nickname(user)}" } - |> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user)) - |> Map.merge(maybe_make_image(&User.banner_url/2, "image", user)) + |> Map.merge( + maybe_make_image( + &User.avatar_url/2, + User.image_description(user.avatar, nil), + "icon", + user + ) + ) + |> Map.merge( + maybe_make_image( + &User.banner_url/2, + User.image_description(user.banner, nil), + "image", + user + ) + ) |> Map.merge(Utils.make_json_ld_header()) end @@ -305,16 +319,24 @@ defmodule Pleroma.Web.ActivityPub.UserView do end end - defp maybe_make_image(func, key, user) do + defp maybe_make_image(func, description, key, user) do if image = func.(user, no_default: true) do %{ - key => %{ - "type" => "Image", - "url" => image - } + key => + %{ + "type" => "Image", + "url" => image + } + |> maybe_put_description(description) } else %{} end end + + defp maybe_put_description(map, description) when is_binary(description) do + Map.put(map, "name", description) + end + + defp maybe_put_description(map, _description), do: map end diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 7de6745d4..f6727d29d 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -219,10 +219,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do avatar = User.avatar_url(user) |> MediaProxy.url() avatar_static = User.avatar_url(user) |> MediaProxy.preview_url(static: true) - avatar_description = image_description(user.avatar) + avatar_description = User.image_description(user.avatar) header = User.banner_url(user) |> MediaProxy.url() header_static = User.banner_url(user) |> MediaProxy.preview_url(static: true) - header_description = image_description(user.banner) + header_description = User.image_description(user.banner) following_count = if !user.hide_follows_count or !user.hide_follows or self, @@ -349,10 +349,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do defp username_from_nickname(_), do: nil - defp image_description(%{"name" => name}), do: name - - defp image_description(_), do: "" - defp maybe_put_follow_requests_count( data, %User{id: user_id} = user, diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index b4f6fb68a..72222ae88 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -232,12 +232,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert user.avatar == %{ "type" => "Image", - "url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}] + "url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}], + "name" => "profile picture" } assert user.banner == %{ "type" => "Image", - "url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}] + "url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}], + "name" => "profile picture" } end @@ -432,6 +434,35 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert user.birthday == ~D[2001-02-12] end + + test "fetches avatar description" do + user_id = "https://example.com/users/marcin" + + user_data = + "test/fixtures/users_mock/user.json" + |> File.read!() + |> String.replace("{{nickname}}", "marcin") + |> Jason.decode!() + |> Map.delete("featured") + |> Map.update("icon", %{}, fn image -> Map.put(image, "name", "image description") end) + |> Jason.encode!() + + Tesla.Mock.mock(fn + %{ + method: :get, + url: ^user_id + } -> + %Tesla.Env{ + status: 200, + body: user_data, + headers: [{"content-type", "application/activity+json"}] + } + end) + + {:ok, user} = ActivityPub.make_user_from_ap_id(user_id) + + assert user.avatar["name"] == "image description" + end end test "it fetches the appropriate tag-restricted posts" do diff --git a/test/pleroma/web/activity_pub/views/user_view_test.exs b/test/pleroma/web/activity_pub/views/user_view_test.exs index 651e535ac..a32e72829 100644 --- a/test/pleroma/web/activity_pub/views/user_view_test.exs +++ b/test/pleroma/web/activity_pub/views/user_view_test.exs @@ -68,6 +68,23 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do result = UserView.render("user.json", %{user: user}) assert result["icon"]["url"] == "https://someurl" assert result["image"]["url"] == "https://somebanner" + + refute result["icon"]["name"] + refute result["image"]["name"] + end + + test "Avatar has a description if the user set one" do + user = + insert(:user, + avatar: %{ + "url" => [%{"href" => "https://someurl"}], + "name" => "a drawing of pleroma-tan using pleroma groups" + } + ) + + result = UserView.render("user.json", %{user: user}) + + assert result["icon"]["name"] == "a drawing of pleroma-tan using pleroma groups" end test "renders an invisible user with the invisible property set to true" do