mobilizon/lib/graphql/api/follows.ex

87 lines
2.6 KiB
Elixir

defmodule Mobilizon.GraphQL.API.Follows do
@moduledoc """
Common API for following, unfollowing, accepting and rejecting stuff.
"""
alias Mobilizon.Actors
alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Federation.ActivityPub.{Actions, Activity}
require Logger
@doc """
Make an actor (`follower`) follow another (`followed`).
"""
@spec follow(follower :: Actor.t(), followed :: Actor.t()) ::
{:ok, Activity.t(), Mobilizon.Actors.Follower.t()}
| {:error, String.t()}
def follow(%Actor{} = follower, %Actor{} = followed) do
Actions.Follow.follow(follower, followed)
end
@doc """
Make an actor (`follower`) unfollow another (`followed`).
"""
@spec unfollow(follower :: Actor.t(), followed :: Actor.t()) ::
{:ok, Activity.t(), Mobilizon.Actors.Follower.t()}
| {:error, String.t()}
def unfollow(%Actor{} = follower, %Actor{} = followed) do
Actions.Follow.unfollow(follower, followed)
end
@doc """
Make an actor (`followed`) accept the follow from another (`follower`).
"""
@spec accept(follower :: Actor.t(), followed :: Actor.t()) ::
{:ok, Activity.t(), Mobilizon.Actors.Follower.t()}
| {:error, String.t()}
def accept(%Actor{url: follower_url} = follower, %Actor{url: followed_url} = followed) do
Logger.debug(
"We're trying to accept a follow: #{followed_url} is accepting #{follower_url} follow request."
)
case Actors.is_following(follower, followed) do
%Follower{approved: false} = follow ->
Actions.Accept.accept(
:follow,
follow,
true
)
%Follower{approved: true} ->
{:error, "Follow already accepted"}
nil ->
{:error, "Can't accept follow: #{follower_url} is not following #{followed_url}."}
end
end
@doc """
Make an actor (`followed`) reject the follow from another (`follower`).
"""
@spec reject(follower :: Actor.t(), followed :: Actor.t()) ::
{:ok, Activity.t(), Mobilizon.Actors.Follower.t()}
| {:error, String.t()}
def reject(%Actor{url: follower_url} = follower, %Actor{url: followed_url} = followed) do
Logger.debug(
"We're trying to reject a follow: #{followed_url} is rejecting #{follower_url} follow request."
)
case Actors.is_following(follower, followed) do
%Follower{approved: true} ->
{:error, "Follow already accepted"}
%Follower{} = follow ->
Actions.Reject.reject(
:follow,
follow,
true
)
nil ->
{:error, "Follow not found"}
end
end
end