From a71c51a174d6e25d4b30b80ac1fafbd52c308a43 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Thu, 24 Mar 2022 14:19:24 +0100
Subject: [PATCH] Expose member count in AP data

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 lib/federation/activity_pub/utils.ex              |  4 ++++
 lib/federation/activity_stream/converter/actor.ex |  8 +++++---
 lib/mobilizon/actors/actors.ex                    | 11 +++++++++++
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/lib/federation/activity_pub/utils.ex b/lib/federation/activity_pub/utils.ex
index 9743662a5..84efe8ff0 100644
--- a/lib/federation/activity_pub/utils.ex
+++ b/lib/federation/activity_pub/utils.ex
@@ -117,6 +117,10 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do
             "@id" => "mz:participantCount",
             "@type" => "sc:Integer"
           },
+          "memberCount" => %{
+            "@id" => "mz:memberCount",
+            "@type" => "sc:Integer"
+          },
           "isOnline" => %{
             "@type" => "sc:Boolean",
             "@id" => "mz:isOnline"
diff --git a/lib/federation/activity_stream/converter/actor.ex b/lib/federation/activity_stream/converter/actor.ex
index d564f162c..27fe5037a 100644
--- a/lib/federation/activity_stream/converter/actor.ex
+++ b/lib/federation/activity_stream/converter/actor.ex
@@ -6,8 +6,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
   internal one, and back.
   """
 
+  alias Mobilizon.Actors
   alias Mobilizon.Actors.Actor, as: ActorModel
-
   alias Mobilizon.Addresses.Address
   alias Mobilizon.Federation.ActivityPub.Utils
   alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
@@ -154,8 +154,10 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
     end
   end
 
-  defp maybe_add_members(actor_data, %ActorModel{type: :Group, members_url: members_url}) do
-    Map.put(actor_data, "members", members_url)
+  defp maybe_add_members(actor_data, %ActorModel{type: :Group, members_url: members_url} = group) do
+    actor_data
+    |> Map.put("members", members_url)
+    |> Map.put("memberCount", Actors.count_members_for_group(group))
   end
 
   defp maybe_add_members(actor_data, %ActorModel{}), do: actor_data
diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex
index 1df299fb6..4b4344c89 100644
--- a/lib/mobilizon/actors/actors.ex
+++ b/lib/mobilizon/actors/actors.ex
@@ -890,6 +890,17 @@ defmodule Mobilizon.Actors do
     |> (&(&1 == 0)).()
   end
 
+  @doc """
+  Returns the number of followers for a group
+  """
+  @spec count_members_for_group(Actor.t()) :: integer()
+  def count_members_for_group(%Actor{id: actor_id}) do
+    actor_id
+    |> members_for_group_query()
+    # |> where([m], m.role in @member_roles)
+    |> Repo.aggregate(:count)
+  end
+
   @doc """
   Gets a single bot.
   Raises `Ecto.NoResultsError` if the bot does not exist.