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

@@ -0,0 +1,85 @@
defmodule Mobilizon.GraphQL.Resolvers.Activity do
@moduledoc """
Handles the activity-related GraphQL calls.
"""
import Mobilizon.Users.Guards
alias Mobilizon.{Activities, Actors, Discussions, Events, Posts, Resources, Users}
alias Mobilizon.Activities.Activity
alias Mobilizon.Actors.Actor
alias Mobilizon.Events.Event
alias Mobilizon.Storage.Page
alias Mobilizon.Users.User
require Logger
def group_activity(%Actor{type: :Group, id: group_id}, %{page: page, limit: limit}, %{
context: %{current_user: %User{role: role} = user}
}) do
with {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id) or is_moderator(role)} do
%Page{total: total, elements: elements} =
Activities.list_activities_for_group(group_id, actor_id, [], page, limit)
elements =
Enum.map(elements, fn %Activity{} = activity ->
activity
|> Map.update(:subject_params, %{}, &transform_params/1)
|> Map.put(:object, get_object(activity))
end)
{:ok, %Page{total: total, elements: elements}}
else
{:member, false} ->
{:error, :unauthorized}
end
end
def group_activity(_, _, _) do
{:error, :unauthenticated}
end
defp get_object(%Activity{object_type: object_type, object_id: object_id}) do
get_object(object_type, object_id)
end
defp get_object(_, nil), do: nil
defp get_object(:event, event_id) do
case Events.get_event(event_id) do
{:ok, %Event{} = event} -> event
_ -> nil
end
end
defp get_object(:post, post_id) do
Posts.get_post(post_id)
end
defp get_object(:member, member_id) do
Actors.get_member(member_id)
end
defp get_object(:resource, resource_id) do
Resources.get_resource(resource_id)
end
defp get_object(:discussion, discussion_id) do
Discussions.get_discussion(discussion_id)
end
defp get_object(:group, group_id) do
Actors.get_actor(group_id)
end
@spec transform_params(map()) :: list()
defp transform_params(params) do
Enum.map(params, fn {key, value} -> %{key: key, value: transform_value(value)} end)
end
defp transform_value(value) when is_list(value) do
Enum.join(value, ",")
end
defp transform_value(value), do: value
end

View File

@@ -29,6 +29,7 @@ defmodule Mobilizon.GraphQL.Schema do
import_types(Schema.Custom.UUID)
import_types(Schema.Custom.Point)
import_types(Schema.ActivityType)
import_types(Schema.UserType)
import_types(Schema.MediaType)
import_types(Schema.ActorInterface)

View File

@@ -0,0 +1,78 @@
defmodule Mobilizon.GraphQL.Schema.ActivityType do
@moduledoc """
Schema representation for Activity
"""
use Absinthe.Schema.Notation
alias Mobilizon.Actors.{Actor, Member}
alias Mobilizon.Discussions.Discussion
alias Mobilizon.Events.Event
alias Mobilizon.Posts.Post
alias Mobilizon.Resources.Resource
enum :activity_type do
value(:event, description: "Activities concerning events")
value(:post, description: "Activities concerning posts")
value(:discussion, description: "Activities concerning discussions")
value(:resource, description: "Activities concerning resources")
value(:group, description: "Activities concerning group settings")
value(:member, description: "Activities concerning members")
end
object :activity_param_item do
field(:key, :string)
field(:value, :string)
end
interface :activity_object do
field(:id, :id)
resolve_type(fn
%Event{}, _ ->
:event
%Post{}, _ ->
:post
%Actor{type: "Group"}, _ ->
:group
%Member{}, _ ->
:member
%Resource{}, _ ->
:resource
%Discussion{}, _ ->
:discussion
%Actor{type: :Group}, _ ->
:group
_, _ ->
nil
end)
end
@desc """
A paginated list of activity items
"""
object :paginated_activity_list do
field(:elements, list_of(:activity), description: "A list of activities")
field(:total, :integer, description: "The total number of elements in the list")
end
object :activity do
field(:id, :id, description: "The activity item ID")
field(:inserted_at, :datetime, description: "When was the activity inserted")
field(:priority, :integer)
field(:type, :activity_type)
field(:subject, :string)
field(:subject_params, list_of(:activity_param_item))
field(:message, :string)
field(:message_params, list_of(:activity_param_item))
field(:object, :activity_object)
field(:author, :actor)
field(:group, :group)
end
end

View File

@@ -10,6 +10,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
alias Mobilizon.Addresses
alias Mobilizon.GraphQL.Resolvers.{
Activity,
Discussion,
Followers,
Group,
@@ -28,7 +29,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
Represents a group of actors
"""
object :group do
interfaces([:actor, :interactable])
interfaces([:actor, :interactable, :activity_object])
field(:id, :id, description: "Internal ID for this group")
field(:url, :string, description: "The ActivityPub actor's URL")
@@ -142,6 +143,19 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
resolve(&Followers.find_followers_for_group/3)
description("A paginated list of the followers this group has")
end
field :activity, :paginated_activity_list do
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated activity items list"
)
arg(:limit, :integer, default_value: 10, description: "The limit of activity items per page")
arg(:type, :activity_type, description: "Filter by type of activity")
resolve(&Activity.group_activity/3)
description("The group activity")
end
end
@desc """

View File

@@ -10,6 +10,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.MemberType do
Represents a member of a group
"""
object :member do
interfaces([:activity_object])
field(:id, :id, description: "The member's ID")
field(:parent, :group, description: "Of which the profile is member")
field(:actor, :person, description: "Which profile is member of")

View File

@@ -11,6 +11,7 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.DiscussionType do
@desc "A discussion"
object :discussion do
interfaces([:activity_object])
field(:id, :id, description: "Internal ID for this discussion")
field(:title, :string, description: "The title for this discussion")
field(:slug, :string, description: "The slug for the discussion")

View File

@@ -17,7 +17,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
@desc "An event"
object :event do
interfaces([:action_log_object, :interactable])
interfaces([:action_log_object, :interactable, :activity_object])
field(:id, :id, description: "Internal ID for this event")
field(:uuid, :uuid, description: "The Event UUID")
field(:url, :string, description: "The ActivityPub Event URL")

View File

@@ -7,6 +7,7 @@ defmodule Mobilizon.GraphQL.Schema.PostType do
@desc "A post"
object :post do
interfaces([:activity_object])
field(:id, :id, description: "The post's ID")
field(:title, :string, description: "The post's title")
field(:slug, :string, description: "The post's slug")

View File

@@ -9,6 +9,7 @@ defmodule Mobilizon.GraphQL.Schema.ResourceType do
@desc "A resource"
object :resource do
interfaces([:activity_object])
field(:id, :id, description: "The resource's ID")
field(:title, :string, description: "The resource's title")
field(:summary, :string, description: "The resource's summary")