Support lists exclusive param

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk 2026-02-18 11:06:13 +01:00 committed by nicole mikołajczyk
commit 490cd33bc9
11 changed files with 133 additions and 48 deletions

View file

@ -17,13 +17,14 @@ defmodule Pleroma.List do
field(:title, :string)
field(:following, {:array, :string}, default: [])
field(:ap_id, :string)
field(:exclusive, :boolean, default: false)
timestamps()
end
def title_changeset(list, attrs \\ %{}) do
def update_changeset(list, attrs \\ %{}) do
list
|> cast(attrs, [:title])
|> cast(attrs, [:title, :exclusive])
|> validate_required([:title])
end
@ -91,14 +92,14 @@ defmodule Pleroma.List do
|> Repo.all()
end
def rename(%Pleroma.List{} = list, title) do
def update(%Pleroma.List{} = list, params) do
list
|> title_changeset(%{title: title})
|> update_changeset(params)
|> Repo.update()
end
def create(title, %User{} = creator) do
changeset = title_changeset(%Pleroma.List{user_id: creator.id}, %{title: title})
def create(params, %User{} = creator) do
changeset = update_changeset(%Pleroma.List{user_id: creator.id}, params)
if changeset.valid? do
Repo.transaction(fn ->
@ -149,4 +150,14 @@ defmodule Pleroma.List do
end
def member?(_, _), do: false
def get_exclusive_list_members(%User{id: user_id}) do
Pleroma.List
|> where([l], l.user_id == ^user_id)
|> where([l], l.exclusive == true)
|> select([l], l.following)
|> Repo.all()
|> List.flatten()
|> Enum.uniq()
end
end

View file

@ -36,7 +36,7 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
summary: "Create a list",
description: "Fetch the list with the given ID. Used for verifying the title of a list.",
operationId: "ListController.create",
requestBody: create_update_request(),
requestBody: create_request(),
security: [%{"oAuth" => ["write:lists"]}],
responses: %{
200 => Operation.response("List", "application/json", List),
@ -68,7 +68,7 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
description: "Change the title of a list",
operationId: "ListController.update",
parameters: [id_param()],
requestBody: create_update_request(),
requestBody: update_request(),
security: [%{"oAuth" => ["write:lists"]}],
responses: %{
200 => Operation.response("List", "application/json", List),
@ -164,14 +164,15 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
)
end
defp create_update_request do
defp create_request do
request_body(
"Parameters",
%Schema{
description: "POST body for creating or updating a List",
description: "POST body for creating a List",
type: :object,
properties: %{
title: %Schema{type: :string, description: "List title"}
title: %Schema{type: :string, description: "List title"},
exclusive: %Schema{type: :boolean, description: "Whether members of the list should be removed from the “Home” feed"}
},
required: [:title]
},
@ -179,6 +180,21 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
)
end
defp update_request do
request_body(
"Parameters",
%Schema{
description: "PUT body for updating a List",
type: :object,
properties: %{
title: %Schema{type: :string, description: "List title"},
exclusive: %Schema{type: :boolean, description: "Whether members of the list should be removed from the “Home” feed"}
}
},
required: true
)
end
defp add_remove_accounts_request(required) when is_boolean(required) do
request_body(
"Parameters",

View file

@ -13,7 +13,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.List do
type: :object,
properties: %{
id: %Schema{type: :string, description: "The internal database ID of the list"},
title: %Schema{type: :string, description: "The user-defined title of the list"}
title: %Schema{type: :string, description: "The user-defined title of the list"},
exclusive: %Schema{
type: :boolean,
description: "Whether members of the list should be removed from the “Home” feed"
}
},
example: %{
"id" => "12249",

View file

@ -28,27 +28,27 @@ defmodule Pleroma.Web.MastodonAPI.ListController do
# POST /api/v1/lists
def create(
%{assigns: %{user: user}, private: %{open_api_spex: %{body_params: %{title: title}}}} =
%{assigns: %{user: user}, private: %{open_api_spex: %{body_params: params}}} =
conn,
_
) do
with {:ok, %Pleroma.List{} = list} <- Pleroma.List.create(title, user) do
with {:ok, %Pleroma.List{} = list} <- Pleroma.List.create(params, user) do
render(conn, "show.json", list: list)
end
end
# GET /api/v1/lists/:idOB
# GET /api/v1/lists/:id
def show(%{assigns: %{list: list}} = conn, _) do
render(conn, "show.json", list: list)
end
# PUT /api/v1/lists/:id
def update(
%{assigns: %{list: list}, private: %{open_api_spex: %{body_params: %{title: title}}}} =
%{assigns: %{list: list}, private: %{open_api_spex: %{body_params: params}}} =
conn,
_
) do
with {:ok, list} <- Pleroma.List.rename(list, title) do
with {:ok, list} <- Pleroma.List.update(list, params) do
render(conn, "show.json", list: list)
end
end

View file

@ -45,6 +45,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> User.followed_hashtags()
|> Enum.map(& &1.id)
excluded_list_members =
user
|> Pleroma.List.get_exclusive_list_members()
params =
params
|> Map.put(:type, ["Create", "Announce"])
@ -58,7 +62,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.delete(:local)
activities =
[user.ap_id | User.following(user)]
[user.ap_id | User.following(user) -- excluded_list_members]
|> ActivityPub.fetch_activities(params)
|> Enum.reverse()

View file

@ -13,7 +13,8 @@ defmodule Pleroma.Web.MastodonAPI.ListView do
def render("show.json", %{list: list}) do
%{
id: to_string(list.id),
title: list.title
title: list.title,
exclusive: list.exclusive
}
end
end