forked from potsda.mn/mobilizon
Merge branch 'api/add-address' into 'master'
Remove address_type See merge request framasoft/mobilizon!47
This commit is contained in:
commit
7709c2c566
|
@ -8,14 +8,8 @@
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-form>
|
<v-form>
|
||||||
<v-text-field
|
<v-text-field label="Title" v-model="event.title" :counter="100" required></v-text-field>
|
||||||
label="Title"
|
<v-date-picker v-model="event.begins_on"></v-date-picker>
|
||||||
v-model="event.title"
|
|
||||||
:counter="100"
|
|
||||||
required
|
|
||||||
></v-text-field>
|
|
||||||
<v-date-picker v-model="event.begins_on">
|
|
||||||
</v-date-picker>
|
|
||||||
<v-radio-group v-model="event.location_type" row>
|
<v-radio-group v-model="event.location_type" row>
|
||||||
<v-radio label="Address" value="physical" off-icon="place"></v-radio>
|
<v-radio label="Address" value="physical" off-icon="place"></v-radio>
|
||||||
<v-radio label="Online" value="online" off-icon="link"></v-radio>
|
<v-radio label="Online" value="online" off-icon="link"></v-radio>
|
||||||
|
@ -54,8 +48,7 @@
|
||||||
item-text="title"
|
item-text="title"
|
||||||
item-value="id"
|
item-value="id"
|
||||||
label="Categories"
|
label="Categories"
|
||||||
>
|
></v-autocomplete>
|
||||||
</v-autocomplete>
|
|
||||||
<v-btn color="primary" @click="create">Create event</v-btn>
|
<v-btn color="primary" @click="create">Create event</v-btn>
|
||||||
</v-form>
|
</v-form>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
@ -67,11 +60,11 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// import Location from '@/components/Location';
|
// import Location from '@/components/Location';
|
||||||
import VueMarkdown from 'vue-markdown';
|
import VueMarkdown from "vue-markdown";
|
||||||
import { CREATE_EVENT, EDIT_EVENT } from '@/graphql/event';
|
import { CREATE_EVENT, EDIT_EVENT } from "@/graphql/event";
|
||||||
import { FETCH_CATEGORIES } from '@/graphql/category';
|
import { FETCH_CATEGORIES } from "@/graphql/category";
|
||||||
import { AUTH_USER_ACTOR } from '@/constants';
|
import { AUTH_USER_ACTOR } from "@/constants";
|
||||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
import { Component, Prop, Vue } from "vue-property-decorator";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
|
@ -79,36 +72,36 @@
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
categories: {
|
categories: {
|
||||||
query: FETCH_CATEGORIES,
|
query: FETCH_CATEGORIES
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export default class CreateEvent extends Vue {
|
export default class CreateEvent extends Vue {
|
||||||
@Prop({required: false, type: String}) uuid!: string
|
@Prop({ required: false, type: String }) uuid!: string;
|
||||||
|
|
||||||
e1 = 0
|
e1 = 0;
|
||||||
event = {
|
event = {
|
||||||
title: null,
|
title: null,
|
||||||
organizer_actor_id: null,
|
organizer_actor_id: null,
|
||||||
description: '',
|
description: "",
|
||||||
begins_on: (new Date()).toISOString().substr(0, 10),
|
begins_on: new Date().toISOString().substr(0, 10),
|
||||||
ends_on: new Date(),
|
ends_on: new Date(),
|
||||||
seats: null,
|
seats: null,
|
||||||
physical_address: null,
|
physical_address: null,
|
||||||
location_type: 'physical',
|
location_type: "physical",
|
||||||
online_address: null,
|
online_address: null,
|
||||||
tel_num: null,
|
tel_num: null,
|
||||||
price: null,
|
price: null,
|
||||||
category: null,
|
category: null,
|
||||||
category_id: null,
|
category_id: null,
|
||||||
tags: [],
|
tags: [],
|
||||||
participants: [],
|
participants: []
|
||||||
} as any // FIXME: correctly type an event
|
} as any; // FIXME: correctly type an event
|
||||||
categories = []
|
categories = [];
|
||||||
tags = []
|
tags = [];
|
||||||
tagsToSend = []
|
tagsToSend = [];
|
||||||
tagsFetched = []
|
tagsFetched = [];
|
||||||
loading = false
|
loading = false;
|
||||||
|
|
||||||
// created() {
|
// created() {
|
||||||
// if (this.uuid) {
|
// if (this.uuid) {
|
||||||
|
@ -125,40 +118,51 @@
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
// FIXME: correctly parse actor JSON
|
// FIXME: correctly parse actor JSON
|
||||||
const actor = JSON.parse(localStorage.getItem(AUTH_USER_ACTOR) || '{}')
|
const actor = JSON.parse(localStorage.getItem(AUTH_USER_ACTOR) || "{}");
|
||||||
this.event.category_id = this.event.category
|
this.event.category_id = this.event.category;
|
||||||
this.event.organizer_actor_id = actor.id
|
this.event.organizer_actor_id = actor.id;
|
||||||
this.event.participants = [actor.id]
|
this.event.participants = [actor.id];
|
||||||
// this.event.price = parseFloat(this.event.price);
|
// this.event.price = parseFloat(this.event.price);
|
||||||
|
|
||||||
if (this.uuid === undefined) {
|
if (this.uuid === undefined) {
|
||||||
this.$apollo.mutate({
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
mutation: CREATE_EVENT,
|
mutation: CREATE_EVENT,
|
||||||
variables: {
|
variables: {
|
||||||
title: this.event.title,
|
title: this.event.title,
|
||||||
description: this.event.description,
|
description: this.event.description,
|
||||||
organizerActorId: this.event.organizer_actor_id,
|
organizerActorId: this.event.organizer_actor_id,
|
||||||
categoryId: this.event.category_id,
|
categoryId: this.event.category_id,
|
||||||
beginsOn: this.event.begins_on,
|
beginsOn: this.event.begins_on
|
||||||
addressType: this.event.location_type,
|
|
||||||
}
|
}
|
||||||
}).then((data) => {
|
|
||||||
this.loading = false
|
|
||||||
this.$router.push({name: 'Event', params: {uuid: data.data.uuid}})
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
})
|
})
|
||||||
|
.then(data => {
|
||||||
|
this.loading = false;
|
||||||
|
this.$router.push({
|
||||||
|
name: "Event",
|
||||||
|
params: { uuid: data.data.uuid }
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.$apollo.mutate({
|
this.$apollo
|
||||||
mutation: EDIT_EVENT,
|
.mutate({
|
||||||
}).then((data) => {
|
mutation: EDIT_EVENT
|
||||||
this.loading = false
|
|
||||||
this.$router.push({name: 'Event', params: {uuid: data.data.uuid}})
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
})
|
})
|
||||||
|
.then(data => {
|
||||||
|
this.loading = false;
|
||||||
|
this.$router.push({
|
||||||
|
name: "Event",
|
||||||
|
params: { uuid: data.data.uuid }
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.event.tags = []
|
this.event.tags = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getAddressData(addressData) {
|
getAddressData(addressData) {
|
||||||
|
@ -167,20 +171,19 @@
|
||||||
geom: {
|
geom: {
|
||||||
data: {
|
data: {
|
||||||
latitude: addressData.latitude,
|
latitude: addressData.latitude,
|
||||||
longitude: addressData.longitude,
|
longitude: addressData.longitude
|
||||||
},
|
},
|
||||||
type: 'point',
|
type: "point"
|
||||||
},
|
},
|
||||||
addressCountry: addressData.country,
|
addressCountry: addressData.country,
|
||||||
addressLocality: addressData.locality,
|
addressLocality: addressData.locality,
|
||||||
addressRegion: addressData.administrative_area_level_1,
|
addressRegion: addressData.administrative_area_level_1,
|
||||||
postalCode: addressData.postal_code,
|
postalCode: addressData.postal_code,
|
||||||
streetAddress: `${addressData.street_number} ${addressData.route}`,
|
streetAddress: `${addressData.street_number} ${addressData.route}`
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -105,9 +105,9 @@
|
||||||
</v-list-tile-action>
|
</v-list-tile-action>
|
||||||
|
|
||||||
<v-list-tile-content>
|
<v-list-tile-content>
|
||||||
<v-list-tile-title><span v-if="event.address_type === 'physical'">
|
<v-list-tile-title>
|
||||||
{{ event.physical_address.streetAddress }}
|
{{ event.physical_address.streetAddress }}
|
||||||
</span></v-list-tile-title>
|
</v-list-tile-title>
|
||||||
<v-list-tile-sub-title>Mobile</v-list-tile-sub-title>
|
<v-list-tile-sub-title>Mobile</v-list-tile-sub-title>
|
||||||
</v-list-tile-content>
|
</v-list-tile-content>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
|
|
|
@ -12,13 +12,12 @@ export const FETCH_EVENT = gql`
|
||||||
ends_on,
|
ends_on,
|
||||||
state,
|
state,
|
||||||
status,
|
status,
|
||||||
public,
|
visibility,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
large_image,
|
large_image,
|
||||||
publish_at,
|
publish_at,
|
||||||
# address_type,
|
|
||||||
# online_address,
|
# online_address,
|
||||||
# phone,
|
# phone_address,
|
||||||
organizerActor {
|
organizerActor {
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
preferredUsername,
|
preferredUsername,
|
||||||
|
@ -56,13 +55,12 @@ export const FETCH_EVENTS = gql`
|
||||||
ends_on,
|
ends_on,
|
||||||
state,
|
state,
|
||||||
status,
|
status,
|
||||||
public,
|
visibility,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
large_image,
|
large_image,
|
||||||
publish_at,
|
publish_at,
|
||||||
# address_type,
|
|
||||||
# online_address,
|
# online_address,
|
||||||
# phone,
|
# phone_address,
|
||||||
organizerActor {
|
organizerActor {
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
preferredUsername,
|
preferredUsername,
|
||||||
|
@ -87,19 +85,13 @@ export const CREATE_EVENT = gql`
|
||||||
$organizerActorId: Int!,
|
$organizerActorId: Int!,
|
||||||
$categoryId: Int!,
|
$categoryId: Int!,
|
||||||
$beginsOn: DateTime!,
|
$beginsOn: DateTime!,
|
||||||
$addressType: AddressType!,
|
|
||||||
) {
|
) {
|
||||||
createEvent(
|
createEvent(
|
||||||
title: $title,
|
title: $title,
|
||||||
description: $description,
|
description: $description,
|
||||||
beginsOn: $beginsOn,
|
beginsOn: $beginsOn,
|
||||||
organizerActorId: $organizerActorId,
|
organizerActorId: $organizerActorId,
|
||||||
categoryId: $categoryId,
|
categoryId: $categoryId
|
||||||
addressType: $addressType) {
|
|
||||||
uuid,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import EctoEnum
|
import EctoEnum
|
||||||
defenum(Mobilizon.Events.AddressTypeEnum, :address_type, [:physical, :url, :phone, :other])
|
|
||||||
|
|
||||||
defenum(Mobilizon.Events.EventVisibilityEnum, :event_visibility_type, [
|
defenum(Mobilizon.Events.EventVisibilityEnum, :event_visibility_type, [
|
||||||
:public,
|
:public,
|
||||||
|
@ -38,9 +37,8 @@ defmodule Mobilizon.Events.Event do
|
||||||
field(:large_image, :string)
|
field(:large_image, :string)
|
||||||
field(:publish_at, Timex.Ecto.DateTimeWithTimezone)
|
field(:publish_at, Timex.Ecto.DateTimeWithTimezone)
|
||||||
field(:uuid, Ecto.UUID, default: Ecto.UUID.generate())
|
field(:uuid, Ecto.UUID, default: Ecto.UUID.generate())
|
||||||
field(:address_type, Mobilizon.Events.AddressTypeEnum, default: :physical)
|
|
||||||
field(:online_address, :string)
|
field(:online_address, :string)
|
||||||
field(:phone, :string)
|
field(:phone_address, :string)
|
||||||
belongs_to(:organizer_actor, Actor, foreign_key: :organizer_actor_id)
|
belongs_to(:organizer_actor, Actor, foreign_key: :organizer_actor_id)
|
||||||
belongs_to(:attributed_to, Actor, foreign_key: :attributed_to_id)
|
belongs_to(:attributed_to, Actor, foreign_key: :attributed_to_id)
|
||||||
many_to_many(:tags, Tag, join_through: "events_tags")
|
many_to_many(:tags, Tag, join_through: "events_tags")
|
||||||
|
@ -69,9 +67,8 @@ defmodule Mobilizon.Events.Event do
|
||||||
:thumbnail,
|
:thumbnail,
|
||||||
:large_image,
|
:large_image,
|
||||||
:publish_at,
|
:publish_at,
|
||||||
:address_type,
|
|
||||||
:online_address,
|
:online_address,
|
||||||
:phone
|
:phone_address
|
||||||
])
|
])
|
||||||
|> cast_assoc(:tags)
|
|> cast_assoc(:tags)
|
||||||
|> cast_assoc(:physical_address)
|
|> cast_assoc(:physical_address)
|
||||||
|
@ -82,8 +79,7 @@ defmodule Mobilizon.Events.Event do
|
||||||
:organizer_actor_id,
|
:organizer_actor_id,
|
||||||
:category_id,
|
:category_id,
|
||||||
:url,
|
:url,
|
||||||
:uuid,
|
:uuid
|
||||||
:address_type
|
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,291 +4,28 @@ defmodule MobilizonWeb.Schema do
|
||||||
"""
|
"""
|
||||||
use Absinthe.Schema
|
use Absinthe.Schema
|
||||||
|
|
||||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
|
||||||
alias Mobilizon.{Actors, Events}
|
alias Mobilizon.{Actors, Events}
|
||||||
alias Mobilizon.Actors.{Actor, Follower, Member}
|
alias Mobilizon.Actors.{Actor, Follower, Member}
|
||||||
alias Mobilizon.Events.{Event, Comment, Participant}
|
alias Mobilizon.Events.{Event, Comment, Participant}
|
||||||
|
|
||||||
import_types(MobilizonWeb.Schema.Custom.UUID)
|
import_types(MobilizonWeb.Schema.Custom.UUID)
|
||||||
|
import_types(MobilizonWeb.Schema.Custom.Point)
|
||||||
import_types(Absinthe.Type.Custom)
|
import_types(Absinthe.Type.Custom)
|
||||||
import_types(Absinthe.Plug.Types)
|
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
|
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"
|
@desc "A JWT and the associated user ID"
|
||||||
object :login do
|
object :login do
|
||||||
field(:token, non_null(:string), description: "A JWT Token for this session")
|
field(:token, non_null(:string), description: "A JWT Token for this session")
|
||||||
field(:user, non_null(:user), description: "The user associated to this session")
|
field(:user, non_null(:user), description: "The user associated to this session")
|
||||||
end
|
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"
|
@desc "A picture"
|
||||||
object :picture do
|
object :picture do
|
||||||
field(:url, :string, description: "The URL for this picture")
|
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")
|
field(:published, :datetime, description: "Datetime when the notification was published")
|
||||||
end
|
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
|
union :object do
|
||||||
types([:event, :person, :group, :comment, :follower, :member, :participant])
|
types([:event, :person, :group, :comment, :follower, :member, :participant])
|
||||||
|
|
||||||
|
@ -484,9 +199,8 @@ defmodule MobilizonWeb.Schema do
|
||||||
arg(:thumbnail, :string)
|
arg(:thumbnail, :string)
|
||||||
arg(:large_image, :string)
|
arg(:large_image, :string)
|
||||||
arg(:publish_at, :datetime)
|
arg(:publish_at, :datetime)
|
||||||
arg(:address_type, non_null(:address_type))
|
|
||||||
arg(:online_address, :string)
|
arg(:online_address, :string)
|
||||||
arg(:phone, :string)
|
arg(:phone_address, :string)
|
||||||
arg(:organizer_actor_username, non_null(:string))
|
arg(:organizer_actor_username, non_null(:string))
|
||||||
arg(:category, non_null(:string))
|
arg(:category, non_null(:string))
|
||||||
|
|
||||||
|
|
65
lib/mobilizon_web/schema/actor.ex
Normal file
65
lib/mobilizon_web/schema/actor.ex
Normal file
|
@ -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
|
18
lib/mobilizon_web/schema/actors/follower.ex
Normal file
18
lib/mobilizon_web/schema/actors/follower.ex
Normal file
|
@ -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
|
71
lib/mobilizon_web/schema/actors/group.ex
Normal file
71
lib/mobilizon_web/schema/actors/group.ex
Normal file
|
@ -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
|
16
lib/mobilizon_web/schema/actors/member.ex
Normal file
16
lib/mobilizon_web/schema/actors/member.ex
Normal file
|
@ -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
|
47
lib/mobilizon_web/schema/actors/person.ex
Normal file
47
lib/mobilizon_web/schema/actors/person.ex
Normal file
|
@ -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
|
39
lib/mobilizon_web/schema/address.ex
Normal file
39
lib/mobilizon_web/schema/address.ex
Normal file
|
@ -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
|
31
lib/mobilizon_web/schema/comment.ex
Normal file
31
lib/mobilizon_web/schema/comment.ex
Normal file
|
@ -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
|
38
lib/mobilizon_web/schema/custom/point.ex
Normal file
38
lib/mobilizon_web/schema/custom/point.ex
Normal file
|
@ -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
|
71
lib/mobilizon_web/schema/event.ex
Normal file
71
lib/mobilizon_web/schema/event.ex
Normal file
|
@ -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
|
14
lib/mobilizon_web/schema/events/category.ex
Normal file
14
lib/mobilizon_web/schema/events/category.ex
Normal file
|
@ -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
|
18
lib/mobilizon_web/schema/events/participant.ex
Normal file
18
lib/mobilizon_web/schema/events/participant.ex
Normal file
|
@ -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
|
36
lib/mobilizon_web/schema/user.ex
Normal file
36
lib/mobilizon_web/schema/user.ex
Normal file
|
@ -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
|
|
@ -2,9 +2,7 @@ defmodule Mobilizon.Repo.Migrations.AddAddressType do
|
||||||
use Ecto.Migration
|
use Ecto.Migration
|
||||||
|
|
||||||
def up do
|
def up do
|
||||||
Mobilizon.Events.AddressTypeEnum.create_type
|
|
||||||
alter table(:events) do
|
alter table(:events) do
|
||||||
add :address_type, :address_type
|
|
||||||
add :online_address, :string
|
add :online_address, :string
|
||||||
add :phone, :string
|
add :phone, :string
|
||||||
end
|
end
|
||||||
|
@ -17,11 +15,9 @@ defmodule Mobilizon.Repo.Migrations.AddAddressType do
|
||||||
|
|
||||||
def down do
|
def down do
|
||||||
alter table(:events) do
|
alter table(:events) do
|
||||||
remove :address_type
|
|
||||||
remove :online_address
|
remove :online_address
|
||||||
remove :phone
|
remove :phone
|
||||||
end
|
end
|
||||||
Mobilizon.Events.AddressTypeEnum.drop_type
|
|
||||||
drop constraint(:events, "events_physical_address_id_fkey")
|
drop constraint(:events, "events_physical_address_id_fkey")
|
||||||
rename table(:events), :physical_address_id, to: :address_id
|
rename table(:events), :physical_address_id, to: :address_id
|
||||||
alter table(:events) do
|
alter table(:events) do
|
||||||
|
|
10
priv/repo/migrations/20190114162055_remove_address_type.exs
Normal file
10
priv/repo/migrations/20190114162055_remove_address_type.exs
Normal file
|
@ -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
|
|
@ -118,8 +118,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
|
||||||
description: "it will be fine",
|
description: "it will be fine",
|
||||||
begins_on: "#{DateTime.utc_now() |> DateTime.to_iso8601()}",
|
begins_on: "#{DateTime.utc_now() |> DateTime.to_iso8601()}",
|
||||||
organizer_actor_username: "#{actor.preferred_username}",
|
organizer_actor_username: "#{actor.preferred_username}",
|
||||||
category: "#{category.title}",
|
category: "#{category.title}"
|
||||||
address_type: #{"OTHER"}
|
|
||||||
) {
|
) {
|
||||||
title,
|
title,
|
||||||
uuid
|
uuid
|
||||||
|
|
Loading…
Reference in a new issue