diff --git a/lib/clacks/actor.ex b/lib/clacks/actor.ex index 4e772a9..0402431 100644 --- a/lib/clacks/actor.ex +++ b/lib/clacks/actor.ex @@ -74,4 +74,9 @@ defmodule Clacks.Actor do end end end + + @spec get_all_following(actor :: t()) :: [t()] + def get_all_following(actor) do + Repo.all(from a in __MODULE__, where: ^actor.ap_id in a.followers) + end end diff --git a/lib/clacks_web/controllers/actor_controller.ex b/lib/clacks_web/controllers/actor_controller.ex index b0a47fd..3956085 100644 --- a/lib/clacks_web/controllers/actor_controller.ex +++ b/lib/clacks_web/controllers/actor_controller.ex @@ -1,7 +1,6 @@ defmodule ClacksWeb.ActorController do use ClacksWeb, :controller alias Clacks.Actor - import Ecto.Query @context "https://www.w3.org/ns/activitystreams" @@ -64,6 +63,42 @@ defmodule ClacksWeb.ActorController do |> json(data) end + def following(conn, %{"page" => page}) do + actor = conn.assigns[:actor] + + following = + Actor.get_all_following(actor) + |> Enum.map(fn actor -> actor.ap_id end) + + data = + collection_page(conn, following, page) + |> Map.put("@context", @context) + + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(data) + end + + def following(conn, _params) do + actor = conn.assigns[:actor] + + following = + Actor.get_all_following(actor) + |> Enum.map(fn actor -> actor.ap_id end) + + data = %{ + "@context" => @context, + "type" => "OrderedCollection", + "id" => current_url(conn, %{}), + "totalItems" => length(following), + "first" => collection_page(conn, following, 1) + } + + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(data) + end + defp collection_page(conn, collection, page) do chunks = Enum.chunk_every(collection, 20) # page is 1 indexed, so subtract 1 to get the current chunk diff --git a/lib/clacks_web/router.ex b/lib/clacks_web/router.ex index 55c9724..761ec8d 100644 --- a/lib/clacks_web/router.ex +++ b/lib/clacks_web/router.ex @@ -24,6 +24,7 @@ defmodule ClacksWeb.Router do get "/users/:nickname", ActorController, :get get "/users/:nickname/followers", ActorController, :followers + get "/users/:nickname/following", ActorController, :following post "/inbox", InboxController, :shared post "/users/:nickname/inbox", InboxController, :user_specific