Introduce the group activity section

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2021-02-24 19:06:48 +01:00
parent d0567f783d
commit 3fe64a4389
70 changed files with 3224 additions and 70 deletions

View File

@@ -66,6 +66,7 @@ defmodule Mobilizon.Actors do
Gets a single actor.
"""
@spec get_actor(integer | String.t()) :: Actor.t() | nil
def get_actor(nil), do: nil
def get_actor(id), do: Repo.get(Actor, id)
@doc """
@@ -860,7 +861,7 @@ defmodule Mobilizon.Actors do
end
@doc """
Returns the list of members for a group.
Returns a paginated list of members for a group.
"""
@spec list_members_for_group(Actor.t(), list(atom()), integer | nil, integer | nil) :: Page.t()
def list_members_for_group(
@@ -882,6 +883,13 @@ defmodule Mobilizon.Actors do
|> Repo.all()
end
@spec list_internal_actors_members_for_group(Actor.t(), list()) :: list(Actor.t())
def list_internal_actors_members_for_group(%Actor{id: group_id, type: :Group}, roles \\ []) do
group_id
|> group_internal_member_actor_query(roles)
|> Repo.all()
end
@doc """
Returns a paginated list of administrator members for a group.
"""
@@ -1512,6 +1520,16 @@ defmodule Mobilizon.Actors do
|> select([m, _a], m)
end
@spec group_internal_member_actor_query(integer(), list()) :: Ecto.Query.t()
defp group_internal_member_actor_query(group_id, role) do
Member
|> where([m], m.parent_id == ^group_id)
|> filter_member_role(role)
|> join(:inner, [m], a in Actor, on: m.actor_id == a.id)
|> where([_m, a], is_nil(a.domain))
|> select([_m, a], a)
end
@spec group_internal_member_query(integer()) :: Ecto.Query.t()
defp group_internal_member_query(group_id) do
Member
@@ -1523,13 +1541,13 @@ defmodule Mobilizon.Actors do
end
@spec filter_member_role(Ecto.Query.t(), list(atom()) | atom()) :: Ecto.Query.t()
def filter_member_role(query, []), do: query
defp filter_member_role(query, []), do: query
def filter_member_role(query, roles) when is_list(roles) do
defp filter_member_role(query, roles) when is_list(roles) do
where(query, [m], m.role in ^roles)
end
def filter_member_role(query, role) when is_atom(role) do
defp filter_member_role(query, role) when is_atom(role) do
from(m in query, where: m.role == ^role)
end

View File

@@ -25,6 +25,7 @@ defmodule Mobilizon.Actors.Member do
schema "members" do
field(:role, MemberRole, default: :member)
field(:url, :string)
field(:member_since, :utc_datetime)
embeds_one :metadata, Metadata, on_replace: :delete do
# TODO : Use this space to put notes when someone is invited / requested to join
@@ -64,6 +65,7 @@ defmodule Mobilizon.Actors.Member do
|> cast(attrs, @attrs)
|> cast_embed(:metadata, with: &metadata_changeset/2)
|> ensure_url()
|> update_member_since()
|> validate_required(@required_attrs)
# On both parent_id and actor_id
|> unique_constraint(:parent_id, name: :members_actor_parent_unique_index)
@@ -98,4 +100,29 @@ defmodule Mobilizon.Actors.Member do
|> put_change(:id, uuid)
|> put_change(:url, "#{Endpoint.url()}/member/#{uuid}")
end
@spec update_member_since(Ecto.Changeset.t()) :: Ecto.Changeset.t()
defp update_member_since(%Ecto.Changeset{data: data} = changeset) do
new_role = get_change(changeset, :role)
cond do
new_role in [
:member,
:moderator,
:administrator,
:creator
] ->
put_change(
changeset,
:member_since,
DateTime.truncate(data.member_since || DateTime.utc_now(), :second)
)
new_role in [:invited, :not_approved, :rejected] ->
put_change(changeset, :member_since, nil)
true ->
changeset
end
end
end