common_api/utils: break up get_to_and_cc

To make it usable in scenarios without a draft.
The next commit adds a user for the new function.

This does technically change behaviour a bit, since
"private" relies to "direct" messages no longer implicitly
address the parent post’s actor, but this seems like a contrived
scenario and was likely never intended to actually occur anyway
as cocorroborated by the absence of tests for it.
This commit is contained in:
Oneric 2025-06-09 17:11:13 +02:00
parent 242e798054
commit 2cdc4acce9

View file

@ -56,48 +56,59 @@ def get_to_and_cc(%{in_reply_to_conversation: %Participation{} = participation})
{Enum.map(participation.recipients, & &1.ap_id), []}
end
def get_to_and_cc(%{visibility: visibility} = draft) when visibility in ["public", "local"] do
to =
case visibility do
"public" -> [Pleroma.Constants.as_public() | draft.mentions]
"local" -> [Utils.as_local_public() | draft.mentions]
def get_to_and_cc(%{visibility: visibility} = draft) do
# If the OP is a DM already, add the implicit actor
mentions =
if visibility == "direct" && draft.in_reply_to && Visibility.is_direct?(draft.in_reply_to) do
Enum.uniq([draft.in_reply_to.data["actor"] | draft.mentions])
else
draft.mentions
end
cc = [draft.user.follower_address]
if draft.in_reply_to do
{Enum.uniq([draft.in_reply_to.data["actor"] | to]), cc}
else
{to, cc}
end
get_to_and_cc_for_visibility(
visibility,
draft.user.follower_address,
draft.in_reply_to && draft.in_reply_to.data["actor"],
mentions
)
end
def get_to_and_cc(%{visibility: "unlisted"} = draft) do
to = [draft.user.follower_address | draft.mentions]
cc = [Pleroma.Constants.as_public()]
def get_to_and_cc_for_visibility(visibility, follower_collection, parent_actor, mentions)
when visibility in ["public", "local"] do
scope_addr =
case visibility do
"public" -> Pleroma.Constants.as_public()
"local" -> Utils.as_local_public()
end
if draft.in_reply_to do
{Enum.uniq([draft.in_reply_to.data["actor"] | to]), cc}
else
{to, cc}
end
to =
if parent_actor,
do: Enum.uniq([parent_actor, scope_addr | mentions]),
else: [scope_addr | mentions]
{to, [follower_collection]}
end
def get_to_and_cc(%{visibility: "private"} = draft) do
{to, cc} = get_to_and_cc(struct(draft, visibility: "direct"))
{[draft.user.follower_address | to], cc}
def get_to_and_cc_for_visibility("unlisted", follower_collection, parent_actor, mentions) do
to =
if parent_actor,
do: Enum.uniq([parent_actor, follower_collection | mentions]),
else: [follower_collection | mentions]
{to, [Pleroma.Constants.as_public()]}
end
def get_to_and_cc(%{visibility: "direct"} = draft) do
# If the OP is a DM already, add the implicit actor.
if draft.in_reply_to && Visibility.is_direct?(draft.in_reply_to) do
{Enum.uniq([draft.in_reply_to.data["actor"] | draft.mentions]), []}
else
{draft.mentions, []}
end
def get_to_and_cc_for_visibility("private", follower_collection, _, mentions) do
{[follower_collection | mentions], []}
end
def get_to_and_cc(%{visibility: {:list, _}, mentions: mentions}), do: {mentions, []}
def get_to_and_cc_for_visibility("direct", _, _, mentions) do
{mentions, []}
end
def get_to_and_cc_for_visibility({:list, _}, _, _, mentions) do
{mentions, []}
end
def get_addressed_users(_, to) when is_list(to) do
User.get_ap_ids_by_nicknames(to)