2019-01-21 15:08:22 +01:00
|
|
|
<template>
|
2022-07-12 10:55:28 +02:00
|
|
|
<div class="container mx-auto">
|
|
|
|
<o-loading v-model:active="eventLoading" />
|
2022-10-11 17:48:58 +02:00
|
|
|
<div class="flex flex-col mb-3">
|
2022-07-12 10:55:28 +02:00
|
|
|
<event-banner :picture="event?.picture" />
|
2022-10-31 18:05:59 +01:00
|
|
|
<div
|
|
|
|
class="flex flex-col relative pb-2 bg-white dark:bg-zinc-700 my-2 rounded"
|
|
|
|
>
|
|
|
|
<div class="date-calendar-icon-wrapper relative" v-if="event?.beginsOn">
|
|
|
|
<date-calendar-icon
|
|
|
|
:date="event.beginsOn.toString()"
|
|
|
|
class="absolute left-3 -top-16"
|
|
|
|
/>
|
2021-08-04 11:23:37 +02:00
|
|
|
</div>
|
2022-07-12 10:55:28 +02:00
|
|
|
|
2022-10-31 18:05:59 +01:00
|
|
|
<section class="intro px-2 pt-4" dir="auto">
|
2022-10-11 17:48:58 +02:00
|
|
|
<div class="flex flex-wrap gap-2">
|
2022-10-31 18:05:59 +01:00
|
|
|
<div class="flex-1 min-w-[300px]">
|
2021-11-13 15:58:54 +01:00
|
|
|
<h1
|
2022-07-12 10:55:28 +02:00
|
|
|
class="text-4xl font-bold m-0"
|
2021-11-13 15:58:54 +01:00
|
|
|
dir="auto"
|
2022-07-12 10:55:28 +02:00
|
|
|
:lang="event?.language"
|
2021-11-13 15:58:54 +01:00
|
|
|
>
|
2022-07-12 10:55:28 +02:00
|
|
|
{{ event?.title }}
|
2021-11-07 14:59:20 +01:00
|
|
|
</h1>
|
2021-08-04 11:23:37 +02:00
|
|
|
<div class="organizer">
|
2022-07-12 10:55:28 +02:00
|
|
|
<div v-if="event?.organizerActor && !event?.attributedTo">
|
2021-08-04 11:23:37 +02:00
|
|
|
<popover-actor-card
|
|
|
|
:actor="event.organizerActor"
|
|
|
|
:inline="true"
|
|
|
|
>
|
2022-07-12 10:55:28 +02:00
|
|
|
<i18n-t
|
|
|
|
keypath="By {username}"
|
2022-04-22 12:00:47 +02:00
|
|
|
dir="auto"
|
|
|
|
class="block truncate max-w-xs md:max-w-sm"
|
|
|
|
>
|
2022-07-12 10:55:28 +02:00
|
|
|
<template #username>
|
|
|
|
<span dir="ltr">{{
|
|
|
|
displayName(event.organizerActor)
|
|
|
|
}}</span>
|
|
|
|
</template>
|
|
|
|
</i18n-t>
|
2021-08-04 11:23:37 +02:00
|
|
|
</popover-actor-card>
|
2021-11-07 14:59:20 +01:00
|
|
|
</div>
|
2022-07-12 10:55:28 +02:00
|
|
|
<span v-else-if="event?.attributedTo">
|
2021-08-04 11:23:37 +02:00
|
|
|
<popover-actor-card
|
|
|
|
:actor="event.attributedTo"
|
|
|
|
:inline="true"
|
|
|
|
>
|
2022-07-12 10:55:28 +02:00
|
|
|
<i18n-t
|
|
|
|
keypath="By {group}"
|
2022-04-22 12:00:47 +02:00
|
|
|
dir="auto"
|
|
|
|
class="block truncate max-w-xs md:max-w-sm"
|
|
|
|
>
|
2022-07-12 10:55:28 +02:00
|
|
|
<template #group>
|
|
|
|
<router-link
|
|
|
|
:to="{
|
|
|
|
name: RouteName.GROUP,
|
|
|
|
params: {
|
|
|
|
preferredUsername: usernameWithDomain(
|
|
|
|
event.attributedTo
|
|
|
|
),
|
|
|
|
},
|
|
|
|
}"
|
|
|
|
dir="ltr"
|
|
|
|
>{{ displayName(event.attributedTo) }}</router-link
|
|
|
|
>
|
|
|
|
</template>
|
|
|
|
</i18n-t>
|
2021-11-07 21:02:06 +01:00
|
|
|
</popover-actor-card>
|
2021-08-04 11:23:37 +02:00
|
|
|
</span>
|
|
|
|
</div>
|
2022-10-31 18:05:59 +01:00
|
|
|
<div class="flex flex-wrap items-center gap-2 gap-y-4 mt-2 my-3">
|
2022-08-26 16:08:58 +02:00
|
|
|
<p v-if="event?.status !== EventStatus.CONFIRMED">
|
|
|
|
<tag
|
|
|
|
variant="warning"
|
|
|
|
v-if="event?.status === EventStatus.TENTATIVE"
|
|
|
|
>{{ t("Event to be confirmed") }}</tag
|
|
|
|
>
|
|
|
|
<tag
|
|
|
|
variant="danger"
|
|
|
|
v-if="event?.status === EventStatus.CANCELLED"
|
|
|
|
>{{ t("Event cancelled") }}</tag
|
|
|
|
>
|
|
|
|
</p>
|
2022-10-31 18:05:59 +01:00
|
|
|
<template v-if="!event?.draft">
|
|
|
|
<p
|
|
|
|
v-if="event?.visibility === EventVisibility.PUBLIC"
|
|
|
|
class="inline-flex gap-1"
|
|
|
|
>
|
|
|
|
<Earth />
|
|
|
|
{{ t("Public event") }}
|
|
|
|
</p>
|
|
|
|
<p
|
|
|
|
v-if="event?.visibility === EventVisibility.UNLISTED"
|
|
|
|
class="inline-flex gap-1"
|
|
|
|
>
|
|
|
|
<Link />
|
|
|
|
{{ t("Private event") }}
|
|
|
|
</p>
|
|
|
|
</template>
|
|
|
|
<template v-if="!event?.local && organizerDomain">
|
|
|
|
<a :href="event?.url">
|
|
|
|
<tag variant="info">{{ organizerDomain }}</tag>
|
|
|
|
</a>
|
|
|
|
</template>
|
|
|
|
<p class="flex flex-wrap gap-1 items-center" dir="auto">
|
2022-08-26 16:08:58 +02:00
|
|
|
<tag v-if="eventCategory" class="category" capitalize>{{
|
|
|
|
eventCategory
|
|
|
|
}}</tag>
|
|
|
|
<router-link
|
|
|
|
v-for="tag in event?.tags ?? []"
|
|
|
|
:key="tag.title"
|
|
|
|
:to="{ name: RouteName.TAG, params: { tag: tag.title } }"
|
|
|
|
>
|
|
|
|
<tag>{{ tag.title }}</tag>
|
|
|
|
</router-link>
|
|
|
|
</p>
|
|
|
|
<tag variant="warning" size="medium" v-if="event?.draft"
|
|
|
|
>{{ t("Draft") }}
|
|
|
|
</tag>
|
|
|
|
</div>
|
2021-08-04 11:23:37 +02:00
|
|
|
</div>
|
2022-07-12 10:55:28 +02:00
|
|
|
|
2022-10-11 17:48:58 +02:00
|
|
|
<EventActionSection
|
|
|
|
v-if="event"
|
|
|
|
:event="event"
|
|
|
|
:currentActor="currentActor"
|
|
|
|
:participations="participations"
|
|
|
|
:person="person"
|
|
|
|
/>
|
2021-08-04 11:23:37 +02:00
|
|
|
</div>
|
|
|
|
</section>
|
|
|
|
</div>
|
2022-07-12 10:55:28 +02:00
|
|
|
|
|
|
|
<div
|
2022-10-31 11:43:18 +01:00
|
|
|
class="rounded-lg dark:border-violet-title flex flex-wrap flex-col md:flex-row-reverse gap-4"
|
2022-07-12 10:55:28 +02:00
|
|
|
>
|
2022-10-31 18:05:59 +01:00
|
|
|
<aside
|
|
|
|
class="rounded bg-white dark:bg-zinc-700 shadow-md h-min max-w-screen-sm"
|
|
|
|
>
|
2022-10-11 17:48:58 +02:00
|
|
|
<div class="sticky p-4">
|
2021-08-09 14:26:11 +02:00
|
|
|
<event-metadata-sidebar
|
2022-09-01 10:00:17 +02:00
|
|
|
v-if="event"
|
2021-08-09 14:26:11 +02:00
|
|
|
:event="event"
|
2021-10-10 16:25:50 +02:00
|
|
|
:user="loggedUser"
|
|
|
|
@showMapModal="showMap = true"
|
2021-08-09 14:26:11 +02:00
|
|
|
/>
|
2021-08-04 11:23:37 +02:00
|
|
|
</div>
|
|
|
|
</aside>
|
2022-10-31 11:43:18 +01:00
|
|
|
<div class="flex-1">
|
2022-10-31 13:03:03 +01:00
|
|
|
<section
|
|
|
|
class="event-description bg-white dark:bg-zinc-700 px-3 pt-1 pb-3 rounded mb-4"
|
|
|
|
>
|
2022-10-31 11:43:18 +01:00
|
|
|
<h2 class="text-2xl">{{ t("About this event") }}</h2>
|
2022-07-12 10:55:28 +02:00
|
|
|
<p v-if="!event?.description">
|
|
|
|
{{ t("The event organizer didn't add any description.") }}
|
2021-08-04 11:23:37 +02:00
|
|
|
</p>
|
|
|
|
<div v-else>
|
|
|
|
<div
|
2022-07-12 10:55:28 +02:00
|
|
|
:lang="event?.language"
|
2021-11-07 14:59:20 +01:00
|
|
|
dir="auto"
|
2022-10-31 18:05:59 +01:00
|
|
|
class="mt-4 prose md:prose-lg lg:prose-xl dark:prose-invert prose-h1:text-xl prose-h1:font-semibold prose-h2:text-lg prose-h3:text-base md:prose-h1:text-2xl md:prose-h1:font-semibold md:prose-h2:text-xl md:prose-h3:text-lg lg:prose-h1:text-2xl lg:prose-h1:font-semibold lg:prose-h2:text-xl lg:prose-h3:text-lg"
|
2021-08-04 11:23:37 +02:00
|
|
|
ref="eventDescriptionElement"
|
|
|
|
v-html="event.description"
|
|
|
|
/>
|
2019-04-03 17:29:03 +02:00
|
|
|
</div>
|
2021-08-04 11:23:37 +02:00
|
|
|
</section>
|
2022-10-31 11:43:18 +01:00
|
|
|
<section class="my-4">
|
2021-08-09 14:26:11 +02:00
|
|
|
<component
|
|
|
|
v-for="(metadata, integration) in integrations"
|
2022-11-04 11:28:56 +01:00
|
|
|
:is="metadataToComponent[integration]"
|
2021-08-09 14:26:11 +02:00
|
|
|
:key="integration"
|
|
|
|
:metadata="metadata"
|
2022-11-04 11:28:56 +01:00
|
|
|
class="my-2"
|
2021-08-09 14:26:11 +02:00
|
|
|
/>
|
|
|
|
</section>
|
2022-10-31 13:03:03 +01:00
|
|
|
<section
|
|
|
|
class="bg-white dark:bg-zinc-700 px-3 pt-1 pb-3 rounded my-4"
|
|
|
|
ref="commentsObserver"
|
|
|
|
>
|
2021-08-04 11:23:37 +02:00
|
|
|
<a href="#comments">
|
2022-10-31 18:05:59 +01:00
|
|
|
<h2 class="text-2xl" id="comments">{{ t("Comments") }}</h2>
|
2021-08-04 11:23:37 +02:00
|
|
|
</a>
|
2022-07-12 10:55:28 +02:00
|
|
|
<comment-tree v-if="event && loadComments" :event="event" />
|
2021-08-04 11:23:37 +02:00
|
|
|
</section>
|
|
|
|
</div>
|
|
|
|
</div>
|
2022-07-12 10:55:28 +02:00
|
|
|
|
2022-10-31 13:03:03 +01:00
|
|
|
<section
|
|
|
|
class="bg-white dark:bg-zinc-700 px-3 pt-1 pb-3 rounded my-4"
|
|
|
|
v-if="(event?.relatedEvents ?? []).length > 0"
|
|
|
|
>
|
2022-10-31 11:43:18 +01:00
|
|
|
<h2 class="text-2xl mb-2">
|
2022-07-12 10:55:28 +02:00
|
|
|
{{ t("These events may interest you") }}
|
2022-08-12 16:46:44 +02:00
|
|
|
</h2>
|
2022-07-12 10:55:28 +02:00
|
|
|
<multi-card :events="event?.relatedEvents ?? []" />
|
2021-08-04 11:23:37 +02:00
|
|
|
</section>
|
2022-07-12 10:55:28 +02:00
|
|
|
<o-modal
|
|
|
|
v-model:active="showMap"
|
|
|
|
:close-button-aria-label="t('Close')"
|
2021-10-10 16:25:50 +02:00
|
|
|
class="map-modal"
|
2022-07-12 10:55:28 +02:00
|
|
|
v-if="event?.physicalAddress?.geom"
|
2021-10-10 16:25:50 +02:00
|
|
|
has-modal-card
|
|
|
|
full-screen
|
|
|
|
:can-cancel="['escape', 'outside']"
|
|
|
|
>
|
2022-11-04 18:17:30 +01:00
|
|
|
<template #default>
|
2022-09-20 16:53:26 +02:00
|
|
|
<event-map
|
|
|
|
:routingType="routingType ?? RoutingType.OPENSTREETMAP"
|
2021-10-10 16:25:50 +02:00
|
|
|
:address="event.physicalAddress"
|
2022-11-04 18:17:30 +01:00
|
|
|
@close="showMap = false"
|
2022-09-20 16:53:26 +02:00
|
|
|
/>
|
2021-10-10 16:25:50 +02:00
|
|
|
</template>
|
2022-07-12 10:55:28 +02:00
|
|
|
</o-modal>
|
2021-08-04 11:23:37 +02:00
|
|
|
</div>
|
2019-10-08 22:27:14 +02:00
|
|
|
</div>
|
2019-01-21 15:08:22 +01:00
|
|
|
</template>
|
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
<script lang="ts" setup>
|
2022-10-31 18:05:59 +01:00
|
|
|
import {
|
|
|
|
EventStatus,
|
|
|
|
ParticipantRole,
|
|
|
|
RoutingType,
|
|
|
|
EventVisibility,
|
|
|
|
} from "@/types/enums";
|
2020-02-18 08:57:00 +01:00
|
|
|
import {
|
|
|
|
EVENT_PERSON_PARTICIPATION,
|
2022-09-20 16:53:26 +02:00
|
|
|
// EVENT_PERSON_PARTICIPATION_SUBSCRIPTION_CHANGED,
|
2022-08-12 16:46:44 +02:00
|
|
|
} from "@/graphql/event";
|
2022-10-31 18:05:59 +01:00
|
|
|
import {
|
|
|
|
displayName,
|
|
|
|
IActor,
|
|
|
|
IPerson,
|
|
|
|
usernameWithDomain,
|
|
|
|
} from "@/types/actor";
|
2022-08-12 16:46:44 +02:00
|
|
|
import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue";
|
2022-10-31 18:05:59 +01:00
|
|
|
import Earth from "vue-material-design-icons/Earth.vue";
|
|
|
|
import Link from "vue-material-design-icons/Link.vue";
|
2022-08-12 16:46:44 +02:00
|
|
|
import MultiCard from "@/components/Event/MultiCard.vue";
|
|
|
|
import RouteName from "@/router/name";
|
|
|
|
import CommentTree from "@/components/Comment/CommentTree.vue";
|
2020-02-18 08:57:00 +01:00
|
|
|
import "intersection-observer";
|
2022-09-20 16:53:26 +02:00
|
|
|
import Tag from "@/components/TagElement.vue";
|
2022-08-12 16:46:44 +02:00
|
|
|
import EventMetadataSidebar from "@/components/Event/EventMetadataSidebar.vue";
|
|
|
|
import EventBanner from "@/components/Event/EventBanner.vue";
|
2022-10-11 17:48:58 +02:00
|
|
|
import EventActionSection from "@/components/Event/EventActionSection.vue";
|
2022-08-12 16:46:44 +02:00
|
|
|
import PopoverActorCard from "@/components/Account/PopoverActorCard.vue";
|
2021-08-09 14:26:11 +02:00
|
|
|
import { IEventMetadataDescription } from "@/types/event-metadata";
|
2022-08-12 16:46:44 +02:00
|
|
|
import { eventMetaDataList } from "@/services/EventMetadata";
|
2022-10-11 17:48:58 +02:00
|
|
|
import { useFetchEvent } from "@/composition/apollo/event";
|
2022-07-12 10:55:28 +02:00
|
|
|
import {
|
|
|
|
computed,
|
|
|
|
onMounted,
|
|
|
|
ref,
|
|
|
|
watch,
|
|
|
|
defineAsyncComponent,
|
|
|
|
inject,
|
|
|
|
} from "vue";
|
|
|
|
import { useRoute, useRouter } from "vue-router";
|
|
|
|
import {
|
|
|
|
useCurrentActorClient,
|
|
|
|
usePersonStatusGroup,
|
|
|
|
} from "@/composition/apollo/actor";
|
|
|
|
import { useLoggedUser } from "@/composition/apollo/user";
|
2022-10-11 17:48:58 +02:00
|
|
|
import { useQuery } from "@vue/apollo-composable";
|
2022-07-12 10:55:28 +02:00
|
|
|
import {
|
|
|
|
useEventCategories,
|
2022-09-20 16:53:26 +02:00
|
|
|
useRoutingType,
|
2022-07-12 10:55:28 +02:00
|
|
|
} from "@/composition/apollo/config";
|
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
import { Notifier } from "@/plugins/notifier";
|
2022-08-26 16:08:58 +02:00
|
|
|
import { AbsintheGraphQLErrors } from "@/types/errors.model";
|
|
|
|
import { useHead } from "@vueuse/head";
|
2022-07-12 10:55:28 +02:00
|
|
|
|
|
|
|
const IntegrationTwitch = defineAsyncComponent(
|
2022-08-26 16:08:58 +02:00
|
|
|
() => import("@/components/Event/Integrations/TwitchIntegration.vue")
|
2022-07-12 10:55:28 +02:00
|
|
|
);
|
|
|
|
const IntegrationPeertube = defineAsyncComponent(
|
2022-08-26 16:08:58 +02:00
|
|
|
() => import("@/components/Event/Integrations/PeerTubeIntegration.vue")
|
2022-07-12 10:55:28 +02:00
|
|
|
);
|
|
|
|
const IntegrationYoutube = defineAsyncComponent(
|
2022-08-26 16:08:58 +02:00
|
|
|
() => import("@/components/Event/Integrations/YouTubeIntegration.vue")
|
2022-07-12 10:55:28 +02:00
|
|
|
);
|
|
|
|
const IntegrationJitsiMeet = defineAsyncComponent(
|
2022-08-26 16:08:58 +02:00
|
|
|
() => import("@/components/Event/Integrations/JitsiMeetIntegration.vue")
|
2022-07-12 10:55:28 +02:00
|
|
|
);
|
|
|
|
const IntegrationEtherpad = defineAsyncComponent(
|
2022-08-26 16:08:58 +02:00
|
|
|
() => import("@/components/Event/Integrations/EtherpadIntegration.vue")
|
2022-07-12 10:55:28 +02:00
|
|
|
);
|
2022-10-05 12:13:19 +02:00
|
|
|
const EventMap = defineAsyncComponent(
|
|
|
|
() => import("@/components/Event/EventMap.vue")
|
|
|
|
);
|
2022-07-12 10:55:28 +02:00
|
|
|
|
|
|
|
const props = defineProps<{
|
|
|
|
uuid: string;
|
|
|
|
}>();
|
|
|
|
|
|
|
|
const { t } = useI18n({ useScope: "global" });
|
|
|
|
|
2022-11-21 11:52:41 +01:00
|
|
|
const propsUUID = computed(() => props.uuid)
|
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
const {
|
|
|
|
event,
|
|
|
|
onError: onFetchEventError,
|
|
|
|
loading: eventLoading,
|
2022-11-21 11:52:41 +01:00
|
|
|
refetch: refetchEvent,
|
2022-07-12 10:55:28 +02:00
|
|
|
} = useFetchEvent(props.uuid);
|
2022-11-21 11:52:41 +01:00
|
|
|
|
|
|
|
watch(propsUUID, (newUUid) => {
|
|
|
|
refetchEvent({ uuid: newUUid })
|
|
|
|
})
|
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
const eventId = computed(() => event.value?.id);
|
|
|
|
const { currentActor } = useCurrentActorClient();
|
|
|
|
const currentActorId = computed(() => currentActor.value?.id);
|
|
|
|
const { loggedUser } = useLoggedUser();
|
|
|
|
const {
|
|
|
|
result: participationsResult,
|
2022-09-20 16:53:26 +02:00
|
|
|
// subscribeToMore: subscribeToMoreParticipation,
|
2022-07-12 10:55:28 +02:00
|
|
|
} = useQuery<{ person: IPerson }>(
|
|
|
|
EVENT_PERSON_PARTICIPATION,
|
|
|
|
() => ({
|
|
|
|
eventId: event.value?.id,
|
|
|
|
actorId: currentActorId.value,
|
|
|
|
}),
|
|
|
|
() => ({
|
|
|
|
enabled:
|
|
|
|
currentActorId.value !== undefined &&
|
|
|
|
currentActorId.value !== null &&
|
|
|
|
eventId.value !== undefined,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
// subscribeToMoreParticipation(() => ({
|
|
|
|
// document: EVENT_PERSON_PARTICIPATION_SUBSCRIPTION_CHANGED,
|
|
|
|
// variables: {
|
|
|
|
// eventId: eventId,
|
|
|
|
// actorId: currentActorId,
|
|
|
|
// },
|
|
|
|
// }));
|
|
|
|
|
|
|
|
const participations = computed(
|
2022-09-20 16:53:26 +02:00
|
|
|
() => participationsResult.value?.person.participations?.elements ?? []
|
2022-07-12 10:55:28 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
const { person } = usePersonStatusGroup(
|
|
|
|
usernameWithDomain(event.value?.attributedTo)
|
|
|
|
);
|
|
|
|
|
|
|
|
const { eventCategories } = useEventCategories();
|
|
|
|
|
|
|
|
// metaInfo() {
|
|
|
|
// return {
|
|
|
|
// // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
|
// // @ts-ignore
|
|
|
|
// title: this.eventTitle,
|
|
|
|
// meta: [
|
|
|
|
// // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
|
// // @ts-ignore
|
|
|
|
// { name: "description", content: this.eventDescription },
|
|
|
|
// ],
|
|
|
|
// };
|
|
|
|
// },
|
|
|
|
|
2022-09-20 16:53:26 +02:00
|
|
|
const identity = ref<IPerson | undefined | null>(null);
|
2022-07-12 10:55:28 +02:00
|
|
|
|
|
|
|
const oldParticipationRole = ref<string | undefined>(undefined);
|
|
|
|
|
|
|
|
const observer = ref<IntersectionObserver | null>(null);
|
|
|
|
const commentsObserver = ref<Element | null>(null);
|
|
|
|
|
|
|
|
const loadComments = ref(false);
|
|
|
|
|
|
|
|
const eventTitle = computed((): undefined | string => {
|
|
|
|
return event.value?.title;
|
|
|
|
});
|
|
|
|
|
|
|
|
const eventDescription = computed((): undefined | string => {
|
|
|
|
return event.value?.description;
|
|
|
|
});
|
|
|
|
|
|
|
|
const route = useRoute();
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
const eventDescriptionElement = ref<HTMLElement | null>(null);
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
identity.value = currentActor.value;
|
|
|
|
if (route.hash.includes("#comment-")) {
|
|
|
|
loadComments.value = true;
|
2019-10-14 12:56:37 +02:00
|
|
|
}
|
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
observer.value = new IntersectionObserver(
|
|
|
|
(entries) => {
|
|
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
|
|
for (const entry of entries) {
|
|
|
|
if (entry) {
|
|
|
|
loadComments.value = entry.isIntersecting || loadComments.value;
|
|
|
|
}
|
2019-12-20 13:04:34 +01:00
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
rootMargin: "-50px 0px -50px",
|
2019-12-20 13:04:34 +01:00
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
);
|
|
|
|
if (commentsObserver.value) {
|
|
|
|
observer.value.observe(commentsObserver.value);
|
|
|
|
}
|
2019-12-20 13:04:34 +01:00
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
watch(eventDescription, () => {
|
|
|
|
if (!eventDescription.value) return;
|
|
|
|
if (!eventDescriptionElement.value) return;
|
|
|
|
|
|
|
|
eventDescriptionElement.value.addEventListener("click", ($event) => {
|
|
|
|
// TODO: Find the right type for target
|
|
|
|
let { target }: { target: any } = $event;
|
|
|
|
while (target && target.tagName !== "A") target = target.parentNode;
|
|
|
|
// handle only links that occur inside the component and do not reference external resources
|
|
|
|
if (target && target.matches(".hashtag") && target.href) {
|
|
|
|
// some sanity checks taken from vue-router:
|
|
|
|
// https://github.com/vuejs/vue-router/blob/dev/src/components/link.js#L106
|
|
|
|
const { altKey, ctrlKey, metaKey, shiftKey, button, defaultPrevented } =
|
|
|
|
$event;
|
|
|
|
// don't handle with control keys
|
|
|
|
if (metaKey || altKey || ctrlKey || shiftKey) return;
|
|
|
|
// don't handle when preventDefault called
|
|
|
|
if (defaultPrevented) return;
|
|
|
|
// don't handle right clicks
|
|
|
|
if (button !== undefined && button !== 0) return;
|
|
|
|
// don't handle if `target="_blank"`
|
|
|
|
if (target && target.getAttribute) {
|
|
|
|
const linkTarget = target.getAttribute("target");
|
|
|
|
if (/\b_blank\b/i.test(linkTarget)) return;
|
2019-11-15 18:36:47 +01:00
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
// don't handle same page links/anchors
|
|
|
|
const url = new URL(target.href);
|
|
|
|
const to = url.pathname;
|
|
|
|
if (window.location.pathname !== to && $event.preventDefault) {
|
|
|
|
$event.preventDefault();
|
|
|
|
router.push(to);
|
2019-10-23 12:36:11 +02:00
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
}
|
2020-06-25 11:38:12 +02:00
|
|
|
});
|
2022-07-12 10:55:28 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
// this.$on("event-deleted", () => {
|
|
|
|
// return router.push({ name: RouteName.HOME });
|
|
|
|
// });
|
|
|
|
});
|
|
|
|
|
2022-09-20 16:53:26 +02:00
|
|
|
const notifier = inject<Notifier>("notifier");
|
2019-10-11 15:06:58 +02:00
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
watch(participations, () => {
|
|
|
|
if (participations.value.length > 0) {
|
|
|
|
if (
|
|
|
|
oldParticipationRole.value &&
|
|
|
|
participations.value[0].role !== ParticipantRole.NOT_APPROVED &&
|
|
|
|
oldParticipationRole.value !== participations.value[0].role
|
|
|
|
) {
|
|
|
|
switch (participations.value[0].role) {
|
|
|
|
case ParticipantRole.PARTICIPANT:
|
|
|
|
participationConfirmedMessage();
|
|
|
|
break;
|
|
|
|
case ParticipantRole.REJECTED:
|
|
|
|
participationRejectedMessage();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
participationChangedMessage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
oldParticipationRole.value = participations.value[0].role;
|
2019-10-11 15:06:58 +02:00
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
const participationConfirmedMessage = () => {
|
|
|
|
notifier?.success(t("Your participation has been confirmed"));
|
|
|
|
};
|
|
|
|
|
|
|
|
const participationRejectedMessage = () => {
|
|
|
|
notifier?.error(t("Your participation has been rejected"));
|
|
|
|
};
|
|
|
|
|
|
|
|
const participationChangedMessage = () => {
|
|
|
|
notifier?.info(t("Your participation status has been changed"));
|
|
|
|
};
|
|
|
|
|
2022-08-26 16:08:58 +02:00
|
|
|
const handleErrors = (errors: AbsintheGraphQLErrors): void => {
|
2022-07-12 10:55:28 +02:00
|
|
|
if (
|
|
|
|
errors.some((error) => error.status_code === 404) ||
|
|
|
|
errors.some(({ message }) => message.includes("has invalid value $uuid"))
|
|
|
|
) {
|
|
|
|
router.replace({ name: RouteName.PAGE_NOT_FOUND });
|
2019-12-20 13:04:34 +01:00
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
};
|
|
|
|
|
2022-08-26 16:08:58 +02:00
|
|
|
onFetchEventError(({ graphQLErrors }) =>
|
|
|
|
handleErrors(graphQLErrors as AbsintheGraphQLErrors)
|
|
|
|
);
|
2022-07-12 10:55:28 +02:00
|
|
|
|
2022-11-04 11:28:56 +01:00
|
|
|
const metadataToComponent: Record<string, any> = {
|
|
|
|
"mz:live:twitch:url": IntegrationTwitch,
|
|
|
|
"mz:live:peertube:url": IntegrationPeertube,
|
|
|
|
"mz:live:youtube:url": IntegrationYoutube,
|
|
|
|
"mz:visio:jitsi_meet": IntegrationJitsiMeet,
|
|
|
|
"mz:notes:etherpad:url": IntegrationEtherpad,
|
2022-07-12 10:55:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const integrations = computed((): Record<string, IEventMetadataDescription> => {
|
|
|
|
return (event.value?.metadata ?? [])
|
|
|
|
.map((val) => {
|
|
|
|
const def = eventMetaDataList.find((dat) => dat.key === val.key);
|
|
|
|
return {
|
|
|
|
...def,
|
|
|
|
...val,
|
|
|
|
};
|
|
|
|
})
|
|
|
|
.reduce((acc: Record<string, IEventMetadataDescription>, metadata) => {
|
|
|
|
const component = metadataToComponent[metadata.key];
|
|
|
|
if (component !== undefined) {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
|
// @ts-ignore
|
2022-11-04 11:28:56 +01:00
|
|
|
acc[metadata.key] = metadata;
|
2022-07-12 10:55:28 +02:00
|
|
|
}
|
|
|
|
return acc;
|
|
|
|
}, {});
|
|
|
|
});
|
2021-10-10 16:25:50 +02:00
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
const showMap = ref(false);
|
2021-10-10 16:25:50 +02:00
|
|
|
|
2022-09-20 16:53:26 +02:00
|
|
|
const { routingType } = useRoutingType();
|
2022-03-28 17:42:59 +02:00
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
const eventCategory = computed((): string | undefined => {
|
|
|
|
if (event.value?.category === "MEETING") {
|
|
|
|
return undefined;
|
2022-03-28 17:42:59 +02:00
|
|
|
}
|
2022-09-20 16:53:26 +02:00
|
|
|
return (eventCategories.value ?? []).find((eventCategoryToFind) => {
|
|
|
|
return eventCategoryToFind.id === event.value?.category;
|
2022-07-12 10:55:28 +02:00
|
|
|
})?.label as string;
|
|
|
|
});
|
2022-08-26 16:08:58 +02:00
|
|
|
|
2022-10-31 18:05:59 +01:00
|
|
|
const organizer = computed((): IActor | null => {
|
|
|
|
if (event.value?.attributedTo?.id) {
|
|
|
|
return event.value.attributedTo;
|
|
|
|
}
|
|
|
|
if (event.value?.organizerActor) {
|
|
|
|
return event.value.organizerActor;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
|
|
|
|
const organizerDomain = computed((): string | undefined => {
|
|
|
|
return organizer.value?.domain ?? undefined;
|
|
|
|
});
|
|
|
|
|
2022-08-26 16:08:58 +02:00
|
|
|
useHead({
|
|
|
|
title: computed(() => eventTitle.value ?? ""),
|
|
|
|
meta: [{ name: "description", content: eventDescription.value }],
|
|
|
|
});
|
2019-01-21 15:08:22 +01:00
|
|
|
</script>
|
2022-10-31 11:43:18 +01:00
|
|
|
<style>
|
|
|
|
.event-description a {
|
|
|
|
@apply inline-block p-1 bg-mbz-yellow-alt-200 text-black;
|
2021-06-10 10:05:47 +02:00
|
|
|
}
|
2019-03-22 17:35:07 +01:00
|
|
|
</style>
|