Introduce the group activity section
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
85
lib/graphql/resolvers/activity.ex
Normal file
85
lib/graphql/resolvers/activity.ex
Normal 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
|
||||
@@ -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)
|
||||
|
||||
78
lib/graphql/schema/activity.ex
Normal file
78
lib/graphql/schema/activity.ex
Normal 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
|
||||
@@ -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 """
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user