@@ -3,8 +3,8 @@ defmodule Mobilizon.GraphQL.API.Comments do
|
||||
API for Comments.
|
||||
"""
|
||||
|
||||
alias Mobilizon.Conversations.Comment
|
||||
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Activity
|
||||
|
||||
@@ -19,7 +19,7 @@ defmodule Mobilizon.GraphQL.API.Comments do
|
||||
end
|
||||
|
||||
def update_comment(%Comment{} = comment, args) do
|
||||
ActivityPub.update(:comment, comment, args, true)
|
||||
ActivityPub.update(comment, args, true)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@@ -27,8 +27,8 @@ defmodule Mobilizon.GraphQL.API.Comments do
|
||||
|
||||
Deletes a comment from an actor
|
||||
"""
|
||||
@spec delete_comment(Comment.t()) :: {:ok, Activity.t(), Comment.t()} | any
|
||||
def delete_comment(%Comment{} = comment) do
|
||||
ActivityPub.delete(comment, true)
|
||||
@spec delete_comment(Comment.t(), Actor.t()) :: {:ok, Activity.t(), Comment.t()} | any
|
||||
def delete_comment(%Comment{} = comment, %Actor{} = actor) do
|
||||
ActivityPub.delete(comment, actor, true)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -34,7 +34,7 @@ defmodule Mobilizon.GraphQL.API.Events do
|
||||
Map.update(args, :picture, nil, fn picture ->
|
||||
process_picture(picture, organizer_actor)
|
||||
end) do
|
||||
ActivityPub.update(:event, event, args, Map.get(args, :draft, false) == false)
|
||||
ActivityPub.update(event, args, Map.get(args, :draft, false) == false)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,8 +43,8 @@ defmodule Mobilizon.GraphQL.API.Events do
|
||||
|
||||
If the event is deleted by
|
||||
"""
|
||||
def delete_event(%Event{} = event, federate \\ true) do
|
||||
ActivityPub.delete(event, federate)
|
||||
def delete_event(%Event{} = event, %Actor{} = actor, federate \\ true) do
|
||||
ActivityPub.delete(event, actor, federate)
|
||||
end
|
||||
|
||||
defp process_picture(nil, _), do: nil
|
||||
|
||||
@@ -19,8 +19,25 @@ defmodule Mobilizon.GraphQL.API.Groups do
|
||||
args |> Map.get(:preferred_username) |> HTML.strip_tags() |> String.trim(),
|
||||
{:existing_group, nil} <-
|
||||
{:existing_group, Actors.get_local_group_by_title(preferred_username)},
|
||||
args <- args |> Map.put(:type, :Group),
|
||||
{:ok, %Activity{} = activity, %Actor{} = group} <-
|
||||
ActivityPub.create(:group, args, true, %{"actor" => args.creator_actor.url}) do
|
||||
ActivityPub.create(:actor, args, true, %{"actor" => args.creator_actor.url}) do
|
||||
{:ok, activity, group}
|
||||
else
|
||||
{:existing_group, _} ->
|
||||
{:error, "A group with this name already exists"}
|
||||
|
||||
{:is_owned, nil} ->
|
||||
{:error, "Actor id is not owned by authenticated user"}
|
||||
end
|
||||
end
|
||||
|
||||
@spec create_group(map) :: {:ok, Activity.t(), Actor.t()} | any
|
||||
def update_group(%{id: id} = args) do
|
||||
with {:existing_group, {:ok, %Actor{type: :Group} = group}} <-
|
||||
{:existing_group, Actors.get_group_by_actor_id(id)},
|
||||
{:ok, %Activity{} = activity, %Actor{} = group} <-
|
||||
ActivityPub.update(group, args, true, %{"actor" => args.updater_actor.url}) do
|
||||
{:ok, activity, group}
|
||||
else
|
||||
{:existing_group, _} ->
|
||||
|
||||
@@ -9,7 +9,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Admin.{ActionLog, Setting}
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Conversations.Comment
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
@@ -297,7 +297,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
|
||||
with {:changes, true} <- {:changes, args != %{}},
|
||||
%Actor{} = instance_actor <- Relay.get_actor(),
|
||||
{:ok, _activity, _actor} <- ActivityPub.update(:actor, instance_actor, args, true) do
|
||||
{:ok, _activity, _actor} <- ActivityPub.update(instance_actor, args, true) do
|
||||
:ok
|
||||
else
|
||||
{:changes, false} ->
|
||||
|
||||
@@ -3,9 +3,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
Handles the comment-related GraphQL calls.
|
||||
"""
|
||||
|
||||
alias Mobilizon.{Actors, Admin, Conversations}
|
||||
alias Mobilizon.{Actors, Admin, Discussions}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Conversations.Comment, as: CommentModel
|
||||
alias Mobilizon.Discussions.Comment, as: CommentModel
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
@@ -14,7 +14,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
require Logger
|
||||
|
||||
def get_thread(_parent, %{id: thread_id}, _context) do
|
||||
{:ok, Conversations.get_thread_replies(thread_id)}
|
||||
{:ok, Discussions.get_thread_replies(thread_id)}
|
||||
end
|
||||
|
||||
def create_comment(
|
||||
@@ -51,7 +51,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
) do
|
||||
with {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
%CommentModel{actor_id: comment_actor_id} = comment <-
|
||||
Mobilizon.Conversations.get_comment(comment_id),
|
||||
Mobilizon.Discussions.get_comment(comment_id),
|
||||
true <- actor_id === comment_actor_id,
|
||||
{:ok, _, %CommentModel{} = comment} <- Comments.update_comment(comment, %{text: text}) do
|
||||
{:ok, comment}
|
||||
@@ -72,15 +72,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
}
|
||||
) do
|
||||
with {actor_id, ""} <- Integer.parse(actor_id),
|
||||
{:is_owned, %Actor{} = _organizer_actor} <- User.owns_actor(user, actor_id),
|
||||
{:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
|
||||
%CommentModel{deleted_at: nil} = comment <-
|
||||
Conversations.get_comment_with_preload(comment_id) do
|
||||
Discussions.get_comment_with_preload(comment_id) do
|
||||
cond do
|
||||
{:comment_can_be_managed, true} == CommentModel.can_be_managed_by(comment, actor_id) ->
|
||||
do_delete_comment(comment)
|
||||
do_delete_comment(comment, actor)
|
||||
|
||||
role in [:moderator, :administrator] ->
|
||||
with {:ok, res} <- do_delete_comment(comment),
|
||||
with {:ok, res} <- do_delete_comment(comment, actor),
|
||||
%Actor{} = actor <- Actors.get_actor(actor_id) do
|
||||
Admin.log_action(actor, "delete", comment)
|
||||
|
||||
@@ -103,9 +103,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
{:error, "You are not allowed to delete a comment if not connected"}
|
||||
end
|
||||
|
||||
defp do_delete_comment(%CommentModel{} = comment) do
|
||||
defp do_delete_comment(%CommentModel{} = comment, %Actor{} = actor) do
|
||||
with {:ok, _, %CommentModel{} = comment} <-
|
||||
Comments.delete_comment(comment) do
|
||||
Comments.delete_comment(comment, actor) do
|
||||
{:ok, comment}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
defmodule Mobilizon.GraphQL.Resolvers.Conversation do
|
||||
@moduledoc """
|
||||
Handles the group-related GraphQL calls.
|
||||
"""
|
||||
|
||||
alias Mobilizon.{Actors, Conversations, Users}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Conversations.Conversation, as: ConversationModel
|
||||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
def find_conversations_for_actor(
|
||||
%Actor{id: group_id},
|
||||
_args,
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = 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)} do
|
||||
{:ok, Conversations.find_conversations_for_actor(group_id)}
|
||||
else
|
||||
{:member, false} ->
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
end
|
||||
|
||||
def find_conversations_for_actor(%Actor{}, _args, _resolution) do
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
def get_conversation(_parent, %{id: id}, _resolution) do
|
||||
{:ok, Conversations.get_conversation(id)}
|
||||
end
|
||||
|
||||
def get_comments_for_conversation(
|
||||
%ConversationModel{id: conversation_id},
|
||||
%{page: page, limit: limit},
|
||||
_resolution
|
||||
) do
|
||||
{:ok, Conversations.get_comments_for_conversation(conversation_id, page, limit)}
|
||||
end
|
||||
|
||||
def create_conversation(
|
||||
_parent,
|
||||
%{title: title, text: text, actor_id: actor_id, creator_id: creator_id},
|
||||
_resolution
|
||||
) do
|
||||
with {:ok, %ConversationModel{} = conversation} <-
|
||||
Conversations.create_conversation(%{
|
||||
title: title,
|
||||
text: text,
|
||||
actor_id: actor_id,
|
||||
creator_id: creator_id
|
||||
}) do
|
||||
{:ok, conversation}
|
||||
end
|
||||
end
|
||||
|
||||
def reply_to_conversation(
|
||||
_parent,
|
||||
%{text: text, conversation_id: conversation_id},
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
{:no_conversation, %ConversationModel{} = conversation} <-
|
||||
{:no_conversation, Conversations.get_conversation(conversation_id)},
|
||||
{:ok, %ConversationModel{} = conversation} <-
|
||||
Conversations.reply_to_conversation(
|
||||
conversation,
|
||||
%{
|
||||
text: text,
|
||||
actor_id: actor_id
|
||||
}
|
||||
) do
|
||||
{:ok, conversation}
|
||||
end
|
||||
end
|
||||
|
||||
@spec update_conversation(map(), map(), map()) :: {:ok, ConversationModel.t()}
|
||||
def update_conversation(
|
||||
_parent,
|
||||
%{title: title, conversation_id: conversation_id},
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
{:no_conversation, %ConversationModel{creator_id: creator_id} = conversation} <-
|
||||
{:no_conversation, Conversations.get_conversation(conversation_id)},
|
||||
{:check_access, true} <- {:check_access, actor_id == creator_id},
|
||||
{:ok, %ConversationModel{} = conversation} <-
|
||||
Conversations.update_conversation(
|
||||
conversation,
|
||||
%{
|
||||
title: title
|
||||
}
|
||||
) do
|
||||
{:ok, conversation}
|
||||
end
|
||||
end
|
||||
end
|
||||
179
lib/graphql/resolvers/discussion.ex
Normal file
179
lib/graphql/resolvers/discussion.ex
Normal file
@@ -0,0 +1,179 @@
|
||||
defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
@moduledoc """
|
||||
Handles the group-related GraphQL calls.
|
||||
"""
|
||||
|
||||
alias Mobilizon.{Actors, Discussions, Users}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
def find_discussions_for_actor(
|
||||
%Actor{id: group_id},
|
||||
_args,
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = 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)} do
|
||||
{:ok, Discussions.find_discussions_for_actor(group_id)}
|
||||
else
|
||||
{:member, false} ->
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
end
|
||||
|
||||
def find_discussions_for_actor(%Actor{}, _args, _resolution) do
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
def get_discussion(_parent, %{id: id}, %{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}) do
|
||||
with {:actor, %Actor{id: creator_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
%Discussion{actor_id: actor_id} = discussion <-
|
||||
Discussions.get_discussion(id),
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)} do
|
||||
{:ok, discussion}
|
||||
end
|
||||
end
|
||||
|
||||
def get_discussion(_parent, %{slug: slug}, %{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}) do
|
||||
with {:actor, %Actor{id: creator_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
%Discussion{actor_id: actor_id} = discussion <-
|
||||
Discussions.get_discussion_by_slug(slug),
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)} do
|
||||
{:ok, discussion}
|
||||
else
|
||||
nil -> {:error, "No such discussion"}
|
||||
end
|
||||
end
|
||||
|
||||
def get_discussion(_parent, _args, _resolution),
|
||||
do: {:error, "You need to be logged-in to access discussions"}
|
||||
|
||||
def get_comments_for_discussion(
|
||||
%Discussion{id: discussion_id},
|
||||
%{page: page, limit: limit},
|
||||
_resolution
|
||||
) do
|
||||
{:ok, Discussions.get_comments_for_discussion(discussion_id, page, limit)}
|
||||
end
|
||||
|
||||
def create_discussion(
|
||||
_parent,
|
||||
%{title: title, text: text, actor_id: actor_id},
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:actor, %Actor{id: creator_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
ActivityPub.create(
|
||||
:discussion,
|
||||
%{
|
||||
title: title,
|
||||
text: text,
|
||||
actor_id: actor_id,
|
||||
creator_id: creator_id,
|
||||
attributed_to_id: actor_id
|
||||
},
|
||||
true
|
||||
) do
|
||||
{:ok, discussion}
|
||||
end
|
||||
end
|
||||
|
||||
def reply_to_discussion(
|
||||
_parent,
|
||||
%{text: text, discussion_id: discussion_id},
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:actor, %Actor{id: creator_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
{:no_discussion,
|
||||
%Discussion{
|
||||
actor_id: actor_id,
|
||||
last_comment: %Comment{
|
||||
id: last_comment_id,
|
||||
origin_comment_id: origin_comment_id,
|
||||
in_reply_to_comment_id: previous_in_reply_to_comment_id
|
||||
}
|
||||
} = _discussion} <-
|
||||
{:no_discussion, Discussions.get_discussion(discussion_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
ActivityPub.create(
|
||||
:discussion,
|
||||
%{
|
||||
text: text,
|
||||
discussion_id: discussion_id,
|
||||
actor_id: creator_id,
|
||||
attributed_to_id: actor_id,
|
||||
in_reply_to_comment_id: last_comment_id,
|
||||
origin_comment_id:
|
||||
origin_comment_id || previous_in_reply_to_comment_id || last_comment_id
|
||||
},
|
||||
true
|
||||
) do
|
||||
{:ok, discussion}
|
||||
end
|
||||
end
|
||||
|
||||
@spec update_discussion(map(), map(), map()) :: {:ok, Discussion.t()}
|
||||
def update_discussion(
|
||||
_parent,
|
||||
%{title: title, discussion_id: discussion_id},
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:actor, %Actor{id: creator_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
{:no_discussion, %Discussion{actor_id: actor_id} = discussion} <-
|
||||
{:no_discussion, Discussions.get_discussion(discussion_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
ActivityPub.update(
|
||||
discussion,
|
||||
%{
|
||||
title: title
|
||||
}
|
||||
) do
|
||||
{:ok, discussion}
|
||||
end
|
||||
end
|
||||
|
||||
def delete_discussion(_parent, %{discussion_id: discussion_id}, %{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}) do
|
||||
with {:actor, %Actor{id: creator_id} = actor} <- {:actor, Users.get_actor_for_user(user)},
|
||||
{:no_discussion, %Discussion{actor_id: actor_id} = discussion} <-
|
||||
{:no_discussion, Discussions.get_discussion(discussion_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
ActivityPub.delete(discussion, actor) do
|
||||
{:ok, discussion}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -255,13 +255,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
) do
|
||||
with {:ok, %Event{local: is_local} = event} <- Events.get_event_with_preload(event_id),
|
||||
{actor_id, ""} <- Integer.parse(actor_id),
|
||||
{:is_owned, %Actor{}} <- User.owns_actor(user, actor_id) do
|
||||
{:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id) do
|
||||
cond do
|
||||
{:event_can_be_managed, true} == Event.can_be_managed_by(event, actor_id) ->
|
||||
do_delete_event(event)
|
||||
do_delete_event(event, actor)
|
||||
|
||||
role in [:moderator, :administrator] ->
|
||||
with {:ok, res} <- do_delete_event(event, !is_local),
|
||||
with {:ok, res} <- do_delete_event(event, actor, !is_local),
|
||||
%Actor{} = actor <- Actors.get_actor(actor_id) do
|
||||
Admin.log_action(actor, "delete", event)
|
||||
|
||||
@@ -284,8 +284,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
{:error, "You need to be logged-in to delete an event"}
|
||||
end
|
||||
|
||||
defp do_delete_event(event, federate \\ true) when is_boolean(federate) do
|
||||
with {:ok, _activity, event} <- API.Events.delete_event(event) do
|
||||
defp do_delete_event(%Event{} = event, %Actor{} = actor, federate \\ true)
|
||||
when is_boolean(federate) do
|
||||
with {:ok, _activity, event} <- API.Events.delete_event(event, actor) do
|
||||
{:ok, %{id: event.id}}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -80,7 +80,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
API.Groups.create_group(args) do
|
||||
{:ok, group}
|
||||
else
|
||||
{:error, err} when is_bitstring(err) ->
|
||||
{:error, err} when is_binary(err) ->
|
||||
{:error, err}
|
||||
|
||||
{:is_owned, nil} ->
|
||||
@@ -92,6 +92,36 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
{:error, "You need to be logged-in to create a group"}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Create a new group. The creator is automatically added as admin
|
||||
"""
|
||||
def update_group(
|
||||
_parent,
|
||||
args,
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
}
|
||||
) do
|
||||
with %Actor{} = updater_actor <- Users.get_actor_for_user(user),
|
||||
args <- Map.put(args, :updater_actor, updater_actor),
|
||||
{:ok, _activity, %Actor{type: :Group} = group} <-
|
||||
API.Groups.update_group(args) do
|
||||
{:ok, group}
|
||||
else
|
||||
{:error, err} when is_binary(err) ->
|
||||
{:error, err}
|
||||
|
||||
{:is_owned, nil} ->
|
||||
{:error, "Creator actor id is not owned by the current user"}
|
||||
end
|
||||
end
|
||||
|
||||
def update_group(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in to update a group"}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Delete an existing group
|
||||
"""
|
||||
|
||||
@@ -16,14 +16,26 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
"""
|
||||
def find_members_for_group(
|
||||
%Actor{id: group_id} = group,
|
||||
_args,
|
||||
%{page: page, limit: limit, roles: roles},
|
||||
%{
|
||||
context: %{current_user: %User{} = user}
|
||||
} = _resolution
|
||||
) do
|
||||
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
%Page{} = page <- Actors.list_members_for_group(group) do
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do
|
||||
roles =
|
||||
case roles do
|
||||
"" ->
|
||||
[]
|
||||
|
||||
roles ->
|
||||
roles
|
||||
|> String.split(",")
|
||||
|> Enum.map(&String.downcase/1)
|
||||
|> Enum.map(&String.to_existing_atom/1)
|
||||
end
|
||||
|
||||
%Page{} = page = Actors.list_members_for_group(group, roles, page, limit)
|
||||
{:ok, page}
|
||||
else
|
||||
{:member, false} ->
|
||||
|
||||
@@ -129,7 +129,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
{:find_actor, Actors.get_actor(id)},
|
||||
{:is_owned, %Actor{}} <- User.owns_actor(user, actor.id),
|
||||
args <- save_attached_pictures(args),
|
||||
{:ok, _activity, %Actor{} = actor} <- ActivityPub.update(:actor, actor, args, true) do
|
||||
{:ok, _activity, %Actor{} = actor} <- ActivityPub.update(actor, args, true) do
|
||||
{:ok, actor}
|
||||
else
|
||||
{:find_actor, nil} ->
|
||||
|
||||
198
lib/graphql/resolvers/post.ex
Normal file
198
lib/graphql/resolvers/post.ex
Normal file
@@ -0,0 +1,198 @@
|
||||
defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
@moduledoc """
|
||||
Handles the posts-related GraphQL calls
|
||||
"""
|
||||
|
||||
alias Mobilizon.{Actors, Posts, Users}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
require Logger
|
||||
|
||||
@public_accessible_visibilities [:public, :unlisted]
|
||||
|
||||
@doc """
|
||||
Find posts for group.
|
||||
|
||||
Returns only if actor requesting is a member of the group
|
||||
"""
|
||||
def find_posts_for_group(
|
||||
%Actor{id: group_id} = group,
|
||||
%{page: page, limit: limit} = args,
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
%Page{} = page <- Posts.get_posts_for_group(group, page, limit) do
|
||||
{:ok, page}
|
||||
else
|
||||
{:member, _} ->
|
||||
find_posts_for_group(group, args, nil)
|
||||
end
|
||||
end
|
||||
|
||||
def find_posts_for_group(
|
||||
%Actor{} = group,
|
||||
%{page: page, limit: limit},
|
||||
_resolution
|
||||
) do
|
||||
with %Page{} = page <- Posts.get_public_posts_for_group(group, page, limit) do
|
||||
{:ok, page}
|
||||
end
|
||||
end
|
||||
|
||||
def find_posts_for_group(
|
||||
_group,
|
||||
_args,
|
||||
_resolution
|
||||
) do
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
def get_post(
|
||||
parent,
|
||||
%{slug: slug},
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:current_actor, %Actor{id: actor_id}} <-
|
||||
{:current_actor, Users.get_actor_for_user(user)},
|
||||
{:post, %Post{attributed_to: %Actor{id: group_id}} = post} <-
|
||||
{:post, Posts.get_post_by_slug_with_preloads(slug)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do
|
||||
{:ok, post}
|
||||
else
|
||||
{:member, false} -> get_post(parent, %{slug: slug}, nil)
|
||||
{:post, _} -> {:error, "No such post"}
|
||||
end
|
||||
end
|
||||
|
||||
def get_post(
|
||||
_parent,
|
||||
%{slug: slug},
|
||||
_resolution
|
||||
) do
|
||||
case {:post, Posts.get_post_by_slug_with_preloads(slug)} do
|
||||
{:post, %Post{visibility: visibility, draft: false} = post}
|
||||
when visibility in @public_accessible_visibilities ->
|
||||
{:ok, post}
|
||||
|
||||
{:post, _} ->
|
||||
{:error, "No such post"}
|
||||
end
|
||||
end
|
||||
|
||||
def get_post(_parent, _args, _resolution) do
|
||||
{:error, "No such post"}
|
||||
end
|
||||
|
||||
def create_post(
|
||||
_parent,
|
||||
%{attributed_to_id: group_id} = args,
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Post{} = post} <-
|
||||
ActivityPub.create(
|
||||
:post,
|
||||
args
|
||||
|> Map.put(:author_id, actor_id)
|
||||
|> Map.put(:attributed_to_id, group_id),
|
||||
true,
|
||||
%{}
|
||||
) do
|
||||
{:ok, post}
|
||||
else
|
||||
{:own_check, _} ->
|
||||
{:error, "Parent post doesn't match this group"}
|
||||
|
||||
{:member, _} ->
|
||||
{:error, "Actor id is not member of group"}
|
||||
end
|
||||
end
|
||||
|
||||
def create_post(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in to create posts"}
|
||||
end
|
||||
|
||||
def update_post(
|
||||
_parent,
|
||||
%{id: id} = args,
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:uuid, {:ok, _uuid}} <- {:uuid, Ecto.UUID.cast(id)},
|
||||
%Actor{id: actor_id} <- Users.get_actor_for_user(user),
|
||||
{:post, %Post{attributed_to: %Actor{id: group_id}} = post} <-
|
||||
{:post, Posts.get_post_with_preloads(id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Post{} = post} <-
|
||||
ActivityPub.update(post, args, true, %{}) do
|
||||
{:ok, post}
|
||||
else
|
||||
{:uuid, :error} ->
|
||||
{:error, "Post ID is not a valid ID"}
|
||||
|
||||
{:post, _} ->
|
||||
{:error, "Post doesn't exist"}
|
||||
|
||||
{:member, _} ->
|
||||
{:error, "Actor id is not member of group"}
|
||||
end
|
||||
end
|
||||
|
||||
def update_post(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in to update posts"}
|
||||
end
|
||||
|
||||
def delete_post(
|
||||
_parent,
|
||||
%{id: post_id},
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:uuid, {:ok, _uuid}} <- {:uuid, Ecto.UUID.cast(post_id)},
|
||||
%Actor{id: actor_id} = actor <- Users.get_actor_for_user(user),
|
||||
{:post, %Post{attributed_to: %Actor{id: group_id}} = post} <-
|
||||
{:post, Posts.get_post_with_preloads(post_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Post{} = post} <-
|
||||
ActivityPub.delete(post, actor) do
|
||||
{:ok, post}
|
||||
else
|
||||
{:uuid, :error} ->
|
||||
{:error, "Post ID is not a valid ID"}
|
||||
|
||||
{:post, _} ->
|
||||
{:error, "Post doesn't exist"}
|
||||
|
||||
{:member, _} ->
|
||||
{:error, "Actor id is not member of group"}
|
||||
end
|
||||
end
|
||||
|
||||
def delete_post(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in to delete posts"}
|
||||
end
|
||||
end
|
||||
@@ -141,7 +141,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
{:resource, Resources.get_resource_with_preloads(resource_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Resource{} = resource} <-
|
||||
ActivityPub.update(:resource, resource, args, true, %{}) do
|
||||
ActivityPub.update(resource, args, true, %{}) do
|
||||
{:ok, resource}
|
||||
else
|
||||
{:resource, _} ->
|
||||
@@ -165,12 +165,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
|
||||
with %Actor{id: actor_id} = actor <- Users.get_actor_for_user(user),
|
||||
{:resource, %Resource{parent_id: _parent_id, actor_id: group_id} = resource} <-
|
||||
{:resource, Resources.get_resource_with_preloads(resource_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Resource{} = resource} <-
|
||||
ActivityPub.delete(resource) do
|
||||
ActivityPub.delete(resource, actor) do
|
||||
{:ok, resource}
|
||||
else
|
||||
{:resource, _} ->
|
||||
|
||||
@@ -3,8 +3,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Tag do
|
||||
Handles the tag-related GraphQL calls
|
||||
"""
|
||||
|
||||
alias Mobilizon.Events
|
||||
alias Mobilizon.{Events, Posts}
|
||||
alias Mobilizon.Events.{Event, Tag}
|
||||
alias Mobilizon.Posts.Post
|
||||
|
||||
def list_tags(_parent, %{page: page, limit: limit}, _resolution) do
|
||||
tags = Mobilizon.Events.list_tags(page, limit)
|
||||
@@ -16,7 +17,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Tag do
|
||||
Retrieve the list of tags for an event
|
||||
"""
|
||||
def list_tags_for_event(%Event{id: id}, _args, _resolution) do
|
||||
{:ok, Mobilizon.Events.list_tags_for_event(id)}
|
||||
{:ok, Events.list_tags_for_event(id)}
|
||||
end
|
||||
|
||||
@doc """
|
||||
@@ -24,10 +25,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Tag do
|
||||
"""
|
||||
def list_tags_for_event(%{url: url}, _args, _resolution) do
|
||||
with %Event{id: event_id} <- Events.get_event_by_url(url) do
|
||||
{:ok, Mobilizon.Events.list_tags_for_event(event_id)}
|
||||
{:ok, Events.list_tags_for_event(event_id)}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Retrieve the list of tags for a post
|
||||
"""
|
||||
def list_tags_for_post(%Post{id: id}, _args, _resolution) do
|
||||
{:ok, Posts.list_tags_for_post(id)}
|
||||
end
|
||||
|
||||
# @doc """
|
||||
# Retrieve the list of related tags for a given tag ID
|
||||
# """
|
||||
@@ -42,7 +50,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Tag do
|
||||
Retrieve the list of related tags for a parent tag
|
||||
"""
|
||||
def get_related_tags(%Tag{} = tag, _args, _resolution) do
|
||||
with tags <- Mobilizon.Events.list_tag_neighbors(tag) do
|
||||
with tags <- Events.list_tag_neighbors(tag) do
|
||||
{:ok, tags}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -211,7 +211,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
{:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Todo{} = todo} <-
|
||||
ActivityPub.update(:todo, todo, args, true, %{}) do
|
||||
ActivityPub.update(todo, args, true, %{}) do
|
||||
{:ok, todo}
|
||||
else
|
||||
{:todo_list, _} ->
|
||||
|
||||
@@ -9,6 +9,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Crypto
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
alias Mobilizon.Service.Auth.Authenticator
|
||||
alias Mobilizon.Storage.{Page, Repo}
|
||||
alias Mobilizon.Users.{Setting, User}
|
||||
@@ -417,7 +418,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
with {:moderator_actor, %Actor{} = moderator_actor} <-
|
||||
{:moderator_actor, Users.get_actor_for_user(moderator_user)},
|
||||
%User{disabled: false} = user <- Users.get_user(user_id),
|
||||
{:ok, %User{}} <- do_delete_account(%User{} = user) do
|
||||
{:ok, %User{}} <-
|
||||
do_delete_account(%User{} = user, Relay.get_actor()) do
|
||||
Admin.log_action(moderator_actor, "delete", user)
|
||||
else
|
||||
{:moderator_actor, nil} ->
|
||||
@@ -432,7 +434,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
{:error, "You need to be logged-in to delete your account"}
|
||||
end
|
||||
|
||||
defp do_delete_account(%User{} = user) do
|
||||
defp do_delete_account(%User{} = user, actor_performing \\ nil) do
|
||||
with actors <- Users.get_actors_for_user(user),
|
||||
activated <- not is_nil(user.confirmed_at),
|
||||
# Detach actors from user
|
||||
@@ -444,7 +446,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
# Launch a background job to delete actors
|
||||
:ok <-
|
||||
Enum.each(actors, fn actor ->
|
||||
ActivityPub.delete(actor, true)
|
||||
actor_performing = actor_performing || actor
|
||||
ActivityPub.delete(actor, actor_performing, true)
|
||||
end),
|
||||
# Delete user
|
||||
{:ok, user} <- Users.delete_user(user, reserve_email: activated) do
|
||||
|
||||
@@ -8,7 +8,7 @@ defmodule Mobilizon.GraphQL.Schema do
|
||||
alias Mobilizon.{
|
||||
Actors,
|
||||
Addresses,
|
||||
Conversations,
|
||||
Discussions,
|
||||
Events,
|
||||
Media,
|
||||
Reports,
|
||||
@@ -18,7 +18,7 @@ defmodule Mobilizon.GraphQL.Schema do
|
||||
}
|
||||
|
||||
alias Mobilizon.Actors.{Actor, Follower, Member}
|
||||
alias Mobilizon.Conversations.Comment
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.{Event, Participant}
|
||||
alias Mobilizon.GraphQL.Schema
|
||||
alias Mobilizon.Storage.Repo
|
||||
@@ -34,10 +34,11 @@ defmodule Mobilizon.GraphQL.Schema do
|
||||
import_types(Schema.Actors.PersonType)
|
||||
import_types(Schema.Actors.GroupType)
|
||||
import_types(Schema.Actors.ApplicationType)
|
||||
import_types(Schema.Conversations.CommentType)
|
||||
import_types(Schema.Conversations.ConversationType)
|
||||
import_types(Schema.Discussions.CommentType)
|
||||
import_types(Schema.Discussions.DiscussionType)
|
||||
import_types(Schema.SearchType)
|
||||
import_types(Schema.ResourceType)
|
||||
import_types(Schema.PostType)
|
||||
import_types(Schema.Todos.TodoListType)
|
||||
import_types(Schema.Todos.TodoType)
|
||||
import_types(Schema.ConfigType)
|
||||
@@ -116,7 +117,7 @@ defmodule Mobilizon.GraphQL.Schema do
|
||||
|> Dataloader.add_source(Actors, default_source)
|
||||
|> Dataloader.add_source(Users, default_source)
|
||||
|> Dataloader.add_source(Events, default_source)
|
||||
|> Dataloader.add_source(Conversations, Conversations.data())
|
||||
|> Dataloader.add_source(Discussions, Discussions.data())
|
||||
|> Dataloader.add_source(Addresses, default_source)
|
||||
|> Dataloader.add_source(Media, default_source)
|
||||
|> Dataloader.add_source(Reports, default_source)
|
||||
@@ -148,8 +149,9 @@ defmodule Mobilizon.GraphQL.Schema do
|
||||
import_fields(:admin_queries)
|
||||
import_fields(:todo_list_queries)
|
||||
import_fields(:todo_queries)
|
||||
import_fields(:conversation_queries)
|
||||
import_fields(:discussion_queries)
|
||||
import_fields(:resource_queries)
|
||||
import_fields(:post_queries)
|
||||
import_fields(:statistics_queries)
|
||||
end
|
||||
|
||||
@@ -170,8 +172,9 @@ defmodule Mobilizon.GraphQL.Schema do
|
||||
import_fields(:admin_mutations)
|
||||
import_fields(:todo_list_mutations)
|
||||
import_fields(:todo_mutations)
|
||||
import_fields(:conversation_mutations)
|
||||
import_fields(:discussion_mutations)
|
||||
import_fields(:resource_mutations)
|
||||
import_fields(:post_mutations)
|
||||
end
|
||||
|
||||
@desc """
|
||||
@@ -179,5 +182,6 @@ defmodule Mobilizon.GraphQL.Schema do
|
||||
"""
|
||||
subscription do
|
||||
import_fields(:person_subscriptions)
|
||||
import_fields(:discussion_subscriptions)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
|
||||
|
||||
use Absinthe.Schema.Notation
|
||||
|
||||
alias Mobilizon.GraphQL.Resolvers.{Conversation, Group, Member, Resource, Todos}
|
||||
alias Mobilizon.GraphQL.Resolvers.{Discussion, Group, Member, Post, Resource, Todos}
|
||||
alias Mobilizon.GraphQL.Schema
|
||||
|
||||
import_types(Schema.Actors.MemberType)
|
||||
@@ -46,9 +46,9 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
|
||||
description("A list of the events this actor has organized")
|
||||
end
|
||||
|
||||
field :conversations, :paginated_conversation_list do
|
||||
resolve(&Conversation.find_conversations_for_actor/3)
|
||||
description("A list of the conversations for this group")
|
||||
field :discussions, :paginated_discussion_list do
|
||||
resolve(&Discussion.find_discussions_for_actor/3)
|
||||
description("A list of the discussions for this group")
|
||||
end
|
||||
|
||||
field(:types, :group_type, description: "The type of group : Group, Community,…")
|
||||
@@ -58,8 +58,11 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
|
||||
)
|
||||
|
||||
field :members, :paginated_member_list do
|
||||
arg(:page, :integer, default_value: 1)
|
||||
arg(:limit, :integer, default_value: 10)
|
||||
arg(:roles, :string, default_value: "")
|
||||
resolve(&Member.find_members_for_group/3)
|
||||
description("List of group members")
|
||||
description("A paginated list of group members")
|
||||
end
|
||||
|
||||
field :resources, :paginated_resource_list do
|
||||
@@ -69,6 +72,13 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
|
||||
description("A paginated list of the resources this group has")
|
||||
end
|
||||
|
||||
field :posts, :paginated_post_list do
|
||||
arg(:page, :integer, default_value: 1)
|
||||
arg(:limit, :integer, default_value: 10)
|
||||
resolve(&Post.find_posts_for_group/3)
|
||||
description("A paginated list of the posts this group has")
|
||||
end
|
||||
|
||||
field :todo_lists, :paginated_todo_list_list do
|
||||
resolve(&Todos.find_todo_lists_for_group/3)
|
||||
description("A paginated list of the todo lists this group has")
|
||||
@@ -99,6 +109,12 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
|
||||
field(:total, :integer, description: "The total number of elements in the list")
|
||||
end
|
||||
|
||||
@desc "The list of visibility options for a group"
|
||||
enum :group_visibility do
|
||||
value(:public, description: "Publicly listed and federated")
|
||||
value(:unlisted, description: "Visible only to people with the link - or invited")
|
||||
end
|
||||
|
||||
object :group_queries do
|
||||
@desc "Get all groups"
|
||||
field :groups, :paginated_group_list do
|
||||
@@ -124,6 +140,11 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
|
||||
arg(:name, :string, description: "The displayed name for the group")
|
||||
arg(:summary, :string, description: "The summary for the group", default_value: "")
|
||||
|
||||
arg(:visibility, :group_visibility,
|
||||
description: "The visibility for the group",
|
||||
default_value: :public
|
||||
)
|
||||
|
||||
arg(:avatar, :picture_input,
|
||||
description:
|
||||
"The avatar for the group, either as an object or directly the ID of an existing Picture"
|
||||
@@ -137,6 +158,26 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
|
||||
resolve(&Group.create_group/3)
|
||||
end
|
||||
|
||||
@desc "Update a group"
|
||||
field :update_group, :group do
|
||||
arg(:id, non_null(:id), description: "The group ID")
|
||||
|
||||
arg(:name, :string, description: "The displayed name for the group")
|
||||
arg(:summary, :string, description: "The summary for the group", default_value: "")
|
||||
|
||||
arg(:avatar, :picture_input,
|
||||
description:
|
||||
"The avatar for the group, either as an object or directly the ID of an existing Picture"
|
||||
)
|
||||
|
||||
arg(:banner, :picture_input,
|
||||
description:
|
||||
"The banner for the group, either as an object or directly the ID of an existing Picture"
|
||||
)
|
||||
|
||||
resolve(&Group.update_group/3)
|
||||
end
|
||||
|
||||
@desc "Delete a group"
|
||||
field :delete_group, :deleted_object do
|
||||
arg(:group_id, non_null(:id))
|
||||
|
||||
@@ -15,6 +15,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.MemberType do
|
||||
field(:actor, :person, description: "Which profile is member of")
|
||||
field(:role, :member_role_enum, description: "The role of this membership")
|
||||
field(:invited_by, :person, description: "Who invited this member")
|
||||
field(:inserted_at, :naive_datetime, description: "When was this member created")
|
||||
end
|
||||
|
||||
enum :member_role_enum do
|
||||
|
||||
@@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
|
||||
use Absinthe.Schema.Notation
|
||||
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Conversations.Comment
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Reports.{Note, Report}
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
defmodule Mobilizon.GraphQL.Schema.Conversations.ConversationType do
|
||||
@moduledoc """
|
||||
Schema representation for Conversation
|
||||
"""
|
||||
use Absinthe.Schema.Notation
|
||||
|
||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
||||
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.GraphQL.Resolvers.Conversation
|
||||
|
||||
@desc "A conversation"
|
||||
object :conversation do
|
||||
field(:id, :id, description: "Internal ID for this conversation")
|
||||
field(:title, :string)
|
||||
field(:slug, :string)
|
||||
field(:last_comment, :comment)
|
||||
|
||||
field :comments, :paginated_comment_list do
|
||||
arg(:page, :integer, default_value: 1)
|
||||
arg(:limit, :integer, default_value: 10)
|
||||
resolve(&Conversation.get_comments_for_conversation/3)
|
||||
description("The comments for the conversation")
|
||||
end
|
||||
|
||||
field(:creator, :person, resolve: dataloader(Actors))
|
||||
field(:actor, :actor, resolve: dataloader(Actors))
|
||||
field(:inserted_at, :datetime)
|
||||
field(:updated_at, :datetime)
|
||||
end
|
||||
|
||||
object :paginated_conversation_list do
|
||||
field(:elements, list_of(:conversation), description: "A list of conversation")
|
||||
field(:total, :integer, description: "The total number of comments in the list")
|
||||
end
|
||||
|
||||
object :conversation_queries do
|
||||
@desc "Get a conversation"
|
||||
field :conversation, type: :conversation do
|
||||
arg(:id, non_null(:id))
|
||||
resolve(&Conversation.get_conversation/3)
|
||||
end
|
||||
end
|
||||
|
||||
object :conversation_mutations do
|
||||
@desc "Create a conversation"
|
||||
field :create_conversation, type: :conversation do
|
||||
arg(:title, non_null(:string))
|
||||
arg(:text, non_null(:string))
|
||||
arg(:actor_id, non_null(:id))
|
||||
arg(:creator_id, non_null(:id))
|
||||
|
||||
resolve(&Conversation.create_conversation/3)
|
||||
end
|
||||
|
||||
field :reply_to_conversation, type: :conversation do
|
||||
arg(:conversation_id, non_null(:id))
|
||||
arg(:text, non_null(:string))
|
||||
resolve(&Conversation.reply_to_conversation/3)
|
||||
end
|
||||
|
||||
field :update_conversation, type: :conversation do
|
||||
arg(:title, non_null(:string))
|
||||
arg(:conversation_id, non_null(:id))
|
||||
resolve(&Conversation.update_conversation/3)
|
||||
end
|
||||
|
||||
field :delete_conversation, type: :conversation do
|
||||
arg(:conversation_id, non_null(:id))
|
||||
|
||||
# resolve(&Conversation.delete_conversation/3)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule Mobilizon.GraphQL.Schema.Conversations.CommentType do
|
||||
defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
|
||||
@moduledoc """
|
||||
Schema representation for Comment
|
||||
"""
|
||||
@@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.Schema.Conversations.CommentType do
|
||||
|
||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
||||
|
||||
alias Mobilizon.{Actors, Conversations}
|
||||
alias Mobilizon.{Actors, Discussions}
|
||||
alias Mobilizon.GraphQL.Resolvers.Comment
|
||||
|
||||
@desc "A comment"
|
||||
@@ -21,13 +21,13 @@ defmodule Mobilizon.GraphQL.Schema.Conversations.CommentType do
|
||||
field(:primaryLanguage, :string)
|
||||
|
||||
field(:replies, list_of(:comment)) do
|
||||
resolve(dataloader(Conversations))
|
||||
resolve(dataloader(Discussions))
|
||||
end
|
||||
|
||||
field(:total_replies, :integer)
|
||||
field(:in_reply_to_comment, :comment, resolve: dataloader(Conversations))
|
||||
field(:in_reply_to_comment, :comment, resolve: dataloader(Discussions))
|
||||
field(:event, :event, resolve: dataloader(Events))
|
||||
field(:origin_comment, :comment, resolve: dataloader(Conversations))
|
||||
field(:origin_comment, :comment, resolve: dataloader(Discussions))
|
||||
field(:threadLanguages, non_null(list_of(:string)))
|
||||
field(:actor, :person, resolve: dataloader(Actors))
|
||||
field(:inserted_at, :datetime)
|
||||
85
lib/graphql/schema/discussions/discussion.ex
Normal file
85
lib/graphql/schema/discussions/discussion.ex
Normal file
@@ -0,0 +1,85 @@
|
||||
defmodule Mobilizon.GraphQL.Schema.Discussions.DiscussionType do
|
||||
@moduledoc """
|
||||
Schema representation for discussion
|
||||
"""
|
||||
use Absinthe.Schema.Notation
|
||||
|
||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
||||
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.GraphQL.Resolvers.Discussion
|
||||
|
||||
@desc "A discussion"
|
||||
object :discussion do
|
||||
field(:id, :id, description: "Internal ID for this discussion")
|
||||
field(:title, :string)
|
||||
field(:slug, :string)
|
||||
field(:last_comment, :comment)
|
||||
|
||||
field :comments, :paginated_comment_list do
|
||||
arg(:page, :integer, default_value: 1)
|
||||
arg(:limit, :integer, default_value: 10)
|
||||
resolve(&Discussion.get_comments_for_discussion/3)
|
||||
description("The comments for the discussion")
|
||||
end
|
||||
|
||||
field(:creator, :person, resolve: dataloader(Actors))
|
||||
field(:actor, :actor, resolve: dataloader(Actors))
|
||||
field(:inserted_at, :datetime)
|
||||
field(:updated_at, :datetime)
|
||||
end
|
||||
|
||||
object :paginated_discussion_list do
|
||||
field(:elements, list_of(:discussion), description: "A list of discussion")
|
||||
field(:total, :integer, description: "The total number of comments in the list")
|
||||
end
|
||||
|
||||
object :discussion_queries do
|
||||
@desc "Get a discussion"
|
||||
field :discussion, type: :discussion do
|
||||
arg(:id, :id)
|
||||
arg(:slug, :string)
|
||||
resolve(&Discussion.get_discussion/3)
|
||||
end
|
||||
end
|
||||
|
||||
object :discussion_mutations do
|
||||
@desc "Create a discussion"
|
||||
field :create_discussion, type: :discussion do
|
||||
arg(:title, non_null(:string))
|
||||
arg(:text, non_null(:string))
|
||||
arg(:actor_id, non_null(:id))
|
||||
arg(:creator_id, non_null(:id))
|
||||
|
||||
resolve(&Discussion.create_discussion/3)
|
||||
end
|
||||
|
||||
field :reply_to_discussion, type: :discussion do
|
||||
arg(:discussion_id, non_null(:id))
|
||||
arg(:text, non_null(:string))
|
||||
resolve(&Discussion.reply_to_discussion/3)
|
||||
end
|
||||
|
||||
field :update_discussion, type: :discussion do
|
||||
arg(:title, non_null(:string))
|
||||
arg(:discussion_id, non_null(:id))
|
||||
resolve(&Discussion.update_discussion/3)
|
||||
end
|
||||
|
||||
field :delete_discussion, type: :discussion do
|
||||
arg(:discussion_id, non_null(:id))
|
||||
|
||||
resolve(&Discussion.delete_discussion/3)
|
||||
end
|
||||
end
|
||||
|
||||
object :discussion_subscriptions do
|
||||
field :discussion_comment_changed, :discussion do
|
||||
arg(:slug, non_null(:string))
|
||||
|
||||
config(fn args, _ ->
|
||||
{:ok, topic: args.slug}
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,7 +8,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
|
||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
||||
import Mobilizon.GraphQL.Helpers.Error
|
||||
|
||||
alias Mobilizon.{Actors, Addresses, Conversations}
|
||||
alias Mobilizon.{Actors, Addresses, Discussions}
|
||||
alias Mobilizon.GraphQL.Resolvers.{Event, Picture, Tag}
|
||||
alias Mobilizon.GraphQL.Schema
|
||||
|
||||
@@ -82,7 +82,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
|
||||
)
|
||||
|
||||
field(:comments, list_of(:comment), description: "The comments in reply to the event") do
|
||||
resolve(dataloader(Conversations))
|
||||
resolve(dataloader(Discussions))
|
||||
end
|
||||
|
||||
# field(:tracks, list_of(:track))
|
||||
|
||||
91
lib/graphql/schema/post.ex
Normal file
91
lib/graphql/schema/post.ex
Normal file
@@ -0,0 +1,91 @@
|
||||
defmodule Mobilizon.GraphQL.Schema.PostType do
|
||||
@moduledoc """
|
||||
Schema representation for Posts
|
||||
"""
|
||||
use Absinthe.Schema.Notation
|
||||
alias Mobilizon.GraphQL.Resolvers.{Post, Tag}
|
||||
|
||||
@desc "A post"
|
||||
object :post do
|
||||
field(:id, :id, description: "The post's ID")
|
||||
field(:title, :string, description: "The post's title")
|
||||
field(:slug, :string, description: "The post's slug")
|
||||
field(:body, :string, description: "The post's body, as HTML")
|
||||
field(:url, :string, description: "The post's URL")
|
||||
field(:draft, :boolean, description: "Whether the post is a draft")
|
||||
field(:author, :actor, description: "The post's author")
|
||||
field(:attributed_to, :actor, description: "The post's group")
|
||||
field(:visibility, :post_visibility, description: "The post's visibility")
|
||||
field(:publish_at, :datetime, description: "When the post was published")
|
||||
field(:inserted_at, :naive_datetime, description: "The post's creation date")
|
||||
field(:updated_at, :naive_datetime, description: "The post's last update date")
|
||||
|
||||
field(:tags, list_of(:tag),
|
||||
resolve: &Tag.list_tags_for_post/3,
|
||||
description: "The post's tags"
|
||||
)
|
||||
end
|
||||
|
||||
object :paginated_post_list do
|
||||
field(:elements, list_of(:post), description: "A list of posts")
|
||||
field(:total, :integer, description: "The total number of posts in the list")
|
||||
end
|
||||
|
||||
@desc "The list of visibility options for a post"
|
||||
enum :post_visibility do
|
||||
value(:public, description: "Publicly listed and federated. Can be shared.")
|
||||
value(:unlisted, description: "Visible only to people with the link")
|
||||
# value(:restricted, description: "Visible only after a moderator accepted")
|
||||
|
||||
value(:private,
|
||||
description: "Visible only to people members of the group or followers of the person"
|
||||
)
|
||||
end
|
||||
|
||||
object :post_queries do
|
||||
@desc "Get a post"
|
||||
field :post, :post do
|
||||
arg(:slug, non_null(:string))
|
||||
resolve(&Post.get_post/3)
|
||||
end
|
||||
end
|
||||
|
||||
object :post_mutations do
|
||||
@desc "Create a post"
|
||||
field :create_post, :post do
|
||||
arg(:attributed_to_id, non_null(:id))
|
||||
arg(:title, non_null(:string))
|
||||
arg(:body, :string)
|
||||
arg(:draft, :boolean, default_value: false)
|
||||
arg(:visibility, :post_visibility)
|
||||
arg(:publish_at, :datetime)
|
||||
|
||||
arg(:tags, list_of(:string),
|
||||
default_value: [],
|
||||
description: "The list of tags associated to the post"
|
||||
)
|
||||
|
||||
resolve(&Post.create_post/3)
|
||||
end
|
||||
|
||||
@desc "Update a post"
|
||||
field :update_post, :post do
|
||||
arg(:id, non_null(:id))
|
||||
arg(:title, :string)
|
||||
arg(:body, :string)
|
||||
arg(:attributed_to_id, :id)
|
||||
arg(:draft, :boolean)
|
||||
arg(:visibility, :post_visibility)
|
||||
arg(:publish_at, :datetime)
|
||||
arg(:tags, list_of(:string), description: "The list of tags associated to the post")
|
||||
|
||||
resolve(&Post.update_post/3)
|
||||
end
|
||||
|
||||
@desc "Delete a post"
|
||||
field :delete_post, :deleted_object do
|
||||
arg(:id, non_null(:id))
|
||||
resolve(&Post.delete_post/3)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user