@@ -32,6 +32,7 @@ defmodule Mobilizon.Events.Event do
|
||||
ends_on: DateTime.t(),
|
||||
title: String.t(),
|
||||
status: EventStatus.t(),
|
||||
draft: boolean,
|
||||
visibility: EventVisibility.t(),
|
||||
join_options: JoinOptions.t(),
|
||||
publish_at: DateTime.t(),
|
||||
@@ -57,6 +58,7 @@ defmodule Mobilizon.Events.Event do
|
||||
:ends_on,
|
||||
:category,
|
||||
:status,
|
||||
:draft,
|
||||
:visibility,
|
||||
:publish_at,
|
||||
:online_address,
|
||||
@@ -74,6 +76,7 @@ defmodule Mobilizon.Events.Event do
|
||||
:ends_on,
|
||||
:category,
|
||||
:status,
|
||||
:draft,
|
||||
:visibility,
|
||||
:join_options,
|
||||
:publish_at,
|
||||
@@ -93,6 +96,7 @@ defmodule Mobilizon.Events.Event do
|
||||
field(:ends_on, :utc_datetime)
|
||||
field(:title, :string)
|
||||
field(:status, EventStatus, default: :confirmed)
|
||||
field(:draft, :boolean, default: false)
|
||||
field(:visibility, EventVisibility, default: :public)
|
||||
field(:join_options, JoinOptions, default: :free)
|
||||
field(:publish_at, :utc_datetime)
|
||||
|
||||
@@ -169,6 +169,7 @@ defmodule Mobilizon.Events do
|
||||
url
|
||||
|> event_by_url_query()
|
||||
|> filter_public_visibility()
|
||||
|> filter_draft()
|
||||
|> preload_for_event()
|
||||
|> Repo.one()
|
||||
|
||||
@@ -190,18 +191,32 @@ defmodule Mobilizon.Events do
|
||||
url
|
||||
|> event_by_url_query()
|
||||
|> filter_public_visibility()
|
||||
|> filter_draft()
|
||||
|> preload_for_event()
|
||||
|> Repo.one!()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets an event by its UUID, with all associations loaded.
|
||||
Gets a public event by its UUID, with all associations loaded.
|
||||
"""
|
||||
@spec get_public_event_by_uuid_with_preload(String.t()) :: Event.t() | nil
|
||||
def get_public_event_by_uuid_with_preload(uuid) do
|
||||
uuid
|
||||
|> event_by_uuid_query()
|
||||
|> filter_public_visibility()
|
||||
|> filter_draft()
|
||||
|> preload_for_event()
|
||||
|> Repo.one()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets an event by its UUID, with all associations loaded.
|
||||
"""
|
||||
@spec get_own_event_by_uuid_with_preload(String.t(), integer()) :: Event.t() | nil
|
||||
def get_own_event_by_uuid_with_preload(uuid, user_id) do
|
||||
uuid
|
||||
|> event_by_uuid_query()
|
||||
|> user_events_query(user_id)
|
||||
|> preload_for_event()
|
||||
|> Repo.one()
|
||||
end
|
||||
@@ -215,6 +230,7 @@ defmodule Mobilizon.Events do
|
||||
|> upcoming_public_event_for_actor_query()
|
||||
|> filter_public_visibility()
|
||||
|> filter_not_event_uuid(not_event_uuid)
|
||||
|> filter_draft()
|
||||
|> Repo.one()
|
||||
end
|
||||
|
||||
@@ -223,16 +239,18 @@ defmodule Mobilizon.Events do
|
||||
"""
|
||||
@spec create_event(map) :: {:ok, Event.t()} | {:error, Ecto.Changeset.t()}
|
||||
def create_event(attrs \\ %{}) do
|
||||
with {:ok, %Event{} = event} <- do_create_event(attrs),
|
||||
with {:ok, %Event{draft: false} = event} <- do_create_event(attrs),
|
||||
{:ok, %Participant{} = _participant} <-
|
||||
%Participant{}
|
||||
|> Participant.changeset(%{
|
||||
create_participant(%{
|
||||
actor_id: event.organizer_actor_id,
|
||||
role: :creator,
|
||||
event_id: event.id
|
||||
})
|
||||
|> Repo.insert() do
|
||||
}) do
|
||||
{:ok, event}
|
||||
else
|
||||
# We don't create a creator participant if the event is a draft
|
||||
{:ok, %Event{draft: true} = event} -> {:ok, event}
|
||||
err -> err
|
||||
end
|
||||
end
|
||||
|
||||
@@ -262,10 +280,24 @@ defmodule Mobilizon.Events do
|
||||
Updates an event.
|
||||
"""
|
||||
@spec update_event(Event.t(), map) :: {:ok, Event.t()} | {:error, Ecto.Changeset.t()}
|
||||
def update_event(%Event{} = old_event, attrs) do
|
||||
def update_event(
|
||||
%Event{draft: old_draft_status, id: event_id, organizer_actor_id: organizer_actor_id} =
|
||||
old_event,
|
||||
attrs
|
||||
) do
|
||||
with %Ecto.Changeset{changes: changes} = changeset <-
|
||||
old_event |> Repo.preload(:tags) |> Event.update_changeset(attrs) do
|
||||
with {:ok, %Event{} = new_event} <- Repo.update(changeset) do
|
||||
with {:ok, %Event{draft: new_draft_status} = new_event} <- Repo.update(changeset) do
|
||||
# If the event is no longer a draft
|
||||
if old_draft_status == true && new_draft_status == false do
|
||||
{:ok, %Participant{} = _participant} =
|
||||
create_participant(%{
|
||||
event_id: event_id,
|
||||
role: :creator,
|
||||
actor_id: organizer_actor_id
|
||||
})
|
||||
end
|
||||
|
||||
Mobilizon.Service.Events.Tool.calculate_event_diff_and_send_notifications(
|
||||
old_event,
|
||||
new_event,
|
||||
@@ -309,6 +341,7 @@ defmodule Mobilizon.Events do
|
||||
|> sort(sort, direction)
|
||||
|> filter_future_events(is_future)
|
||||
|> filter_unlisted(is_unlisted)
|
||||
|> filter_draft()
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@@ -320,6 +353,7 @@ defmodule Mobilizon.Events do
|
||||
tags
|
||||
|> Enum.map(& &1.id)
|
||||
|> events_by_tags_query(limit)
|
||||
|> filter_draft()
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@@ -333,6 +367,7 @@ defmodule Mobilizon.Events do
|
||||
actor_id
|
||||
|> event_for_actor_query()
|
||||
|> filter_public_visibility()
|
||||
|> filter_draft()
|
||||
|> preload_for_event()
|
||||
|> Page.paginate(page, limit)
|
||||
|> Repo.all()
|
||||
@@ -345,6 +380,15 @@ defmodule Mobilizon.Events do
|
||||
{:ok, events, events_count}
|
||||
end
|
||||
|
||||
@spec list_drafts_for_user(integer, integer | nil, integer | nil) :: [Event.t()]
|
||||
def list_drafts_for_user(user_id, page \\ nil, limit \\ nil) do
|
||||
Event
|
||||
|> user_events_query(user_id)
|
||||
|> filter_draft(true)
|
||||
|> Page.paginate(page, limit)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Finds close events to coordinates.
|
||||
Radius is in meters and defaults to 50km.
|
||||
@@ -354,6 +398,7 @@ defmodule Mobilizon.Events do
|
||||
"SRID=#{srid};POINT(#{lon} #{lat})"
|
||||
|> Geo.WKT.decode!()
|
||||
|> close_events_query(radius)
|
||||
|> filter_draft()
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@@ -364,6 +409,7 @@ defmodule Mobilizon.Events do
|
||||
def count_local_events do
|
||||
count_local_events_query()
|
||||
|> filter_public_visibility()
|
||||
|> filter_draft()
|
||||
|> Repo.one()
|
||||
end
|
||||
|
||||
@@ -1134,6 +1180,16 @@ defmodule Mobilizon.Events do
|
||||
)
|
||||
end
|
||||
|
||||
@spec user_events_query(Ecto.Query.t(), number()) :: Ecto.Query.t()
|
||||
defp user_events_query(query, user_id) do
|
||||
from(
|
||||
e in query,
|
||||
join: a in Actor,
|
||||
on: a.id == e.organizer_actor_id,
|
||||
where: a.user_id == ^user_id
|
||||
)
|
||||
end
|
||||
|
||||
@spec events_by_name_query(String.t()) :: Ecto.Query.t()
|
||||
defp events_by_name_query(name) do
|
||||
from(
|
||||
@@ -1372,6 +1428,11 @@ defmodule Mobilizon.Events do
|
||||
from(e in query, where: e.uuid != ^not_event_uuid)
|
||||
end
|
||||
|
||||
@spec filter_draft(Ecto.Query.t(), boolean) :: Ecto.Query.t()
|
||||
defp filter_draft(query, is_draft \\ false) do
|
||||
from(e in query, where: e.draft == ^is_draft)
|
||||
end
|
||||
|
||||
@spec filter_future_events(Ecto.Query.t(), boolean) :: Ecto.Query.t()
|
||||
defp filter_future_events(query, true) do
|
||||
from(q in query, where: q.begins_on > ^DateTime.utc_now())
|
||||
|
||||
@@ -31,7 +31,8 @@ defmodule MobilizonWeb.API.Events do
|
||||
to: args.to,
|
||||
actor: organizer_actor,
|
||||
object: event,
|
||||
local: true
|
||||
# For now we don't federate drafts but it will be needed if we want to edit them as groups
|
||||
local: args.metadata.draft == false
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -65,7 +66,7 @@ defmodule MobilizonWeb.API.Events do
|
||||
actor: organizer_actor.url,
|
||||
cc: [],
|
||||
object: event,
|
||||
local: true
|
||||
local: args.metadata.draft == false
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -95,7 +96,8 @@ defmodule MobilizonWeb.API.Events do
|
||||
join_options: Map.get(args, :join_options),
|
||||
status: Map.get(args, :status),
|
||||
online_address: Map.get(args, :online_address),
|
||||
phone_address: Map.get(args, :phone_address)
|
||||
phone_address: Map.get(args, :phone_address),
|
||||
draft: Map.get(args, :draft)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@@ -31,6 +31,20 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
{:error, :events_max_limit_reached}
|
||||
end
|
||||
|
||||
def find_event(
|
||||
_parent,
|
||||
%{uuid: uuid},
|
||||
%{context: %{current_user: %User{id: user_id}}} = _resolution
|
||||
) do
|
||||
case {:has_event, Mobilizon.Events.get_own_event_by_uuid_with_preload(uuid, user_id)} do
|
||||
{:has_event, %Event{} = event} ->
|
||||
{:ok, Map.put(event, :organizer_actor, Person.proxify_pictures(event.organizer_actor))}
|
||||
|
||||
{:has_event, _} ->
|
||||
{:error, "Event with UUID #{uuid} not found"}
|
||||
end
|
||||
end
|
||||
|
||||
def find_event(_parent, %{uuid: uuid}, _resolution) do
|
||||
case {:has_event, Mobilizon.Events.get_public_event_by_uuid_with_preload(uuid)} do
|
||||
{:has_event, %Event{} = event} ->
|
||||
@@ -264,6 +278,9 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
else
|
||||
{:is_owned, nil} ->
|
||||
{:error, "Organizer actor id is not owned by the user"}
|
||||
|
||||
{:error, %Ecto.Changeset{} = error} ->
|
||||
{:error, error}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -243,6 +243,19 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the list of draft events for the current user
|
||||
"""
|
||||
def user_drafted_events(%User{id: user_id}, args, %{
|
||||
context: %{current_user: %User{id: logged_user_id}}
|
||||
}) do
|
||||
with {:same_user, true} <- {:same_user, user_id == logged_user_id},
|
||||
events <-
|
||||
Events.list_drafts_for_user(user_id, Map.get(args, :page), Map.get(args, :limit)) do
|
||||
{:ok, events}
|
||||
end
|
||||
end
|
||||
|
||||
def change_password(_parent, %{old_password: old_password, new_password: new_password}, %{
|
||||
context: %{current_user: %User{password_hash: old_password_hash} = user}
|
||||
}) do
|
||||
|
||||
@@ -6,6 +6,7 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
use Absinthe.Schema.Notation
|
||||
|
||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
||||
import MobilizonWeb.Schema.Utils
|
||||
|
||||
alias Mobilizon.{Actors, Addresses}
|
||||
|
||||
@@ -60,6 +61,8 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
|
||||
field(:category, :string, description: "The event's category")
|
||||
|
||||
field(:draft, :boolean, description: "Whether or not the event is a draft")
|
||||
|
||||
field(:participant_stats, :participant_stats, resolve: &Event.stats_participants_for_event/3)
|
||||
|
||||
field(:participants, list_of(:participant), description: "The event's participants") do
|
||||
@@ -252,8 +255,9 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
arg(:category, :string, default_value: "meeting")
|
||||
arg(:physical_address, :address_input)
|
||||
arg(:options, :event_options_input)
|
||||
arg(:draft, :boolean, default_value: false)
|
||||
|
||||
resolve(&Event.create_event/3)
|
||||
resolve(handle_errors(&Event.create_event/3))
|
||||
end
|
||||
|
||||
@desc "Update an event"
|
||||
@@ -280,8 +284,9 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
arg(:category, :string)
|
||||
arg(:physical_address, :address_input)
|
||||
arg(:options, :event_options_input)
|
||||
arg(:draft, :boolean)
|
||||
|
||||
resolve(&Event.update_event/3)
|
||||
resolve(handle_errors(&Event.update_event/3))
|
||||
end
|
||||
|
||||
@desc "Delete an event"
|
||||
|
||||
@@ -49,7 +49,7 @@ defmodule MobilizonWeb.Schema.UserType do
|
||||
field(:locale, :string, description: "The user's locale")
|
||||
|
||||
field(:participations, list_of(:participant),
|
||||
description: "The list of events this user goes to"
|
||||
description: "The list of participations this user has"
|
||||
) do
|
||||
arg(:after_datetime, :datetime)
|
||||
arg(:before_datetime, :datetime)
|
||||
@@ -57,6 +57,12 @@ defmodule MobilizonWeb.Schema.UserType do
|
||||
arg(:limit, :integer, default_value: 10)
|
||||
resolve(&User.user_participations/3)
|
||||
end
|
||||
|
||||
field(:drafts, list_of(:event), description: "The list of draft events this user has created") do
|
||||
arg(:page, :integer, default_value: 1)
|
||||
arg(:limit, :integer, default_value: 10)
|
||||
resolve(&User.user_drafted_events/3)
|
||||
end
|
||||
end
|
||||
|
||||
enum :user_role do
|
||||
|
||||
@@ -70,6 +70,7 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Event do
|
||||
"status" => object["status"],
|
||||
"online_address" => object["onlineAddress"],
|
||||
"phone_address" => object["phoneAddress"],
|
||||
"draft" => object["draft"] || false,
|
||||
"url" => object["id"],
|
||||
"uuid" => object["uuid"],
|
||||
"tags" => tags,
|
||||
@@ -111,6 +112,7 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Event do
|
||||
"joinOptions" => to_string(event.join_options),
|
||||
"endTime" => event.ends_on |> date_to_string(),
|
||||
"tag" => event.tags |> build_tags(),
|
||||
"draft" => event.draft,
|
||||
"id" => event.url,
|
||||
"url" => event.url
|
||||
}
|
||||
|
||||
@@ -319,6 +319,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
|
||||
"status" => metadata.status,
|
||||
"onlineAddress" => metadata.online_address,
|
||||
"phoneAddress" => metadata.phone_address,
|
||||
"draft" => metadata.draft,
|
||||
"uuid" => uuid,
|
||||
"tag" =>
|
||||
tags |> Enum.uniq() |> Enum.map(fn tag -> %{"type" => "Hashtag", "name" => "##{tag}"} end)
|
||||
|
||||
Reference in New Issue
Block a user