diff --git a/js/src/components/Event/Create.vue b/js/src/components/Event/Create.vue
index 3796aa61a..f24f5b4de 100644
--- a/js/src/components/Event/Create.vue
+++ b/js/src/components/Event/Create.vue
@@ -8,14 +8,8 @@
-
-
-
+
+
@@ -33,7 +27,7 @@
types="geocode"
v-on:placechanged="getAddressData"
>
- -->
+ -->
-
+ >
Create event
@@ -66,125 +59,135 @@
diff --git a/js/src/components/Event/Event.vue b/js/src/components/Event/Event.vue
index 6fa6c9e7b..a7f443823 100644
--- a/js/src/components/Event/Event.vue
+++ b/js/src/components/Event/Event.vue
@@ -105,9 +105,9 @@
-
+
{{ event.physical_address.streetAddress }}
-
+
Mobile
diff --git a/js/src/graphql/event.ts b/js/src/graphql/event.ts
index 444669892..d42ef03f8 100644
--- a/js/src/graphql/event.ts
+++ b/js/src/graphql/event.ts
@@ -12,13 +12,12 @@ export const FETCH_EVENT = gql`
ends_on,
state,
status,
- public,
+ visibility,
thumbnail,
large_image,
publish_at,
- # address_type,
# online_address,
- # phone,
+ # phone_address,
organizerActor {
avatarUrl,
preferredUsername,
@@ -56,13 +55,12 @@ export const FETCH_EVENTS = gql`
ends_on,
state,
status,
- public,
+ visibility,
thumbnail,
large_image,
publish_at,
- # address_type,
# online_address,
- # phone,
+ # phone_address,
organizerActor {
avatarUrl,
preferredUsername,
@@ -87,19 +85,13 @@ export const CREATE_EVENT = gql`
$organizerActorId: Int!,
$categoryId: Int!,
$beginsOn: DateTime!,
- $addressType: AddressType!,
) {
createEvent(
title: $title,
description: $description,
beginsOn: $beginsOn,
organizerActorId: $organizerActorId,
- categoryId: $categoryId,
- addressType: $addressType) {
- uuid,
- title,
- description,
- }
+ categoryId: $categoryId
}
`;
diff --git a/lib/mobilizon/events/event.ex b/lib/mobilizon/events/event.ex
index c93616e07..6f36bcc45 100644
--- a/lib/mobilizon/events/event.ex
+++ b/lib/mobilizon/events/event.ex
@@ -1,5 +1,4 @@
import EctoEnum
-defenum(Mobilizon.Events.AddressTypeEnum, :address_type, [:physical, :url, :phone, :other])
defenum(Mobilizon.Events.EventVisibilityEnum, :event_visibility_type, [
:public,
@@ -38,9 +37,8 @@ defmodule Mobilizon.Events.Event do
field(:large_image, :string)
field(:publish_at, Timex.Ecto.DateTimeWithTimezone)
field(:uuid, Ecto.UUID, default: Ecto.UUID.generate())
- field(:address_type, Mobilizon.Events.AddressTypeEnum, default: :physical)
field(:online_address, :string)
- field(:phone, :string)
+ field(:phone_address, :string)
belongs_to(:organizer_actor, Actor, foreign_key: :organizer_actor_id)
belongs_to(:attributed_to, Actor, foreign_key: :attributed_to_id)
many_to_many(:tags, Tag, join_through: "events_tags")
@@ -69,9 +67,8 @@ defmodule Mobilizon.Events.Event do
:thumbnail,
:large_image,
:publish_at,
- :address_type,
:online_address,
- :phone
+ :phone_address
])
|> cast_assoc(:tags)
|> cast_assoc(:physical_address)
@@ -82,8 +79,7 @@ defmodule Mobilizon.Events.Event do
:organizer_actor_id,
:category_id,
:url,
- :uuid,
- :address_type
+ :uuid
])
end
diff --git a/lib/mobilizon_web/schema.ex b/lib/mobilizon_web/schema.ex
index 02e7543a8..afdac3809 100644
--- a/lib/mobilizon_web/schema.ex
+++ b/lib/mobilizon_web/schema.ex
@@ -4,291 +4,28 @@ defmodule MobilizonWeb.Schema do
"""
use Absinthe.Schema
- import Absinthe.Resolution.Helpers, only: [dataloader: 1]
alias Mobilizon.{Actors, Events}
alias Mobilizon.Actors.{Actor, Follower, Member}
alias Mobilizon.Events.{Event, Comment, Participant}
import_types(MobilizonWeb.Schema.Custom.UUID)
+ import_types(MobilizonWeb.Schema.Custom.Point)
import_types(Absinthe.Type.Custom)
import_types(Absinthe.Plug.Types)
+ import_types(MobilizonWeb.Schema.ActorInterface)
+ import_types(MobilizonWeb.Schema.Actors.PersonType)
+ import_types(MobilizonWeb.Schema.Actors.GroupType)
+ import_types(MobilizonWeb.Schema.CommentType)
+
alias MobilizonWeb.Resolvers
- @desc """
- Represents a person identity
- """
- object :person do
- interfaces([:actor])
- field(:user, :user, description: "The user this actor is associated to")
-
- field(:member_of, list_of(:member), description: "The list of groups this person is member of")
-
- field(:url, :string, description: "The ActivityPub actor's URL")
- field(:type, :actor_type, description: "The type of Actor (Person, Group,…)")
- field(:name, :string, description: "The actor's displayed name")
- field(:domain, :string, description: "The actor's domain if (null if it's this instance)")
- field(:local, :boolean, description: "If the actor is from this instance")
- field(:summary, :string, description: "The actor's summary")
- field(:preferred_username, :string, description: "The actor's preferred username")
- field(:keys, :string, description: "The actors RSA Keys")
-
- field(:manually_approves_followers, :boolean,
- description: "Whether the actors manually approves followers"
- )
-
- field(:suspended, :boolean, description: "If the actor is suspended")
- field(:avatar_url, :string, description: "The actor's avatar url")
- field(:banner_url, :string, description: "The actor's banner url")
-
- # These one should have a privacy setting
- field(:following, list_of(:follower), description: "List of followings")
- field(:followers, list_of(:follower), description: "List of followers")
- field(:followersCount, :integer, description: "Number of followers for this actor")
- field(:followingCount, :integer, description: "Number of actors following this actor")
-
- # This one should have a privacy setting
- field(:organized_events, list_of(:event),
- resolve: dataloader(Events),
- description: "A list of the events this actor has organized"
- )
- end
-
- @desc """
- Represents a group of actors
- """
- object :group do
- interfaces([:actor])
-
- field(:url, :string, description: "The ActivityPub actor's URL")
- field(:type, :actor_type, description: "The type of Actor (Person, Group,…)")
- field(:name, :string, description: "The actor's displayed name")
- field(:domain, :string, description: "The actor's domain if (null if it's this instance)")
- field(:local, :boolean, description: "If the actor is from this instance")
- field(:summary, :string, description: "The actor's summary")
- field(:preferred_username, :string, description: "The actor's preferred username")
- field(:keys, :string, description: "The actors RSA Keys")
-
- field(:manually_approves_followers, :boolean,
- description: "Whether the actors manually approves followers"
- )
-
- field(:suspended, :boolean, description: "If the actor is suspended")
- field(:avatar_url, :string, description: "The actor's avatar url")
- field(:banner_url, :string, description: "The actor's banner url")
-
- # These one should have a privacy setting
- field(:following, list_of(:follower), description: "List of followings")
- field(:followers, list_of(:follower), description: "List of followers")
- field(:followersCount, :integer, description: "Number of followers for this actor")
- field(:followingCount, :integer, description: "Number of actors following this actor")
-
- # This one should have a privacy setting
- field(:organized_events, list_of(:event),
- resolve: dataloader(Events),
- description: "A list of the events this actor has organized"
- )
-
- field(:types, :group_type, description: "The type of group : Group, Community,…")
-
- field(:openness, :openness,
- description: "Whether the group is opened to all or has restricted access"
- )
-
- field(:members, non_null(list_of(:member)), description: "List of group members")
- end
-
- @desc """
- Describes how an actor is opened to follows
- """
- enum :openness do
- value(:invite_only, description: "The actor can only be followed by invitation")
-
- value(:moderated, description: "The actor needs to accept the following before it's effective")
-
- value(:open, description: "The actor is open to followings")
- end
-
- @desc """
- The types of Group that exist
- """
- enum :group_type do
- value(:group, description: "A private group of persons")
- value(:community, description: "A public group of many actors")
- end
-
- @desc "An ActivityPub actor"
- interface :actor do
- field(:url, :string, description: "The ActivityPub actor's URL")
- field(:type, :actor_type, description: "The type of Actor (Person, Group,…)")
- field(:name, :string, description: "The actor's displayed name")
- field(:domain, :string, description: "The actor's domain if (null if it's this instance)")
- field(:local, :boolean, description: "If the actor is from this instance")
- field(:summary, :string, description: "The actor's summary")
- field(:preferred_username, :string, description: "The actor's preferred username")
- field(:keys, :string, description: "The actors RSA Keys")
-
- field(:manually_approves_followers, :boolean,
- description: "Whether the actors manually approves followers"
- )
-
- field(:suspended, :boolean, description: "If the actor is suspended")
- field(:avatar_url, :string, description: "The actor's avatar url")
- field(:banner_url, :string, description: "The actor's banner url")
-
- # These one should have a privacy setting
- field(:following, list_of(:follower), description: "List of followings")
- field(:followers, list_of(:follower), description: "List of followers")
- field(:followersCount, :integer, description: "Number of followers for this actor")
- field(:followingCount, :integer, description: "Number of actors following this actor")
-
- # This one should have a privacy setting
- field(:organized_events, list_of(:event),
- resolve: dataloader(Events),
- description: "A list of the events this actor has organized"
- )
-
- # This one is for the person itself **only**
- # field(:feed, list_of(:event), description: "List of events the actor sees in his or her feed")
-
- # field(:memberships, list_of(:member))
-
- resolve_type(fn
- %Actor{type: :Person}, _ ->
- :person
-
- %Actor{type: :Group}, _ ->
- :group
- end)
- end
-
- @desc "The list of types an actor can be"
- enum :actor_type do
- value(:Person, description: "An ActivityPub Person")
- value(:Application, description: "An ActivityPub Application")
- value(:Group, description: "An ActivityPub Group")
- value(:Organization, description: "An ActivityPub Organization")
- value(:Service, description: "An ActivityPub Service")
- end
-
- @desc "A local user of Mobilizon"
- object :user do
- field(:id, non_null(:id), description: "The user's ID")
- field(:email, non_null(:string), description: "The user's email")
-
- field(:profiles, non_null(list_of(:person)),
- description: "The user's list of profiles (identities)"
- )
-
- field(:default_actor, non_null(:person), description: "The user's default actor")
-
- field(:confirmed_at, :datetime,
- description: "The datetime when the user was confirmed/activated"
- )
-
- field(:confirmation_sent_at, :datetime,
- description: "The datetime the last activation/confirmation token was sent"
- )
-
- field(:confirmation_token, :string, description: "The account activation/confirmation token")
-
- field(:reset_password_sent_at, :datetime,
- description: "The datetime last reset password email was sent"
- )
-
- field(:reset_password_token, :string,
- description: "The token sent when requesting password token"
- )
- end
-
@desc "A JWT and the associated user ID"
object :login do
field(:token, non_null(:string), description: "A JWT Token for this session")
field(:user, non_null(:user), description: "The user associated to this session")
end
- @desc "An event"
- object :event do
- field(:uuid, :uuid, description: "The Event UUID")
- field(:url, :string, description: "The ActivityPub Event URL")
- field(:local, :boolean, description: "Whether the event is local or not")
- field(:title, :string, description: "The event's title")
- field(:description, :string, description: "The event's description")
- field(:begins_on, :datetime, description: "Datetime for when the event begins")
- field(:ends_on, :datetime, description: "Datetime for when the event ends")
- field(:state, :integer, description: "State of the event")
- field(:status, :integer, description: "Status of the event")
- field(:public, :boolean, description: "Whether the event is public or not")
- # TODO replace me with picture object
- field(:thumbnail, :string, description: "A thumbnail picture for the event")
- # TODO replace me with banner
- field(:large_image, :string, description: "A large picture for the event")
- field(:publish_at, :datetime, description: "When the event was published")
- field(:address_type, :address_type, description: "The type of the event's address")
- # TODO implement these properly with an interface
- # field(:online_address, :string, description: "???")
- # field(:phone, :string, description: "")
-
- field(:organizer_actor, :person,
- resolve: dataloader(Actors),
- description: "The event's organizer (as a person)"
- )
-
- field(:attributed_to, :actor, description: "Who the event is attributed to (often a group)")
- # field(:tags, list_of(:tag))
- field(:category, :category, description: "The event's category")
-
- field(:participants, list_of(:participant),
- resolve: &Resolvers.Event.list_participants_for_event/3,
- description: "The event's participants"
- )
-
- # field(:tracks, list_of(:track))
- # field(:sessions, list_of(:session))
- # field(:physical_address, :address)
-
- field(:updated_at, :datetime, description: "When the event was last updated")
- field(:created_at, :datetime, description: "When the event was created")
- end
-
- @desc "A comment"
- object :comment do
- field(:uuid, :uuid)
- field(:url, :string)
- field(:local, :boolean)
- field(:text, :string)
- field(:primaryLanguage, :string)
- field(:replies, list_of(:comment))
- field(:threadLanguages, non_null(list_of(:string)))
- end
-
- @desc "Represents a participant to an event"
- object :participant do
- field(:event, :event,
- resolve: dataloader(Events),
- description: "The event which the actor participates in"
- )
-
- field(:actor, :actor, description: "The actor that participates to the event")
- field(:role, :integer, description: "The role of this actor at this event")
- end
-
- @desc "The list of types an address can be"
- enum :address_type do
- value(:physical, description: "The address is physical, like a postal address")
- value(:url, description: "The address is on the Web, like an URL")
- value(:phone, description: "The address is a phone number for a conference")
- value(:other, description: "The address is something else")
- end
-
- @desc "A category"
- object :category do
- field(:id, :id, description: "The category's ID")
- field(:description, :string, description: "The category's description")
- field(:picture, :picture, description: "The category's picture")
- field(:title, :string, description: "The category's title")
- end
-
@desc "A picture"
object :picture do
field(:url, :string, description: "The URL for this picture")
@@ -314,28 +51,6 @@ defmodule MobilizonWeb.Schema do
field(:published, :datetime, description: "Datetime when the notification was published")
end
- @desc """
- Represents a member of a group
- """
- object :member do
- field(:parent, :group, description: "Of which the profile is member")
- field(:person, :person, description: "Which profile is member of")
- field(:role, :integer, description: "The role of this membership")
- field(:approved, :boolean, description: "Whether this membership has been approved")
- end
-
- @desc """
- Represents an actor's follower
- """
- object :follower do
- field(:target_actor, :actor, description: "What or who the profile follows")
- field(:actor, :actor, description: "Which profile follows")
-
- field(:approved, :boolean,
- description: "Whether the follow has been approved by the target actor"
- )
- end
-
union :object do
types([:event, :person, :group, :comment, :follower, :member, :participant])
@@ -484,9 +199,8 @@ defmodule MobilizonWeb.Schema do
arg(:thumbnail, :string)
arg(:large_image, :string)
arg(:publish_at, :datetime)
- arg(:address_type, non_null(:address_type))
arg(:online_address, :string)
- arg(:phone, :string)
+ arg(:phone_address, :string)
arg(:organizer_actor_username, non_null(:string))
arg(:category, non_null(:string))
diff --git a/lib/mobilizon_web/schema/actor.ex b/lib/mobilizon_web/schema/actor.ex
new file mode 100644
index 000000000..c3a051094
--- /dev/null
+++ b/lib/mobilizon_web/schema/actor.ex
@@ -0,0 +1,65 @@
+defmodule MobilizonWeb.Schema.ActorInterface do
+ @moduledoc """
+ Schema representation for Actor
+ """
+ use Absinthe.Schema.Notation
+ import Absinthe.Resolution.Helpers, only: [dataloader: 1]
+ alias Mobilizon.Actors.Actor
+
+ import_types(MobilizonWeb.Schema.Actors.FollowerType)
+ import_types(MobilizonWeb.Schema.EventType)
+
+ @desc "An ActivityPub actor"
+ interface :actor do
+ field(:url, :string, description: "The ActivityPub actor's URL")
+ field(:type, :actor_type, description: "The type of Actor (Person, Group,…)")
+ field(:name, :string, description: "The actor's displayed name")
+ field(:domain, :string, description: "The actor's domain if (null if it's this instance)")
+ field(:local, :boolean, description: "If the actor is from this instance")
+ field(:summary, :string, description: "The actor's summary")
+ field(:preferred_username, :string, description: "The actor's preferred username")
+ field(:keys, :string, description: "The actors RSA Keys")
+
+ field(:manually_approves_followers, :boolean,
+ description: "Whether the actors manually approves followers"
+ )
+
+ field(:suspended, :boolean, description: "If the actor is suspended")
+ field(:avatar_url, :string, description: "The actor's avatar url")
+ field(:banner_url, :string, description: "The actor's banner url")
+
+ # These one should have a privacy setting
+ field(:following, list_of(:follower), description: "List of followings")
+ field(:followers, list_of(:follower), description: "List of followers")
+ field(:followersCount, :integer, description: "Number of followers for this actor")
+ field(:followingCount, :integer, description: "Number of actors following this actor")
+
+ # This one should have a privacy setting
+ field(:organized_events, list_of(:event),
+ resolve: dataloader(Events),
+ description: "A list of the events this actor has organized"
+ )
+
+ # This one is for the person itself **only**
+ # field(:feed, list_of(:event), description: "List of events the actor sees in his or her feed")
+
+ # field(:memberships, list_of(:member))
+
+ resolve_type(fn
+ %Actor{type: :Person}, _ ->
+ :person
+
+ %Actor{type: :Group}, _ ->
+ :group
+ end)
+ end
+
+ @desc "The list of types an actor can be"
+ enum :actor_type do
+ value(:Person, description: "An ActivityPub Person")
+ value(:Application, description: "An ActivityPub Application")
+ value(:Group, description: "An ActivityPub Group")
+ value(:Organization, description: "An ActivityPub Organization")
+ value(:Service, description: "An ActivityPub Service")
+ end
+end
diff --git a/lib/mobilizon_web/schema/actors/follower.ex b/lib/mobilizon_web/schema/actors/follower.ex
new file mode 100644
index 000000000..50f3cb3ae
--- /dev/null
+++ b/lib/mobilizon_web/schema/actors/follower.ex
@@ -0,0 +1,18 @@
+defmodule MobilizonWeb.Schema.Actors.FollowerType do
+ @moduledoc """
+ Schema representation for Follower
+ """
+ use Absinthe.Schema.Notation
+
+ @desc """
+ Represents an actor's follower
+ """
+ object :follower do
+ field(:target_actor, :actor, description: "What or who the profile follows")
+ field(:actor, :actor, description: "Which profile follows")
+
+ field(:approved, :boolean,
+ description: "Whether the follow has been approved by the target actor"
+ )
+ end
+end
diff --git a/lib/mobilizon_web/schema/actors/group.ex b/lib/mobilizon_web/schema/actors/group.ex
new file mode 100644
index 000000000..1dab34591
--- /dev/null
+++ b/lib/mobilizon_web/schema/actors/group.ex
@@ -0,0 +1,71 @@
+defmodule MobilizonWeb.Schema.Actors.GroupType do
+ @moduledoc """
+ Schema representation for Group
+ """
+ use Absinthe.Schema.Notation
+ import Absinthe.Resolution.Helpers, only: [dataloader: 1]
+ import_types(MobilizonWeb.Schema.Actors.MemberType)
+
+ @desc """
+ Represents a group of actors
+ """
+ object :group do
+ interfaces([:actor])
+
+ field(:url, :string, description: "The ActivityPub actor's URL")
+ field(:type, :actor_type, description: "The type of Actor (Person, Group,…)")
+ field(:name, :string, description: "The actor's displayed name")
+ field(:domain, :string, description: "The actor's domain if (null if it's this instance)")
+ field(:local, :boolean, description: "If the actor is from this instance")
+ field(:summary, :string, description: "The actor's summary")
+ field(:preferred_username, :string, description: "The actor's preferred username")
+ field(:keys, :string, description: "The actors RSA Keys")
+
+ field(:manually_approves_followers, :boolean,
+ description: "Whether the actors manually approves followers"
+ )
+
+ field(:suspended, :boolean, description: "If the actor is suspended")
+ field(:avatar_url, :string, description: "The actor's avatar url")
+ field(:banner_url, :string, description: "The actor's banner url")
+
+ # These one should have a privacy setting
+ field(:following, list_of(:follower), description: "List of followings")
+ field(:followers, list_of(:follower), description: "List of followers")
+ field(:followersCount, :integer, description: "Number of followers for this actor")
+ field(:followingCount, :integer, description: "Number of actors following this actor")
+
+ # This one should have a privacy setting
+ field(:organized_events, list_of(:event),
+ resolve: dataloader(Events),
+ description: "A list of the events this actor has organized"
+ )
+
+ field(:types, :group_type, description: "The type of group : Group, Community,…")
+
+ field(:openness, :openness,
+ description: "Whether the group is opened to all or has restricted access"
+ )
+
+ field(:members, non_null(list_of(:member)), description: "List of group members")
+ end
+
+ @desc """
+ The types of Group that exist
+ """
+ enum :group_type do
+ value(:group, description: "A private group of persons")
+ value(:community, description: "A public group of many actors")
+ end
+
+ @desc """
+ Describes how an actor is opened to follows
+ """
+ enum :openness do
+ value(:invite_only, description: "The actor can only be followed by invitation")
+
+ value(:moderated, description: "The actor needs to accept the following before it's effective")
+
+ value(:open, description: "The actor is open to followings")
+ end
+end
diff --git a/lib/mobilizon_web/schema/actors/member.ex b/lib/mobilizon_web/schema/actors/member.ex
new file mode 100644
index 000000000..26848f914
--- /dev/null
+++ b/lib/mobilizon_web/schema/actors/member.ex
@@ -0,0 +1,16 @@
+defmodule MobilizonWeb.Schema.Actors.MemberType do
+ @moduledoc """
+ Schema representation for Member
+ """
+ use Absinthe.Schema.Notation
+
+ @desc """
+ Represents a member of a group
+ """
+ object :member do
+ field(:parent, :group, description: "Of which the profile is member")
+ field(:person, :person, description: "Which profile is member of")
+ field(:role, :integer, description: "The role of this membership")
+ field(:approved, :boolean, description: "Whether this membership has been approved")
+ end
+end
diff --git a/lib/mobilizon_web/schema/actors/person.ex b/lib/mobilizon_web/schema/actors/person.ex
new file mode 100644
index 000000000..46b11dece
--- /dev/null
+++ b/lib/mobilizon_web/schema/actors/person.ex
@@ -0,0 +1,47 @@
+defmodule MobilizonWeb.Schema.Actors.PersonType do
+ @moduledoc """
+ Schema representation for Person
+ """
+ use Absinthe.Schema.Notation
+ import Absinthe.Resolution.Helpers, only: [dataloader: 1]
+ import_types(MobilizonWeb.Schema.UserType)
+
+ @desc """
+ Represents a person identity
+ """
+ object :person do
+ interfaces([:actor])
+ field(:user, :user, description: "The user this actor is associated to")
+
+ field(:member_of, list_of(:member), description: "The list of groups this person is member of")
+
+ field(:url, :string, description: "The ActivityPub actor's URL")
+ field(:type, :actor_type, description: "The type of Actor (Person, Group,…)")
+ field(:name, :string, description: "The actor's displayed name")
+ field(:domain, :string, description: "The actor's domain if (null if it's this instance)")
+ field(:local, :boolean, description: "If the actor is from this instance")
+ field(:summary, :string, description: "The actor's summary")
+ field(:preferred_username, :string, description: "The actor's preferred username")
+ field(:keys, :string, description: "The actors RSA Keys")
+
+ field(:manually_approves_followers, :boolean,
+ description: "Whether the actors manually approves followers"
+ )
+
+ field(:suspended, :boolean, description: "If the actor is suspended")
+ field(:avatar_url, :string, description: "The actor's avatar url")
+ field(:banner_url, :string, description: "The actor's banner url")
+
+ # These one should have a privacy setting
+ field(:following, list_of(:follower), description: "List of followings")
+ field(:followers, list_of(:follower), description: "List of followers")
+ field(:followersCount, :integer, description: "Number of followers for this actor")
+ field(:followingCount, :integer, description: "Number of actors following this actor")
+
+ # This one should have a privacy setting
+ field(:organized_events, list_of(:event),
+ resolve: dataloader(Events),
+ description: "A list of the events this actor has organized"
+ )
+ end
+end
diff --git a/lib/mobilizon_web/schema/address.ex b/lib/mobilizon_web/schema/address.ex
new file mode 100644
index 000000000..d3b560a16
--- /dev/null
+++ b/lib/mobilizon_web/schema/address.ex
@@ -0,0 +1,39 @@
+defmodule MobilizonWeb.Schema.AddressType do
+ @moduledoc """
+ Schema representation for Address
+ """
+ use Absinthe.Schema.Notation
+
+ object :physical_address do
+ field(:type, :address_type)
+ field(:geom, :point)
+ field(:floor, :string)
+ field(:streetAddress, :string)
+ field(:addressLocality, :string)
+ field(:postalCode, :string)
+ field(:addressRegion, :string)
+ field(:addressCountry, :string)
+ field(:description, :string)
+ field(:name, :string)
+ end
+
+ object :phone_address do
+ field(:type, :address_type)
+ field(:phone, :string)
+ field(:info, :string)
+ end
+
+ object :online_address do
+ field(:type, :address_type)
+ field(:url, :string)
+ field(:info, :string)
+ end
+
+ @desc "The list of types an address can be"
+ enum :address_type do
+ value(:physical, description: "The address is physical, like a postal address")
+ value(:url, description: "The address is on the Web, like an URL")
+ value(:phone, description: "The address is a phone number for a conference")
+ value(:other, description: "The address is something else")
+ end
+end
diff --git a/lib/mobilizon_web/schema/comment.ex b/lib/mobilizon_web/schema/comment.ex
new file mode 100644
index 000000000..0768ad06e
--- /dev/null
+++ b/lib/mobilizon_web/schema/comment.ex
@@ -0,0 +1,31 @@
+defmodule MobilizonWeb.Schema.CommentType do
+ @moduledoc """
+ Schema representation for Comment
+ """
+ use Absinthe.Schema.Notation
+
+ @desc "A comment"
+ object :comment do
+ field(:uuid, :uuid)
+ field(:url, :string)
+ field(:local, :boolean)
+ field(:visibility, :comment_visibility)
+ field(:text, :string)
+ field(:primaryLanguage, :string)
+ field(:replies, list_of(:comment))
+ field(:threadLanguages, non_null(list_of(:string)))
+ end
+
+ @desc "The list of visibility options for a comment"
+ enum :comment_visibility do
+ value(:public, description: "Publically listed and federated. Can be shared.")
+ value(:unlisted, description: "Visible only to people with the link - or invited")
+
+ value(:private,
+ description: "Visible only to people members of the group or followers of the person"
+ )
+
+ value(:moderated, description: "Visible only after a moderator accepted")
+ value(:invite, description: "visible only to people invited")
+ end
+end
diff --git a/lib/mobilizon_web/schema/custom/point.ex b/lib/mobilizon_web/schema/custom/point.ex
new file mode 100644
index 000000000..7bd3cf974
--- /dev/null
+++ b/lib/mobilizon_web/schema/custom/point.ex
@@ -0,0 +1,38 @@
+defmodule MobilizonWeb.Schema.Custom.Point do
+ @moduledoc """
+ The geom scalar type allows Geo.PostGIS.Geometry strings to be passed in and out.
+ Requires `{:geo, "~> 3.0"},` package: https://github.com/elixir-ecto/ecto
+ """
+ use Absinthe.Schema.Notation
+
+ scalar :point, name: "Point" do
+ description("""
+ The `Point` scalar type represents Point geographic information compliant string data,
+ represented as floats separated by a semi-colon. The geodetic system is WGS 84
+ """)
+
+ serialize(&encode/1)
+ parse(&decode/1)
+ end
+
+ @spec decode(Absinthe.Blueprint.Input.String.t()) :: {:ok, term()} | :error
+ @spec decode(Absinthe.Blueprint.Input.Null.t()) :: {:ok, nil}
+ defp decode(%Absinthe.Blueprint.Input.String{value: value}) do
+ with [_, _] = lonlat <- String.split(value, ";", trim: true),
+ [{lon, ""}, {lat, ""}] <- Enum.map(lonlat, &Float.parse(&1)) do
+ {:ok, %Geo.Point{coordinates: {lon, lat}, srid: 4326}}
+ else
+ _ -> :error
+ end
+ end
+
+ defp decode(%Absinthe.Blueprint.Input.Null{}) do
+ {:ok, nil}
+ end
+
+ defp decode(_) do
+ :error
+ end
+
+ defp encode(%Geo.Point{coordinates: {lon, lat}, srid: 4326}), do: "#{lon};#{lat}"
+end
diff --git a/lib/mobilizon_web/schema/event.ex b/lib/mobilizon_web/schema/event.ex
new file mode 100644
index 000000000..2ff2192c3
--- /dev/null
+++ b/lib/mobilizon_web/schema/event.ex
@@ -0,0 +1,71 @@
+defmodule MobilizonWeb.Schema.EventType do
+ @moduledoc """
+ Schema representation for Event
+ """
+ use Absinthe.Schema.Notation
+ import Absinthe.Resolution.Helpers, only: [dataloader: 1]
+ import_types(MobilizonWeb.Schema.AddressType)
+ import_types(MobilizonWeb.Schema.Events.ParticipantType)
+ import_types(MobilizonWeb.Schema.Events.CategoryType)
+
+ @desc "An event"
+ object :event do
+ field(:uuid, :uuid, description: "The Event UUID")
+ field(:url, :string, description: "The ActivityPub Event URL")
+ field(:local, :boolean, description: "Whether the event is local or not")
+ field(:title, :string, description: "The event's title")
+ field(:description, :string, description: "The event's description")
+ field(:begins_on, :datetime, description: "Datetime for when the event begins")
+ field(:ends_on, :datetime, description: "Datetime for when the event ends")
+ field(:status, :event_status, description: "Status of the event")
+ field(:visibility, :event_visibility, description: "The event's visibility")
+ # TODO replace me with picture object
+ field(:thumbnail, :string, description: "A thumbnail picture for the event")
+ # TODO replace me with banner
+ field(:large_image, :string, description: "A large picture for the event")
+ field(:publish_at, :datetime, description: "When the event was published")
+ field(:physical_address, :physical_address, description: "The type of the event's address")
+ field(:online_address, :online_address, description: "Online address of the event")
+ field(:phone_address, :phone_address, description: "Phone address for the event")
+
+ field(:organizer_actor, :person,
+ resolve: dataloader(Actors),
+ description: "The event's organizer (as a person)"
+ )
+
+ field(:attributed_to, :actor, description: "Who the event is attributed to (often a group)")
+ # field(:tags, list_of(:tag))
+ field(:category, :category, description: "The event's category")
+
+ field(:participants, list_of(:participant),
+ resolve: &MobilizonWeb.Resolvers.Event.list_participants_for_event/3,
+ description: "The event's participants"
+ )
+
+ # field(:tracks, list_of(:track))
+ # field(:sessions, list_of(:session))
+
+ field(:updated_at, :datetime, description: "When the event was last updated")
+ field(:created_at, :datetime, description: "When the event was created")
+ end
+
+ @desc "The list of visibility options for an event"
+ enum :event_visibility do
+ value(:public, description: "Publically listed and federated. Can be shared.")
+ value(:unlisted, description: "Visible only to people with the link - or invited")
+
+ value(:private,
+ description: "Visible only to people members of the group or followers of the person"
+ )
+
+ value(:moderated, description: "Visible only after a moderator accepted")
+ value(:invite, description: "visible only to people invited")
+ end
+
+ @desc "The list of possible options for the event's status"
+ enum :event_status do
+ value(:tentative, description: "The event is tentative")
+ value(:confirmed, description: "The event is confirmed")
+ value(:cancelled, description: "The event is cancelled")
+ end
+end
diff --git a/lib/mobilizon_web/schema/events/category.ex b/lib/mobilizon_web/schema/events/category.ex
new file mode 100644
index 000000000..25e263fe6
--- /dev/null
+++ b/lib/mobilizon_web/schema/events/category.ex
@@ -0,0 +1,14 @@
+defmodule MobilizonWeb.Schema.Events.CategoryType do
+ @moduledoc """
+ Schema representation for Category
+ """
+ use Absinthe.Schema.Notation
+
+ @desc "A category"
+ object :category do
+ field(:id, :id, description: "The category's ID")
+ field(:description, :string, description: "The category's description")
+ field(:picture, :picture, description: "The category's picture")
+ field(:title, :string, description: "The category's title")
+ end
+end
diff --git a/lib/mobilizon_web/schema/events/participant.ex b/lib/mobilizon_web/schema/events/participant.ex
new file mode 100644
index 000000000..47a6b36b9
--- /dev/null
+++ b/lib/mobilizon_web/schema/events/participant.ex
@@ -0,0 +1,18 @@
+defmodule MobilizonWeb.Schema.Events.ParticipantType do
+ @moduledoc """
+ Schema representation for Participant
+ """
+ use Absinthe.Schema.Notation
+ import Absinthe.Resolution.Helpers, only: [dataloader: 1]
+
+ @desc "Represents a participant to an event"
+ object :participant do
+ field(:event, :event,
+ resolve: dataloader(Events),
+ description: "The event which the actor participates in"
+ )
+
+ field(:actor, :actor, description: "The actor that participates to the event")
+ field(:role, :integer, description: "The role of this actor at this event")
+ end
+end
diff --git a/lib/mobilizon_web/schema/user.ex b/lib/mobilizon_web/schema/user.ex
new file mode 100644
index 000000000..b1106de93
--- /dev/null
+++ b/lib/mobilizon_web/schema/user.ex
@@ -0,0 +1,36 @@
+defmodule MobilizonWeb.Schema.UserType do
+ @moduledoc """
+ Schema representation for User
+ """
+ use Absinthe.Schema.Notation
+
+ @desc "A local user of Mobilizon"
+ object :user do
+ field(:id, non_null(:id), description: "The user's ID")
+ field(:email, non_null(:string), description: "The user's email")
+
+ field(:profiles, non_null(list_of(:person)),
+ description: "The user's list of profiles (identities)"
+ )
+
+ field(:default_actor, non_null(:person), description: "The user's default actor")
+
+ field(:confirmed_at, :datetime,
+ description: "The datetime when the user was confirmed/activated"
+ )
+
+ field(:confirmation_sent_at, :datetime,
+ description: "The datetime the last activation/confirmation token was sent"
+ )
+
+ field(:confirmation_token, :string, description: "The account activation/confirmation token")
+
+ field(:reset_password_sent_at, :datetime,
+ description: "The datetime last reset password email was sent"
+ )
+
+ field(:reset_password_token, :string,
+ description: "The token sent when requesting password token"
+ )
+ end
+end
diff --git a/priv/repo/migrations/20180702150922_add_address_type.exs b/priv/repo/migrations/20180702150922_add_address_type.exs
index d9085e08d..253ede470 100644
--- a/priv/repo/migrations/20180702150922_add_address_type.exs
+++ b/priv/repo/migrations/20180702150922_add_address_type.exs
@@ -2,9 +2,7 @@ defmodule Mobilizon.Repo.Migrations.AddAddressType do
use Ecto.Migration
def up do
- Mobilizon.Events.AddressTypeEnum.create_type
alter table(:events) do
- add :address_type, :address_type
add :online_address, :string
add :phone, :string
end
@@ -17,11 +15,9 @@ defmodule Mobilizon.Repo.Migrations.AddAddressType do
def down do
alter table(:events) do
- remove :address_type
remove :online_address
remove :phone
end
- Mobilizon.Events.AddressTypeEnum.drop_type
drop constraint(:events, "events_physical_address_id_fkey")
rename table(:events), :physical_address_id, to: :address_id
alter table(:events) do
diff --git a/priv/repo/migrations/20190114162055_remove_address_type.exs b/priv/repo/migrations/20190114162055_remove_address_type.exs
new file mode 100644
index 000000000..74b73b7a3
--- /dev/null
+++ b/priv/repo/migrations/20190114162055_remove_address_type.exs
@@ -0,0 +1,10 @@
+defmodule Mobilizon.Repo.Migrations.RemoveAddressType do
+ use Ecto.Migration
+ require Logger
+
+ def up do
+ execute "DROP TYPE IF EXISTS address_type"
+ execute "ALTER TABLE \"events\" DROP COLUMN IF EXISTS address_type"
+ rename table(:events), :phone, to: :phone_address
+ end
+end
diff --git a/test/mobilizon_web/resolvers/event_resolver_test.exs b/test/mobilizon_web/resolvers/event_resolver_test.exs
index e82a1e10b..80a3ad207 100644
--- a/test/mobilizon_web/resolvers/event_resolver_test.exs
+++ b/test/mobilizon_web/resolvers/event_resolver_test.exs
@@ -118,8 +118,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
description: "it will be fine",
begins_on: "#{DateTime.utc_now() |> DateTime.to_iso8601()}",
organizer_actor_username: "#{actor.preferred_username}",
- category: "#{category.title}",
- address_type: #{"OTHER"}
+ category: "#{category.title}"
) {
title,
uuid