defmodule Mobilizon.Service.Activity.Group do @moduledoc """ Insert a group setting activity """ alias Mobilizon.Actors alias Mobilizon.Actors.Actor alias Mobilizon.Service.Activity alias Mobilizon.Service.Workers.ActivityBuilder @behaviour Activity @impl Activity @spec insert_activity(Actor.t(), Keyword.t()) :: {:ok, Job.t()} | {:ok, nil} | {:error, Ecto.Changeset.t()} def insert_activity(group, options \\ []) def insert_activity( %Actor{type: :Group, id: group_id}, options ) do subject = Keyword.get(options, :subject) actor_id = Keyword.get(options, :actor_id) default_updater_actor = Actors.get_actor(actor_id) %Actor{id: actor_id} = Keyword.get(options, :updater_actor, default_updater_actor) old_group = Keyword.get(options, :old_group) case Actors.get_actor(group_id) do %Actor{type: :Group} = group -> ActivityBuilder.enqueue(:build_activity, %{ "type" => "group", "subject" => subject, "subject_params" => subject_params(group, subject, old_group), "group_id" => group.id, "author_id" => actor_id, "object_type" => "group", "object_id" => to_string(group.id), "inserted_at" => DateTime.utc_now() }) nil -> {:ok, nil} end end def insert_activity(_, _), do: {:ok, nil} @impl Activity def get_object(group_id) do Actors.get_actor(group_id) end @spec subject_params(Actor.t(), String.t() | nil, Actor.t() | nil) :: map() defp subject_params(%Actor{} = group, "group_updated", %Actor{} = old_group) do group |> subject_params(nil, nil) |> maybe_put_old_name_if_updated(old_group.name, group.name) |> maybe_put_summary_change_if_updated(old_group.summary, group.summary) |> maybe_put_old_visibility_if_updated(old_group.visibility, group.visibility) |> maybe_put_old_openness_if_updated(old_group.openness, group.openness) |> maybe_put_address_change_if_updated( old_group.physical_address_id, group.physical_address_id ) |> maybe_put_avatar_change_if_updated( old_group.avatar, group.avatar ) |> maybe_put_banner_change_if_updated( old_group.banner, group.banner ) |> maybe_put_manually_approves_followers_change_if_updated( old_group.manually_approves_followers, group.manually_approves_followers ) end defp subject_params( %Actor{preferred_username: preferred_username, domain: domain, name: name} = actor, _, _ ) do %{ group_preferred_username: preferred_username, group_name: name, group_domain: domain, group_federated_username: Actor.preferred_username_and_domain(actor), group_changes: [] } end @spec maybe_put_old_name_if_updated(map(), String.t(), String.t()) :: map() defp maybe_put_old_name_if_updated(params, old_group_name, new_group_name) when old_group_name != new_group_name do params |> Map.update(:group_changes, [], fn changes -> changes ++ [:name] end) |> Map.put(:old_group_name, old_group_name) end defp maybe_put_old_name_if_updated(params, _, _), do: params defp maybe_put_summary_change_if_updated(params, old_summary, new_summary) when old_summary != new_summary do Map.update(params, :group_changes, [], fn changes -> changes ++ [:summary] end) end defp maybe_put_summary_change_if_updated(params, _, _), do: params defp maybe_put_old_visibility_if_updated(params, old_group_visibility, new_group_visibility) when old_group_visibility != new_group_visibility do params |> Map.update(:group_changes, [], fn changes -> changes ++ [:visibility] end) |> Map.put(:old_group_visibility, old_group_visibility) end defp maybe_put_old_visibility_if_updated(params, _, _), do: params defp maybe_put_old_openness_if_updated(params, old_group_openness, new_group_openness) when old_group_openness != new_group_openness do params |> Map.update(:group_changes, [], fn changes -> changes ++ [:openness] end) |> Map.put(:old_group_openness, old_group_openness) end defp maybe_put_old_openness_if_updated(params, _, _), do: params defp maybe_put_address_change_if_updated(params, old_address_id, new_address_id) when old_address_id != new_address_id do Map.update(params, :group_changes, [], fn changes -> changes ++ [:address] end) end defp maybe_put_address_change_if_updated(params, _, _), do: params defp maybe_put_avatar_change_if_updated(params, old_avatar, new_avatar) when old_avatar != new_avatar do Map.update(params, :group_changes, [], fn changes -> changes ++ [:avatar] end) end defp maybe_put_avatar_change_if_updated(params, _, _), do: params defp maybe_put_banner_change_if_updated(params, old_banner, new_banner) when old_banner != new_banner do Map.update(params, :group_changes, [], fn changes -> changes ++ [:banner] end) end defp maybe_put_banner_change_if_updated(params, _, _), do: params defp maybe_put_manually_approves_followers_change_if_updated( params, old_group_manually_approves_followers, new_group_manually_approves_followers ) when old_group_manually_approves_followers != new_group_manually_approves_followers do params |> Map.update(:group_changes, [], fn changes -> changes ++ [:manually_approves_followers] end) |> Map.put(:old_group_manually_approves_followers, old_group_manually_approves_followers) end defp maybe_put_manually_approves_followers_change_if_updated(params, _, _), do: params end