Introduce group posts

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
master
Thomas Citharel 2 years ago
parent bec1c69d4b
commit 9c9f1385fb
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
  1. 2
      config/config.exs
  2. 5
      config/test.exs
  3. 4
      js/package.json
  4. 2
      js/src/App.vue
  5. 2
      js/src/components/Comment/Comment.vue
  6. 8
      js/src/components/Discussion/DiscussionComment.vue
  7. 29
      js/src/components/Discussion/DiscussionListItem.vue
  8. 1
      js/src/components/Event/EventListCard.vue
  9. 5
      js/src/components/Event/ShareEventModal.vue
  10. 6
      js/src/components/Group/InvitationCard.vue
  11. 1
      js/src/components/Logo.vue
  12. 48
      js/src/components/Post/PostListItem.vue
  13. 4
      js/src/components/Resource/FolderItem.vue
  14. 2
      js/src/components/Resource/ResourceItem.vue
  15. 1
      js/src/components/Resource/ResourceSelector.vue
  16. 1
      js/src/components/Settings/SettingMenuItem.vue
  17. 2
      js/src/components/Settings/SettingMenuSection.vue
  18. 1
      js/src/components/Settings/SettingsMenu.vue
  19. 1
      js/src/components/Todo/FullTodo.vue
  20. 41
      js/src/graphql/actor.ts
  21. 120
      js/src/graphql/conversation.ts
  22. 158
      js/src/graphql/discussion.ts
  23. 28
      js/src/graphql/member.ts
  24. 151
      js/src/graphql/post.ts
  25. 9
      js/src/graphql/tags.ts
  26. 4
      js/src/i18n/ar.json
  27. 2
      js/src/i18n/be.json
  28. 2
      js/src/i18n/ca.json
  29. 2
      js/src/i18n/de.json
  30. 8
      js/src/i18n/en_US.json
  31. 10
      js/src/i18n/es.json
  32. 10
      js/src/i18n/fi.json
  33. 8
      js/src/i18n/fr_FR.json
  34. 8
      js/src/i18n/oc.json
  35. 2
      js/src/i18n/pt_BR.json
  36. 14
      js/src/main.ts
  37. 34
      js/src/router/conversation.ts
  38. 34
      js/src/router/discussion.ts
  39. 31
      js/src/router/groups.ts
  40. 4
      js/src/router/index.ts
  41. 4
      js/src/router/name.ts
  42. 11
      js/src/types/actor/group.model.ts
  43. 12
      js/src/types/comment.model.ts
  44. 13
      js/src/types/conversations.ts
  45. 44
      js/src/types/discussions.ts
  46. 26
      js/src/types/post.model.ts
  47. 2
      js/src/utils/i18n.ts
  48. 4
      js/src/views/About/AboutInstance.vue
  49. 3
      js/src/views/Admin/AdminProfile.vue
  50. 2
      js/src/views/Admin/AdminUserProfile.vue
  51. 6
      js/src/views/Admin/Profiles.vue
  52. 1
      js/src/views/Admin/Settings.vue
  53. 2
      js/src/views/Admin/Users.vue
  54. 243
      js/src/views/Conversations/Conversation.vue
  55. 37
      js/src/views/Discussions/Create.vue
  56. 350
      js/src/views/Discussions/Discussion.vue
  57. 29
      js/src/views/Discussions/DiscussionsList.vue
  58. 6
      js/src/views/Event/Event.vue
  59. 2
      js/src/views/Event/MyEvents.vue
  60. 12
      js/src/views/Event/Participants.vue
  61. 245
      js/src/views/Group/Group.vue
  62. 183
      js/src/views/Group/GroupMembers.vue
  63. 91
      js/src/views/Group/GroupSettings.vue
  64. 16
      js/src/views/Group/MyGroups.vue
  65. 2
      js/src/views/Moderation/Report.vue
  66. 217
      js/src/views/Posts/Edit.vue
  67. 86
      js/src/views/Posts/List.vue
  68. 184
      js/src/views/Posts/Post.vue
  69. 6
      js/src/views/Resources/ResourceFolder.vue
  70. 1373
      js/yarn.lock
  71. 799
      lib/federation/activity_pub/activity_pub.ex
  72. 32
      lib/federation/activity_pub/audience.ex
  73. 74
      lib/federation/activity_pub/fetcher.ex
  74. 30
      lib/federation/activity_pub/preloader.ex
  75. 100
      lib/federation/activity_pub/refresher.ex
  76. 239
      lib/federation/activity_pub/transmogrifier.ex
  77. 74
      lib/federation/activity_pub/types/actors.ex
  78. 149
      lib/federation/activity_pub/types/comments.ex
  79. 115
      lib/federation/activity_pub/types/discussions.ex
  80. 151
      lib/federation/activity_pub/types/entity.ex
  81. 203
      lib/federation/activity_pub/types/events.ex
  82. 93
      lib/federation/activity_pub/types/posts.ex
  83. 43
      lib/federation/activity_pub/types/reports.ex
  84. 157
      lib/federation/activity_pub/types/resources.ex
  85. 69
      lib/federation/activity_pub/types/todo_lists.ex
  86. 80
      lib/federation/activity_pub/types/todos.ex
  87. 14
      lib/federation/activity_pub/types/tombstones.ex
  88. 121
      lib/federation/activity_pub/utils.ex
  89. 2
      lib/federation/activity_pub/visibility.ex
  90. 7
      lib/federation/activity_stream.ex
  91. 11
      lib/federation/activity_stream/converter/actor.ex
  92. 156
      lib/federation/activity_stream/converter/comment.ex
  93. 6
      lib/federation/activity_stream/converter/converter.ex
  94. 63
      lib/federation/activity_stream/converter/discussion.ex
  95. 29
      lib/federation/activity_stream/converter/event.ex
  96. 4
      lib/federation/activity_stream/converter/flag.ex
  97. 2
      lib/federation/activity_stream/converter/picture.ex
  98. 70
      lib/federation/activity_stream/converter/post.ex
  99. 2
      lib/federation/activity_stream/converter/todo_list.ex
  100. 1
      lib/federation/activity_stream/converter/tombstone.ex
  101. Some files were not shown because too many files have changed in this diff Show More

