From d0b45de175eccf7a5a39296e681df6f5381de635 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 25 Oct 2021 13:18:46 +0200 Subject: [PATCH] Expose person follows Signed-off-by: Thomas Citharel --- lib/graphql/resolvers/person.ex | 47 +++++++++++++++++++++++++++-- lib/graphql/schema/actors/person.ex | 15 +++++++++ lib/mobilizon/actors/actors.ex | 8 +++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/lib/graphql/resolvers/person.ex b/lib/graphql/resolvers/person.ex index 709927d40..1076d72b4 100644 --- a/lib/graphql/resolvers/person.ex +++ b/lib/graphql/resolvers/person.ex @@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do import Mobilizon.Users.Guards alias Mobilizon.{Actors, Events, Users} - alias Mobilizon.Actors.{Actor, Member} + alias Mobilizon.Actors.{Actor, Follower, Member} alias Mobilizon.Events.Participant alias Mobilizon.Storage.{Page, Repo} alias Mobilizon.Users.User @@ -355,7 +355,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do end @doc """ - Returns the list of events this person is going to + Returns this person's group memberships """ @spec person_memberships(Actor.t(), map(), map()) :: {:ok, Page.t()} | {:error, String.t()} def person_memberships(%Actor{id: actor_id} = person, %{group: group}, %{ @@ -398,6 +398,49 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do end end + @doc """ + Returns this person's group follows + """ + @spec person_follows(Actor.t(), map(), map()) :: {:ok, Page.t()} | {:error, String.t()} + def person_follows(%Actor{id: actor_id} = person, %{group: group}, %{ + context: %{current_user: %User{} = user} + }) do + if user_can_access_person_details?(person, user) do + with {:group, %Actor{} = group} <- {:group, Actors.get_actor_by_name(group, :Group)}, + %Follower{} = follow <- + Actors.get_follower_by_followed_and_following(group, person) do + {:ok, + %Page{ + total: 1, + elements: [follow] + }} + else + nil -> + {:ok, %Page{total: 0, elements: []}} + + {:group, nil} -> + {:error, :group_not_found} + end + else + {:error, dgettext("errors", "Profile is not owned by authenticated user")} + end + end + + def person_follows( + %Actor{} = person, + %{page: page, limit: limit}, + %{ + context: %{current_user: %User{} = user} + } + ) do + if user_can_access_person_details?(person, user) do + follows = Actors.list_paginated_follows_for_actor(person, page, limit) + {:ok, follows} + else + {:error, dgettext("errors", "Profile is not owned by authenticated user")} + end + end + @spec user_for_person(Actor.t(), map(), Absinthe.Resolution.t()) :: {:ok, User.t() | nil} | {:error, String.t() | nil} def user_for_person(%Actor{type: :Person, user_id: user_id}, _args, %{ diff --git a/lib/graphql/schema/actors/person.ex b/lib/graphql/schema/actors/person.ex index 42743316f..65fd6c54a 100644 --- a/lib/graphql/schema/actors/person.ex +++ b/lib/graphql/schema/actors/person.ex @@ -102,6 +102,21 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do arg(:limit, :integer, default_value: 10, description: "The limit of memberships per page") resolve(&Person.person_memberships/3) end + + @desc "The list of groups this person follows" + field(:follows, :paginated_follower_list, + description: "The list of groups this person follows" + ) do + arg(:group, :string, description: "Filter by group federated username") + + arg(:page, :integer, + default_value: 1, + description: "The page in the follows list" + ) + + arg(:limit, :integer, default_value: 10, description: "The limit of follows per page") + resolve(&Person.person_follows/3) + end end @desc """ diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index 68fe1fdcb..da6b0e848 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -1030,6 +1030,14 @@ defmodule Mobilizon.Actors do |> Repo.delete() end + @spec list_paginated_follows_for_actor(Actor.t(), integer | nil, integer | nil) :: + Page.t(Follower.t()) + def list_paginated_follows_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do + actor_id + |> followings_for_actor_query + |> Page.build_page(page, limit) + end + @doc """ Returns the list of external followers for an actor. """