@ -163,6 +163,8 @@ config :auto_linker,
rel: "noopener noreferrer ugc"
]
config :tesla, adapter: Tesla.Adapter.Hackney
config :phoenix, :format_encoders, json: Jason, "activity-json": Jason
config :phoenix, :json_library, Jason

@ -44,6 +44,11 @@ config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "test/uploads"
config :exvcr,
vcr_cassette_library_dir: "test/fixtures/vcr_cassettes"
config :tesla, Mobilizon.Service.HTTP.ActivityPub,
adapter: Mobilizon.Service.HTTP.ActivityPub.Mock
config :tesla, Mobilizon.Service.HTTP.BaseClient, adapter: Mobilizon.Service.HTTP.BaseClient.Mock
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Mock
config :mobilizon, Oban, queues: false, prune: :disabled, crontab: false

@ -49,7 +49,7 @@
"vue-router": "^3.1.6",
"vue-scrollto": "^2.17.1",
"vue2-leaflet": "^2.0.3",
"vuedraggable": "^2.23.2"
"vuedraggable": "2.23.2"
},
"devDependencies": {
"@types/chai": "^4.2.11",
@ -90,7 +90,7 @@
"prettier-eslint": "^10.1.1",
"sass-loader": "^8.0.2",
"typescript": "~3.9.3",
"vue-cli-plugin-styleguidist": "~4.26.0",
"vue-cli-plugin-styleguidist": "~4.29.1",
"vue-cli-plugin-svg": "~0.1.3",
"vue-i18n-extract": "^1.0.2",
"vue-template-compiler": "^2.6.11",

@ -59,6 +59,7 @@ import { initializeCurrentActor } from "./utils/auth";
import { CONFIG } from "./graphql/config";
import { IConfig } from "./types/config.model";
import { ICurrentUser } from "./types/current-user.model";
@Component({
apollo: {
currentUser: CURRENT_USER_CLIENT,
@ -72,6 +73,7 @@ import { ICurrentUser } from "./types/current-user.model";
})
export default class App extends Vue {
config!: IConfig;
currentUser!: ICurrentUser;
async created() {

@ -138,7 +138,7 @@ import { IEvent, CommentModeration } from "../../types/event.model";
import ReportModal from "../Report/ReportModal.vue";
import { IReport } from "../../types/report.model";
import { CREATE_REPORT } from "../../graphql/report";
import PopoverActorCard from "../../components/Account/PopoverActorCard.vue";
import PopoverActorCard from "../Account/PopoverActorCard.vue";
@Component({
apollo: {

@ -12,7 +12,9 @@
<span>@{{ comment.actor.preferredUsername }}</span>
</div>
<div class="post-infos">
<span>{{ comment.updatedAt | formatDateTimeString }}</span>
<span :title="comment.insertedAt | formatDateTimeString">
{{ $timeAgo.format(comment.insertedAt, "twitter") || $t("Right now") }}</span
>
</div>
</div>
<div class="description-content" v-html="comment.text"></div>
@ -21,10 +23,10 @@
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { IComment } from "../../types/comment.model";
import { IComment, CommentModel } from "../../types/comment.model";
@Component
export default class ConversationComment extends Vue {
export default class DiscussionComment extends Vue {
@Prop({ required: true, type: Object }) comment!: IComment;
}
</script>

@ -1,42 +1,45 @@
<template>
<router-link
class="conversation-minimalist-card-wrapper"
:to="{ name: RouteName.CONVERSATION, params: { slug: conversation.slug, id: conversation.id } }"
class="discussion-minimalist-card-wrapper"
:to="{ name: RouteName.DISCUSSION, params: { slug: discussion.slug, id: discussion.id } }"
>
<div class="media-left">
<figure class="image is-32x32" v-if="conversation.lastComment.actor.avatar">
<img class="is-rounded" :src="conversation.lastComment.actor.avatar.url" alt />
<figure class="image is-32x32" v-if="discussion.lastComment.actor.avatar">
<img class="is-rounded" :src="discussion.lastComment.actor.avatar.url" alt />
</figure>
<b-icon v-else size="is-medium" icon="account-circle" />
</div>
<div class="title-info-wrapper">
<p class="conversation-minimalist-title">{{ conversation.title }}</p>
<p class="discussion-minimalist-title">{{ discussion.title }}</p>
<div class="has-text-grey">{{ htmlTextEllipsis }}</div>
</div>
</router-link>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { IConversation } from "../../types/conversations";
import { IDiscussion } from "../../types/discussions";
import RouteName from "../../router/name";
@Component
export default class ConversationListItem extends Vue {
@Prop({ required: true, type: Object }) conversation!: IConversation;
export default class DiscussionListItem extends Vue {
@Prop({ required: true, type: Object }) discussion!: IDiscussion;
RouteName = RouteName;
get htmlTextEllipsis() {
const element = document.createElement("div");
element.innerHTML = this.conversation.lastComment.text
.replace(/<br\s*\/?>/gi, " ")
.replace(/<p>/gi, " ");
if (this.discussion.lastComment) {
element.innerHTML = this.discussion.lastComment.text
.replace(/<br\s*\/?>/gi, " ")
.replace(/<p>/gi, " ");
}
return element.innerText;
}
}
</script>
<style lang="scss" scoped>
.conversation-minimalist-card-wrapper {
.discussion-minimalist-card-wrapper {
text-decoration: none;
display: flex;
width: 100%;
color: initial;
@ -50,7 +53,7 @@ export default class ConversationListItem extends Vue {
.title-info-wrapper {
flex: 2;
.conversation-minimalist-title {
.discussion-minimalist-title {
color: #3c376e;
font-family: "Liberation Sans", "Helvetica Neue", Roboto, Helvetica, Arial, serif;
font-size: 1.25rem;

@ -247,6 +247,7 @@ export default class EventListCard extends mixins(ActorMixin, EventMixin) {
* Delete the event
*/
async openDeleteEventModalWrapper() {
// @ts-ignore
await this.openDeleteEventModal(this.participation.event, this.currentActor);
}

@ -87,13 +87,16 @@ import DiasporaLogo from "../../assets/diaspora-icon.svg?inline";
})
export default class ShareEventModal extends Vue {
@Prop({ type: Object, required: true }) event!: IEvent;
@Prop({ type: Boolean, required: false, default: true }) eventCapacityOK!: boolean;
@Ref("eventURLInput") readonly eventURLInput!: any;
EventVisibility = EventVisibility;
EventStatus = EventStatus;
showCopiedTooltip: boolean = false;
showCopiedTooltip = false;
get twitterShareUrl(): string {
return `https://twitter.com/intent/tweet?url=${encodeURIComponent(this.event.url)}&text=${

@ -23,7 +23,7 @@
<router-link
:to="{
name: RouteName.GROUP,
params: { preferredUsername: member.parent.preferredUsername },
params: { preferredUsername: usernameWithDomain(member.parent) },
}"
>
<h3>{{ member.parent.name }}</h3>
@ -57,7 +57,7 @@
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { IGroup, IMember } from "@/types/actor";
import { IGroup, IMember, usernameWithDomain } from "@/types/actor";
import RouteName from "../../router/name";
@Component
@ -65,6 +65,8 @@ export default class InvitationCard extends Vue {
@Prop({ required: true }) member!: IMember;
RouteName = RouteName;
usernameWithDomain = usernameWithDomain;
}
</script>

@ -7,6 +7,7 @@ import { Component, Prop, Vue } from "vue-property-decorator";
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
import MobilizonLogo from "../assets/mobilizon_logo.svg?inline";
@Component({
components: {
MobilizonLogo,

@ -0,0 +1,48 @@
<template>
<router-link
class="post-minimalist-card-wrapper"
:to="{ name: RouteName.POST, params: { slug: post.slug } }"
>
<div class="title-info-wrapper">
<p class="post-minimalist-title">{{ post.title }}</p>
<small class="has-text-grey">{{ $timeAgo.format(new Date(post.insertedAt)) }}</small>
</div>
</router-link>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import RouteName from "../../router/name";
import { IPost } from "../../types/post.model";
@Component
export default class PostListItem extends Vue {
@Prop({ required: true, type: Object }) post!: IPost;
RouteName = RouteName;
}
</script>
<style lang="scss" scoped>
.post-minimalist-card-wrapper {
text-decoration: none;
display: flex;
width: 100%;
color: initial;
border-bottom: 1px solid #e9e9e9;
align-items: center;
.title-info-wrapper {
flex: 2;
.post-minimalist-title {
color: #3c376e;
font-family: "Liberation Sans", "Helvetica Neue", Roboto, Helvetica, Arial, serif;
font-size: 1rem;
font-weight: 700;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
}
</style>

@ -142,7 +142,7 @@ a {
position: relative;
.preview {
flex: 0 0 100px;
flex: 0 0 50px;
position: relative;
display: flex;
align-items: center;
@ -159,7 +159,7 @@ a {
display: block;
font-weight: 500;
margin-bottom: 5px;
color: $background-color;
color: $primary;
overflow: hidden;
text-overflow: ellipsis;
text-decoration: none;

@ -81,7 +81,7 @@ a {
flex: 1;
.preview {
flex: 0 0 100px;
flex: 0 0 50px;
position: relative;
display: flex;
align-items: center;

@ -76,6 +76,7 @@ import { IResource } from "../../types/resource";
})
export default class ResourceSelector extends Vue {
@Prop({ required: true }) initialResource!: IResource;
@Prop({ required: true }) username!: string;
resource: IResource | undefined = this.initialResource.parent;

@ -13,6 +13,7 @@ import { Route } from "vue-router";
@Component
export default class SettingMenuItem extends Vue {
@Prop({ required: false, type: String }) title!: string;
@Prop({ required: true, type: Object }) to!: Route;
get isActive() {

@ -11,11 +11,13 @@
import { Component, Prop, Vue } from "vue-property-decorator";
import SettingMenuItem from "@/components/Settings/SettingMenuItem.vue";
import { Route } from "vue-router";
@Component({
components: { SettingMenuItem },
})
export default class SettingMenuSection extends Vue {
@Prop({ required: false, type: String }) title!: string;
@Prop({ required: true, type: Object }) to!: Route;
get sectionActive() {

@ -63,6 +63,7 @@ import { CURRENT_USER_CLIENT } from "../../graphql/user";
import { ICurrentUser, ICurrentUserRole } from "../../types/current-user.model";
import RouteName from "../../router/name";
@Component({
components: { SettingMenuSection, SettingMenuItem },
apollo: {

@ -24,6 +24,7 @@ import RouteName from "../../router/name";
import { UPDATE_TODO } from "../../graphql/todos";
import ActorAutoComplete from "../Account/ActorAutoComplete.vue";
import { IPerson } from "../../types/actor";
@Component({
components: { ActorAutoComplete },
})

@ -1,6 +1,7 @@
import gql from "graphql-tag";
import { CONVERSATION_BASIC_FIELDS_FRAGMENT } from "@/graphql/conversation";
import { DISCUSSION_BASIC_FIELDS_FRAGMENT } from "@/graphql/discussion";
import { RESOURCE_METADATA_BASIC_FIELDS_FRAGMENT } from "@/graphql/resources";
import { POST_BASIC_FIELDS } from "./post";
export const FETCH_PERSON = gql`
query($username: String!) {
@ -479,10 +480,16 @@ export const FETCH_GROUP = gql`
}
total
}
conversations {
discussions {
total
elements {
...ConversationBasicFields
...DiscussionBasicFields
}
}
posts {
total
elements {
...PostBasicFields
}
}
members {
@ -497,6 +504,7 @@ export const FETCH_GROUP = gql`
url
}
}
insertedAt
}
total
}
@ -537,9 +545,11 @@ export const FETCH_GROUP = gql`
}
}
}
${CONVERSATION_BASIC_FIELDS_FRAGMENT}
${DISCUSSION_BASIC_FIELDS_FRAGMENT}
${POST_BASIC_FIELDS}
${RESOURCE_METADATA_BASIC_FIELDS_FRAGMENT}
`;
export const CREATE_GROUP = gql`
mutation CreateGroup(
$creatorActorId: ID!
@ -571,6 +581,29 @@ export const CREATE_GROUP = gql`
}
`;
export const UPDATE_GROUP = gql`
mutation UpdateGroup(
$id: ID!
$name: String
$summary: String
$avatar: PictureInput
$banner: PictureInput
) {
createGroup(id: $id, name: $name, summary: $summary, banner: $banner, avatar: $avatar) {
id
preferredUsername
name
summary
avatar {
url
}
banner {
url
}
}
}
`;
export const SUSPEND_PROFILE = gql`
mutation SuspendProfile($id: ID!) {
suspendProfile(id: $id) {

@ -1,120 +0,0 @@
import gql from "graphql-tag";
export const CONVERSATION_BASIC_FIELDS_FRAGMENT = gql`
fragment ConversationBasicFields on Conversation {
id
title
slug
lastComment {
id
text
actor {
preferredUsername
avatar {
url
}
}
}
}
`;
export const CONVERSATION_FIELDS_FOR_REPLY_FRAGMENT = gql`
fragment ConversationFieldsReply on Conversation {
id
title
slug
lastComment {
id
text
updatedAt
actor {
id
preferredUsername
avatar {
url
}
}
}
actor {
id
preferredUsername
}
creator {
id
preferredUsername
}
}
`;
export const CONVERSATION_FIELDS_FRAGMENT = gql`
fragment ConversationFields on Conversation {
id
title
slug
lastComment {
id
text
updatedAt
}
actor {
id
preferredUsername
}
creator {
id
preferredUsername
}
}
`;
export const CREATE_CONVERSATION = gql`
mutation createConversation($title: String!, $creatorId: ID!, $actorId: ID!, $text: String!) {
createConversation(title: $title, text: $text, creatorId: $creatorId, actorId: $actorId) {
...ConversationFields
}
}
${CONVERSATION_FIELDS_FRAGMENT}
`;
export const REPLY_TO_CONVERSATION = gql`
mutation replyToConversation($conversationId: ID!, $text: String!) {
replyToConversation(conversationId: $conversationId, text: $text) {
...ConversationFieldsReply
}
}
${CONVERSATION_FIELDS_FOR_REPLY_FRAGMENT}
`;
export const GET_CONVERSATION = gql`
query getConversation($id: ID!, $page: Int, $limit: Int) {
conversation(id: $id) {
comments(page: $page, limit: $limit) {
total
elements {
id
text
actor {
id
avatar {
url
}
preferredUsername
}
insertedAt
updatedAt
}
}
...ConversationFields
}
}
${CONVERSATION_FIELDS_FRAGMENT}
`;
export const UPDATE_CONVERSATION = gql`
mutation updateConversation($conversationId: ID!, $title: String!) {
updateConversation(conversationId: $conversationId, title: $title) {
...ConversationFields
}
}
${CONVERSATION_FIELDS_FRAGMENT}
`;

@ -0,0 +1,158 @@
import gql from "graphql-tag";
export const DISCUSSION_BASIC_FIELDS_FRAGMENT = gql`
fragment DiscussionBasicFields on Discussion {
id
title
slug
lastComment {
id
text
actor {
id
preferredUsername
avatar {
url
}
}
}
}
`;
export const DISCUSSION_FIELDS_FOR_REPLY_FRAGMENT = gql`
fragment DiscussionFieldsReply on Discussion {
id
title
slug
lastComment {
id
text
updatedAt
actor {
id
preferredUsername
avatar {
url
}
}
}
actor {
id
preferredUsername
}
creator {
id
preferredUsername
}
}
`;
export const DISCUSSION_FIELDS_FRAGMENT = gql`
fragment DiscussionFields on Discussion {
id
title
slug
lastComment {
id
text
updatedAt
}
actor {
id
domain
name
preferredUsername
}
creator {
id
domain
name
preferredUsername
}
}
`;
export const CREATE_DISCUSSION = gql`
mutation createDiscussion($title: String!, $creatorId: ID!, $actorId: ID!, $text: String!) {
createDiscussion(title: $title, text: $text, creatorId: $creatorId, actorId: $actorId) {
...DiscussionFields
}
}
${DISCUSSION_FIELDS_FRAGMENT}
`;
export const REPLY_TO_DISCUSSION = gql`
mutation replyToDiscussion($discussionId: ID!, $text: String!) {
replyToDiscussion(discussionId: $discussionId, text: $text) {
...DiscussionFields
}
}
${DISCUSSION_FIELDS_FRAGMENT}
`;
export const GET_DISCUSSION = gql`
query getDiscussion($slug: String!, $page: Int, $limit: Int) {
discussion(slug: $slug) {
comments(page: $page, limit: $limit)
@connection(key: "discussion-comments", filter: ["slug"]) {
total
elements {
id
text
actor {
id
avatar {
url
}
name
domain
preferredUsername
}
insertedAt
updatedAt
}
}
...DiscussionFields
}
}
${DISCUSSION_FIELDS_FRAGMENT}
`;
export const UPDATE_DISCUSSION = gql`
mutation updateDiscussion($discussionId: ID!, $title: String!) {
updateDiscussion(discussionId: $discussionId, title: $title) {
...DiscussionFields
}
}
${DISCUSSION_FIELDS_FRAGMENT}
`;
export const DELETE_DISCUSSION = gql`
mutation deleteDiscussion($discussionId: ID!) {
deleteDiscussion(discussionId: $discussionId) {
id
}
}
`;
export const DISCUSSION_COMMENT_CHANGED = gql`
subscription($slug: String!) {
discussionCommentChanged(slug: $slug) {
id
lastComment {
id
text
updatedAt
insertedAt
actor {
id
preferredUsername
domain
avatar {
url
}
}
}
}
}
`;

@ -22,3 +22,31 @@ export const ACCEPT_INVITATION = gql`
}
}
`;
export const GROUP_MEMBERS = gql`
query($name: String!, $roles: String, $page: Int, $limit: Int) {
group(preferredUsername: $name) {
id
url
name
domain
preferredUsername
members(page: $page, limit: $limit, roles: $roles) {
elements {
role
actor {
id
name
domain
preferredUsername
avatar {
url
}
}
insertedAt
}
total
}
}
}
`;

@ -0,0 +1,151 @@
import gql from "graphql-tag";
import { TAG_FRAGMENT } from "./tags";
export const POST_FRAGMENT = gql`
fragment PostFragment on Post {
id
title
slug
url
body
author {
id
preferredUsername
name
domain
avatar {
url
}
}
attributedTo {
id
preferredUsername
name
domain
avatar {
url
}
}
insertedAt
updatedAt
publishAt
draft
visibility
tags {
...TagFragment
}
}
${TAG_FRAGMENT}
`;
export const POST_BASIC_FIELDS = gql`
fragment PostBasicFields on Post {
id
title
slug
url
author {
id
preferredUsername
name
avatar {
url
}
}
attributedTo {
id
preferredUsername
name
avatar {
url
}
}
insertedAt
updatedAt
publishAt
draft
}
`;
export const FETCH_GROUP_POSTS = gql`
query GroupPosts($preferredUsername: String!, $page: Int, $limit: Int) {
group(preferredUsername: $preferredUsername) {
id
preferredUsername
domain
name
posts(page: $page, limit: $limit) {
total
elements {
...PostBasicFields
}
}
}
}
${POST_BASIC_FIELDS}
`;
export const FETCH_POST = gql`
query Post($slug: String!) {
post(slug: $slug) {
...PostFragment
}
}
${POST_FRAGMENT}
`;
export const CREATE_POST = gql`
mutation CreatePost(
$title: String!
$body: String
$attributedToId: ID!
$visibility: PostVisibility
$draft: Boolean
$tags: [String]
) {
createPost(
title: $title
body: $body
attributedToId: $attributedToId
visibility: $visibility
draft: $draft
tags: $tags
) {
...PostFragment
}
}
${POST_FRAGMENT}
`;
export const UPDATE_POST = gql`
mutation UpdatePost(
$id: ID!
$title: String
$body: String
$attributedToId: ID
$visibility: PostVisibility
$draft: Boolean
$tags: [String]
) {
updatePost(
id: $id
title: $title
body: $body
attributedToId: $attributedToId
visibility: $visibility
draft: $draft
tags: $tags
) {
...PostFragment
}
}
${POST_FRAGMENT}
`;
export const DELETE_POST = gql`
mutation DeletePost($id: ID!) {
deletePost(id: $id) {
id
}
}
`;

@ -1,6 +1,13 @@
import gql from "graphql-tag";
/* eslint-disable import/prefer-default-export */
export const TAG_FRAGMENT = gql`
fragment TagFragment on Tag {
id
slug
title
}
`;
export const TAGS = gql`
query {
tags {

@ -55,7 +55,7 @@
"Continue editing": "مواصلة التحرير",
"Country": "البلد",
"Create": "انشاء",
"Create a new conversation": "أنشئ محادثة جديدة",
"Create a new discussion": "أنشئ محادثة جديدة",
"Create a new event": "انشاء فعالية جديدة",
"Create a new group": "إنشاء فريق جديد",
"Create a new identity": "إنشاء هوية جديدة",
@ -186,7 +186,7 @@
"My events": "فعالياتي",
"My identities": "هوياتي",
"Name": "الإسم",
"New conversation": "محادثة جديدة",
"New discussion": "محادثة جديدة",
"New email": "العنوان الجديد للبريد الإلكتروني",
"New folder": "مجلد جديد",
"New link": "رابط جديد",

@ -21,7 +21,7 @@
"An error has occurred.": "Адбылася памылка.",
"Approve": "Пацвердзіць",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Вы сапраўды хочаце <b>выдаліць</b> гэты каментарый? Гэта дзеянне нельга адмяніць.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Вы сапраўды жадаеце <b>выдаліць</b> гэту падзею? Гэта дзеянне нельга адмяніць. Магчыма, варта замест гэтага пагаварыць з аўтарам ці аўтаркай падзеі ці адрэдагаваць падзею.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Вы сапраўды жадаеце <b>выдаліць</b> гэту падзею? Гэта дзеянне нельга адмяніць. Магчыма, варта замест гэтага пагаварыць з аўтарам ці аўтаркай падзеі ці адрэдагаваць падзею.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Вы сапраўды хочаце адмяніць стварэнне падзеі? Вы страціце ўсе свае рэдагаванні.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Вы сапраўды хочаце адмяніць рэдагаванне падзеі? Вы страціце ўсе рэдагаванні.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Вы сапраўды хочаце адмовіцца ад удзелу ў падзеі «{title}»?",

@ -30,7 +30,7 @@
"Approve": "Aprova",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Segur que voleu suprimir tot el compte? Ho perdràs tot. Les identitats, la configuració, els esdeveniments creats, els missatges i les participacions desapareixeran per sempre.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Segur que vols <b>esborrar</b> aquest comentari? Aquesta acció és irreversible.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Segur que vols <b>esborrar</b> aquesta activitat? Aquesta acció és irreversible. En comptes d'això, pots parlar amb la persona creadora de l'activitat o modificar l'activitat.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Segur que vols <b>esborrar</b> aquesta activitat? Aquesta acció és irreversible. En comptes d'això, pots parlar amb la persona creadora de l'activitat o modificar l'activitat.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Segur que vols esborrar aquesta activitat? Perdràs tots els canvis.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Segur que vols canceŀlar l'edició? Perdràs tots els canvis que hagis fet.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Segur que vols deixar de participar a l'activitat \"{title}\"?",

@ -27,7 +27,7 @@
"Approve": "Bestätigen",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Bist du dir sicher, dass du den gesamten Account löschen möchtest? Du verlierst dadurch alles. Identitäten, Einstellungen, erstellte Events, Nachrichten, Teilnahmen sind dann für immer verschwunden.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Bist du sicher, dass du diesen Kommentar <b>löschen</b> willst? Diese Aktion kann nicht rückgängig gemacht werden.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Bist du sicher, dass du diese Veranstaltung <b>löschen</b> willst? Diese Aktion kann nicht rückgängig gemacht werden.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Bist du sicher, dass du diese Veranstaltung <b>löschen</b> willst? Diese Aktion kann nicht rückgängig gemacht werden.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Bist Du dir sicher, dass du das Erstellen der Veranstaltung abbrechen möchtest? Alle Änderungen werden verloren gehen.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Bist du dir sicher, dass Du die Bearbeitung der Veranstaltung abbrechen möchtest? Alle Änderungen werden verloren gehen.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Bist Du dir sicher, dass Du nicht mehr an der Veranstaltung \"{title}\" teilnehmen möchtest?",

@ -29,7 +29,7 @@
"Approve": "Approve",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Are you sure you want to <b>delete</b> this comment? This action cannot be undone.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Are you sure you want to cancel the event creation? You'll lose all modifications.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Are you sure you want to cancel the event edition? You'll lose all modifications.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Are you sure you want to cancel your participation at event \"{title}\"?",
@ -710,5 +710,9 @@
"Error while login with {provider}. Retry or login another way.": "Error while login with {provider}. Retry or login another way.",
"Error while login with {provider}. This login provider doesn't exist.": "Error while login with {provider}. This login provider doesn't exist.",
"This user has been disabled": "This user has been disabled",
"You can't reset your password because you use a 3rd-party auth provider to login.": "You can't reset your password because you use a 3rd-party auth provider to login."
"You can't reset your password because you use a 3rd-party auth provider to login.": "You can't reset your password because you use a 3rd-party auth provider to login.",
"Update post {name}": "Update post {name}",
"Create a new post": "Create a new post",
"Post": "Post",
"By {author}": "By {author}"
}

@ -55,7 +55,7 @@
"Approve": "Aprobar",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "¿Estás realmente seguro de que deseas eliminar toda tu cuenta? Lo perderás todo. Las identidades, la configuración, los eventos creados, los mensajes y las participaciones desaparecerán para siempre.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "¿Estás seguro de que quieres <b> eliminar </b> este comentario? Esta acción no se puede deshacer.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "¿Estás seguro de que quieres <b> eliminar </b> este evento? Esta acción no se puede deshacer. Es posible que desee entablar una conversación con el creador del evento o editar el evento en su lugar.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "¿Estás seguro de que quieres <b> eliminar </b> este evento? Esta acción no se puede deshacer. Es posible que desee entablar una conversación con el creador del evento o editar el evento en su lugar.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "¿Seguro que quieres cancelar la creación del evento? Perderás todas las modificaciones.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "¿Seguro que quieres cancelar la edición del evento? Perderás todas las modificaciones.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "¿Está seguro de que desea cancelar su participación en el evento \"{title}\"?",
@ -103,14 +103,14 @@
"Confirmed: Will happen": "Confirmado: sucederá",
"Contact": "Contacto",
"Continue editing": "Continua editando",
"Conversations": "Conversaciones",
"Discussions": "Conversaciones",
"Cookies and Local storage": "Cookies y almacenamiento local",
"Country": "País",
"Create": "Crear",
"Create a calc": "Crear un calco",
"Create a discussion": "Crear una discusión",
"Create a folder": "Crear una carpeta",
"Create a new conversation": "Crea una nueva conversación",
"Create a new discussion": "Crea una nueva conversación",
"Create a new event": "Crear un nuevo evento",
"Create a new group": "Crear un nuevo grupo",
"Create a new identity": "Crear una nueva identidad",
@ -347,7 +347,7 @@
"My identities": "Mis identidades",
"NOTE! The default terms have not been checked over by a lawyer and thus are unlikely to provide full legal protection for all situations for an instance admin using them. They are also not specific to all countries and jurisdictions. If you are unsure, please check with a lawyer.": "¡NOTA! Los términos predeterminados no han sido revisados por un abogado y, por lo tanto, es poco probable que brinden protección legal completa para todas las situaciones para un administrador de instancia que los use. Tampoco son específicos de todos los países y jurisdicciones. Si no está seguro, consulte con un abogado.",
"Name": "Nombre",
"New conversation": "Nueva conversación",
"New discussion": "Nueva conversación",
"New discussion": "Nueva discusión",
"New email": "Nuevo correo electrónico",
"New folder": "Nueva carpeta",
@ -620,7 +620,7 @@
"Username": "Nombre de usuario",
"Users": "Los usuarios",
"View a reply": "|Ver una respuesta|Ver {totalReplies} respuestas",
"View all conversations": "Ver todas las conversaciones",
"View all discussions": "Ver todas las conversaciones",
"View all discussions": "Ver todas las discusiones",
"View all resources": "Ver todos los recursos",
"View all todos": "Ver todas las tareas pendientes",

@ -54,7 +54,7 @@
"Approve": "Hyväksy",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Haluatko varmasti poistaa koko tilin? Tällöin kaikki poistetaan. Identiteetit, asetukset, luodut tapahtumat, viestit ja osallistumiset poistetaan pysyvästi.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Haluatko varmasti <b>poistaa</b> tämän kommentin? Toimintoa ei voi perua.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Haluatko varmasti <b>poistaa</b> tämän tapahtuman? Toimintoa ei voi perua. Poistamisen sijaan voisit ehkä keskustella tapahtuman luojan kanssa tai muokata tapahtumaa.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Haluatko varmasti <b>poistaa</b> tämän tapahtuman? Toimintoa ei voi perua. Poistamisen sijaan voisit ehkä keskustella tapahtuman luojan kanssa tai muokata tapahtumaa.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Haluatko varmasti keskeyttää tapahtuman luomisen? Kaikki muutokset menetetään.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Haluatko varmasti keskeyttää tapahtuman muokkaamisen? Kaikki muutokset menetetään.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Haluatko varmasti perua osallistumisesi tapahtumaan {title}?",
@ -101,14 +101,14 @@
"Confirmed: Will happen": "Vahvistettu: Tapahtuu",
"Contact": "Ota yhteyttä",
"Continue editing": "Jatka muokkausta",
"Conversations": "Keskustelut",
"Discussions": "Keskustelut",
"Cookies and Local storage": "Evästeet ja paikallisesti tallennettavat tiedot",
"Country": "Maa",
"Create": "Luo",
"Create a calc": "Luo taulukko",
"Create a discussion": "Luo keskustelu",
"Create a folder": "Luo kansio",
"Create a new conversation": "Luo uusi keskustelu",
"Create a new discussion": "Luo uusi keskustelu",
"Create a new event": "Luo uusi tapahtuma",
"Create a new group": "Luo uusi ryhmä",
"Create a new identity": "Luo uusi identiteetti",
@ -341,7 +341,7 @@
"My identities": "Omat identiteetit",
"NOTE! The default terms have not been checked over by a lawyer and thus are unlikely to provide full legal protection for all situations for an instance admin using them. They are also not specific to all countries and jurisdictions. If you are unsure, please check with a lawyer.": "HUOM! Oletusehdot eivät ole juristin tarkistamia, joten palvelimen ylläpitäjän ei ole syytä luottaa niiden tarjoamaan juridiseen suojaan. Niitä ei ole myöskään sovitettu eri maiden ja lainkäyttöalueiden olosuhteisiin. Epävarmoissa tilanteissa suosittelemme tarkistuttamaan ehdot lakiasiantuntijalla.",
"Name": "Nimi",
"New conversation": "Uusi keskustelu",
"New discussion": "Uusi keskustelu",
"New discussion": "Uusi keskustelu",
"New email": "Uusi sähköpostiosoite",
"New folder": "Uusi kansio",
@ -615,7 +615,7 @@
"Username": "Käyttäjänimi",
"Users": "Käyttäjät",
"View a reply": "|Näytä vastaus|Näytä {totalReplies} vastausta",
"View all conversations": "Näytä kaikki keskustelut",
"View all discussions": "Näytä kaikki keskustelut",
"View all discussions": "Näytä kaikki keskustelut",
"View all resources": "Näytä kaikki resurssit",
"View all todos": "Näytä kaikki tehtävät",

@ -53,7 +53,7 @@
"Approve": "Approuver",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Êtes-vous vraiment certain⋅e de vouloir supprimer votre compte ? Vous allez tout perdre. Identités, paramètres, événements créés, messages et participations disparaîtront pour toujours.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> ce commentaire ? Cette action ne peut pas être annulée.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> cet évènement ? Cette action n'est pas réversible. Vous voulez peut-être engager la conversation avec le créateur de l'évènement ou bien modifier son évènement à la place.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> cet évènement ? Cette action n'est pas réversible. Vous voulez peut-être engager la discussion avec le créateur de l'évènement ou bien modifier son évènement à la place.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Étes-vous certain⋅e de vouloir annuler la création de l'évènement ? Vous allez perdre toutes vos modifications.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Êtes-vous certain⋅e de vouloir annuler la modification de l'évènement ? Vous allez perdre toutes vos modifications.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Êtes-vous certain⋅e de vouloir annuler votre participation à l'évènement « {title} » ?",
@ -710,5 +710,9 @@
"Error while login with {provider}. Retry or login another way.": "Erreur lors de la connexion avec {provider}. Réessayez ou bien connectez vous autrement.",
"Error while login with {provider}. This login provider doesn't exist.": "Erreur lors de la connexion avec {provider}. Cette méthode de connexion n'existe pas.",
"This user has been disabled": "Cet utilisateur·ice a été désactivé·e",
"You can't reset your password because you use a 3rd-party auth provider to login.": "Vous ne pouvez pas réinitialiser votre mot de passe car vous vous connectez via une méthode externe."
"You can't reset your password because you use a 3rd-party auth provider to login.": "Vous ne pouvez pas réinitialiser votre mot de passe car vous vous connectez via une méthode externe.",
"Update post {name}": "Mettre à jour le billet {name}",
"Create a new post": "Créer un nouveau billet",
"Post": "Billet",
"By {author}": "Par {author}"
}

@ -41,7 +41,7 @@
"Are you going to this event?": "Anatz a aqueste eveniment ?",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Volètz vertadièrament suprimir vòstre compte? O perdretz tot. Identitats, paramètres, eveniments creats, messatges e participacions desapareisseràn per totjorn.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Volètz vertadièrament <b>suprimir</b> aqueste comentari? Aquesta accion es irreversibla.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Volètz vertadièrament <b>suprimir</b> aqueste eveniment? Aquesta accion es irreversibla. Benlèu qu’a la plaça volètz començar una conversacion amb l’organizaire o modificar sos eveniment.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Volètz vertadièrament <b>suprimir</b> aqueste eveniment? Aquesta accion es irreversibla. Benlèu qu’a la plaça volètz començar una conversacion amb l’organizaire o modificar sos eveniment.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Volètz vertadièrament anullar la creacion de l’eveniment ? Perdretz totas vòstras modificacions.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Volètz vertadièrament anullar la modificacion de l’eveniment ? Perdretz totas vòstras modificacions.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Volètz vertadièrament anullar vòstra participacion a l’eveniment « {title} » ?",
@ -84,10 +84,10 @@
"Confirmed: Will happen": "Confirmat : se tendrà",
"Contact": "Contacte",
"Continue editing": "Contunhar la modificacion",
"Conversations": "Conversacions",
"Discussions": "Conversacions",
"Country": "País",
"Create": "Crear",
"Create a new conversation": "Crear una conversacion novèla",
"Create a new discussion": "Crear una conversacion novèla",
"Create a new event": "Crear un eveniment novèl",
"Create a new group": "Crear un grop novèl",
"Create a new identity": "Crear una identitat novèla",
@ -273,7 +273,7 @@
"My groups": "Mos grops",
"My identities": "Mas identitats",
"Name": "Nom",
"New conversation": "Conversacion novèla",
"New discussion": "Conversacion novèla",
"New email": "Adreça novèla",
"New folder": "Dossièr novèl",
"New link": "Ligam novèl",

@ -26,7 +26,7 @@
"Anonymous participations": "Participações anônimas",
"Approve": "Aprovar",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Você está seguro que quer <b>apagar</b> este comentário? Esta ação não pode ser desfeita.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Você está seguro que quer <b>apagar</b> este evento? Esta ação não pode ser desfeita. Talvez você queira tentar uma conversa com o criador do evento ou, então, editar este evento.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Você está seguro que quer <b>apagar</b> este evento? Esta ação não pode ser desfeita. Talvez você queira tentar uma conversa com o criador do evento ou, então, editar este evento.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Você está seguro que quer cancelar a criação do evento? Você perderá todas as modificações.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Você está seguro que quer cancelar a edição do evento? Você perderá todas as modificações.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Você está seguro que quer cancelar a sua participação no evento \"{title}\"?",

@ -6,15 +6,29 @@ import Component from "vue-class-component";
import VueScrollTo from "vue-scrollto";
import VueMeta from "vue-meta";
import VTooltip from "v-tooltip";
import TimeAgo from "javascript-time-ago";
import App from "./App.vue";
import router from "./router";
import { NotifierPlugin } from "./plugins/notifier";
import filters from "./filters";
import { i18n } from "./utils/i18n";
import messages from "./i18n";
import apolloProvider from "./vue-apollo";
Vue.config.productionTip = false;
let language = document.documentElement.getAttribute("lang") as string;