remaining location and event image related changes from fomo
Co-authored-by: unkonkret <unkonkret@systemli.org>
This commit is contained in:
parent
63bc5b2504
commit
d2a6e631d0
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="truncate"
|
class="ellipsis"
|
||||||
:title="
|
:title="
|
||||||
isDescriptionDifferentFromLocality
|
isDescriptionDifferentFromLocality
|
||||||
? `${physicalAddress.description}, ${physicalAddress.locality}`
|
? `${physicalAddress.description}, ${physicalAddress.locality}`
|
||||||
|
@ -8,8 +8,10 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<b-icon icon="map-marker" />
|
<b-icon icon="map-marker" />
|
||||||
<span v-if="physicalAddress.locality">
|
<span v-if="isDescriptionDifferentFromLocality">
|
||||||
{{ physicalAddress.locality }}
|
<b>{{ physicalAddress.locality }}</b
|
||||||
|
>,
|
||||||
|
{{ physicalAddress.description }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
{{ physicalAddress.description }}
|
{{ physicalAddress.description }}
|
||||||
|
@ -34,3 +36,12 @@ export default class InlineAddress extends Vue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.ellipsis {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 1;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #9e9ef2;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,22 +1,31 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<event-metadata-block
|
<event-metadata-block
|
||||||
v-if="!event.options.isOnline"
|
|
||||||
:title="$t('Location')"
|
:title="$t('Location')"
|
||||||
:icon="physicalAddress ? physicalAddress.poiInfos.poiIcon.icon : 'earth'"
|
:icon="physicalAddress ? physicalAddress.poiInfos.poiIcon.icon : 'earth'"
|
||||||
>
|
>
|
||||||
<div class="address-wrapper">
|
<div class="address-wrapper">
|
||||||
<span v-if="!physicalAddress">{{ $t("No address defined") }}</span>
|
<span v-if="!physicalAddress">{{ $t("No address defined") }}</span>
|
||||||
<div class="address" v-if="physicalAddress">
|
<div class="address" v-if="physicalAddress">
|
||||||
<address-info :address="physicalAddress" />
|
<div>
|
||||||
<b-button
|
<address>
|
||||||
type="is-text"
|
<p
|
||||||
|
class="addressDescription"
|
||||||
|
:title="physicalAddress.poiInfos.name"
|
||||||
|
>
|
||||||
|
{{ physicalAddress.poiInfos.name }}
|
||||||
|
</p>
|
||||||
|
<p class="has-text-grey-dark">
|
||||||
|
{{ physicalAddress.poiInfos.alternativeName }}
|
||||||
|
</p>
|
||||||
|
</address>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
class="map-show-button"
|
class="map-show-button"
|
||||||
@click="$emit('showMapModal', true)"
|
@click="showMap = !showMap"
|
||||||
v-if="physicalAddress.geom"
|
v-if="physicalAddress.geom"
|
||||||
|
>{{ $t("Show map") }}</span
|
||||||
>
|
>
|
||||||
{{ $t("Show map") }}
|
|
||||||
</b-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</event-metadata-block>
|
</event-metadata-block>
|
||||||
|
@ -25,8 +34,6 @@
|
||||||
:beginsOn="event.beginsOn"
|
:beginsOn="event.beginsOn"
|
||||||
:show-start-time="event.options.showStartTime"
|
:show-start-time="event.options.showStartTime"
|
||||||
:show-end-time="event.options.showEndTime"
|
:show-end-time="event.options.showEndTime"
|
||||||
:timezone="event.options.timezone"
|
|
||||||
:userTimezone="userTimezone"
|
|
||||||
:endsOn="event.endsOn"
|
:endsOn="event.endsOn"
|
||||||
/>
|
/>
|
||||||
</event-metadata-block>
|
</event-metadata-block>
|
||||||
|
@ -34,9 +41,14 @@
|
||||||
class="metadata-organized-by"
|
class="metadata-organized-by"
|
||||||
:title="$t('Organized by')"
|
:title="$t('Organized by')"
|
||||||
>
|
>
|
||||||
|
<popover-actor-card
|
||||||
|
:actor="event.organizerActor"
|
||||||
|
v-if="!event.attributedTo"
|
||||||
|
>
|
||||||
|
<actor-card :actor="event.organizerActor" />
|
||||||
|
</popover-actor-card>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="event.attributedTo"
|
v-if="event.attributedTo"
|
||||||
class="hover:underline"
|
|
||||||
:to="{
|
:to="{
|
||||||
name: RouteName.GROUP,
|
name: RouteName.GROUP,
|
||||||
params: {
|
params: {
|
||||||
|
@ -44,21 +56,23 @@
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<actor-card
|
<popover-actor-card
|
||||||
|
:actor="event.attributedTo"
|
||||||
v-if="
|
v-if="
|
||||||
!event.attributedTo || !event.options.hideOrganizerWhenGroupEvent
|
!event.attributedTo || !event.options.hideOrganizerWhenGroupEvent
|
||||||
"
|
"
|
||||||
:actor="event.attributedTo"
|
>
|
||||||
:inline="true"
|
<actor-card :actor="event.attributedTo" />
|
||||||
/>
|
</popover-actor-card>
|
||||||
</router-link>
|
</router-link>
|
||||||
<actor-card v-else :actor="event.organizerActor" :inline="true" />
|
|
||||||
<actor-card
|
<popover-actor-card
|
||||||
:inline="true"
|
|
||||||
:actor="contact"
|
:actor="contact"
|
||||||
v-for="contact in event.contacts"
|
v-for="contact in event.contacts"
|
||||||
:key="contact.id"
|
:key="contact.id"
|
||||||
/>
|
>
|
||||||
|
<actor-card :actor="contact" />
|
||||||
|
</popover-actor-card>
|
||||||
</event-metadata-block>
|
</event-metadata-block>
|
||||||
<event-metadata-block
|
<event-metadata-block
|
||||||
v-if="event.onlineAddress && urlToHostname(event.onlineAddress)"
|
v-if="event.onlineAddress && urlToHostname(event.onlineAddress)"
|
||||||
|
@ -67,7 +81,6 @@
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="hover:underline"
|
|
||||||
rel="noopener noreferrer ugc"
|
rel="noopener noreferrer ugc"
|
||||||
:href="event.onlineAddress"
|
:href="event.onlineAddress"
|
||||||
:title="
|
:title="
|
||||||
|
@ -127,12 +140,109 @@
|
||||||
>
|
>
|
||||||
<span v-else>{{ extra.value }}</span>
|
<span v-else>{{ extra.value }}</span>
|
||||||
</event-metadata-block>
|
</event-metadata-block>
|
||||||
|
<div v-if="event.picture">
|
||||||
|
<h2>{{ $t("Headline picture") }}</h2>
|
||||||
|
<div style="position: relative" @click="showImage = true">
|
||||||
|
<img :src="event.picture.url" style="width: 100%" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<b-modal v-if="event.picture" :active.sync="showImage" has-modal-card>
|
||||||
|
<div>
|
||||||
|
<header class="modal-card-head">{{ $t("Headline picture") }}</header>
|
||||||
|
<section
|
||||||
|
class="modal-card"
|
||||||
|
style="width: auto; -webkit-overflow-scrolling: touch; overflow: auto"
|
||||||
|
>
|
||||||
|
<img :src="event.picture.url" />
|
||||||
|
</section>
|
||||||
|
<footer class="modal-card-foot"></footer>
|
||||||
|
</div>
|
||||||
|
</b-modal>
|
||||||
|
<b-modal
|
||||||
|
class="map-modal"
|
||||||
|
v-if="physicalAddress && physicalAddress.geom"
|
||||||
|
:active.sync="showMap"
|
||||||
|
has-modal-card
|
||||||
|
full-screen
|
||||||
|
>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<button type="button" class="delete" @click="showMap = false" />
|
||||||
|
</header>
|
||||||
|
<div class="modal-card-body">
|
||||||
|
<section class="map">
|
||||||
|
<map-leaflet
|
||||||
|
:coords="physicalAddress.geom"
|
||||||
|
:marker="{
|
||||||
|
text: physicalAddress.fullName,
|
||||||
|
icon: physicalAddress.poiInfos.poiIcon.icon,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
<section class="columns is-centered map-footer">
|
||||||
|
<div class="column is-half has-text-centered">
|
||||||
|
<p class="address">
|
||||||
|
<i class="mdi mdi-map-marker"></i>
|
||||||
|
{{ physicalAddress.fullName }}
|
||||||
|
</p>
|
||||||
|
<p class="getting-there">{{ $t("Getting there") }}</p>
|
||||||
|
<div
|
||||||
|
class="buttons"
|
||||||
|
v-if="
|
||||||
|
addressLinkToRouteByCar ||
|
||||||
|
addressLinkToRouteByBike ||
|
||||||
|
addressLinkToRouteByFeet
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="button"
|
||||||
|
target="_blank"
|
||||||
|
v-if="addressLinkToRouteByFeet"
|
||||||
|
:href="addressLinkToRouteByFeet"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-walk"></i
|
||||||
|
></a>
|
||||||
|
<a
|
||||||
|
class="button"
|
||||||
|
target="_blank"
|
||||||
|
v-if="addressLinkToRouteByBike"
|
||||||
|
:href="addressLinkToRouteByBike"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-bike"></i
|
||||||
|
></a>
|
||||||
|
<a
|
||||||
|
class="button"
|
||||||
|
target="_blank"
|
||||||
|
v-if="addressLinkToRouteByTransit"
|
||||||
|
:href="addressLinkToRouteByTransit"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-bus"></i
|
||||||
|
></a>
|
||||||
|
<a
|
||||||
|
class="button"
|
||||||
|
target="_blank"
|
||||||
|
v-if="addressLinkToRouteByCar"
|
||||||
|
:href="addressLinkToRouteByCar"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-car"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</b-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Address } from "@/types/address.model";
|
import { Address } from "@/types/address.model";
|
||||||
import { IConfig } from "@/types/config.model";
|
import { IConfig } from "@/types/config.model";
|
||||||
import { EventMetadataKeyType, EventMetadataType } from "@/types/enums";
|
import {
|
||||||
|
EventMetadataKeyType,
|
||||||
|
EventMetadataType,
|
||||||
|
RoutingTransportationType,
|
||||||
|
RoutingType,
|
||||||
|
} from "@/types/enums";
|
||||||
import { IEvent } from "@/types/event.model";
|
import { IEvent } from "@/types/event.model";
|
||||||
import { PropType } from "vue";
|
import { PropType } from "vue";
|
||||||
import { Component, Prop, Vue } from "vue-property-decorator";
|
import { Component, Prop, Vue } from "vue-property-decorator";
|
||||||
|
@ -142,13 +252,11 @@ import EventMetadataBlock from "./EventMetadataBlock.vue";
|
||||||
import EventFullDate from "./EventFullDate.vue";
|
import EventFullDate from "./EventFullDate.vue";
|
||||||
import PopoverActorCard from "../Account/PopoverActorCard.vue";
|
import PopoverActorCard from "../Account/PopoverActorCard.vue";
|
||||||
import ActorCard from "../../components/Account/ActorCard.vue";
|
import ActorCard from "../../components/Account/ActorCard.vue";
|
||||||
import AddressInfo from "../../components/Address/AddressInfo.vue";
|
|
||||||
import {
|
import {
|
||||||
IEventMetadata,
|
IEventMetadata,
|
||||||
IEventMetadataDescription,
|
IEventMetadataDescription,
|
||||||
} from "@/types/event-metadata";
|
} from "@/types/event-metadata";
|
||||||
import { eventMetaDataList } from "../../services/EventMetadata";
|
import { eventMetaDataList } from "../../services/EventMetadata";
|
||||||
import { IUser } from "@/types/current-user.model";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
|
@ -156,14 +264,17 @@ import { IUser } from "@/types/current-user.model";
|
||||||
EventFullDate,
|
EventFullDate,
|
||||||
PopoverActorCard,
|
PopoverActorCard,
|
||||||
ActorCard,
|
ActorCard,
|
||||||
AddressInfo,
|
"map-leaflet": () =>
|
||||||
|
import(/* webpackChunkName: "map" */ "../../components/Map.vue"),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class EventMetadataSidebar extends Vue {
|
export default class EventMetadataSidebar extends Vue {
|
||||||
@Prop({ type: Object as PropType<IEvent>, required: true }) event!: IEvent;
|
@Prop({ type: Object as PropType<IEvent>, required: true }) event!: IEvent;
|
||||||
@Prop({ type: Object as PropType<IConfig>, required: true }) config!: IConfig;
|
@Prop({ type: Object as PropType<IConfig>, required: true }) config!: IConfig;
|
||||||
@Prop({ required: true }) user!: IUser | undefined;
|
|
||||||
@Prop({ required: false, default: false }) showMap!: boolean;
|
showImage = false;
|
||||||
|
|
||||||
|
showMap = false;
|
||||||
|
|
||||||
RouteName = RouteName;
|
RouteName = RouteName;
|
||||||
|
|
||||||
|
@ -174,6 +285,21 @@ export default class EventMetadataSidebar extends Vue {
|
||||||
EventMetadataType = EventMetadataType;
|
EventMetadataType = EventMetadataType;
|
||||||
EventMetadataKeyType = EventMetadataKeyType;
|
EventMetadataKeyType = EventMetadataKeyType;
|
||||||
|
|
||||||
|
RoutingParamType = {
|
||||||
|
[RoutingType.OPENSTREETMAP]: {
|
||||||
|
[RoutingTransportationType.FOOT]: "engine=fossgis_osrm_foot",
|
||||||
|
[RoutingTransportationType.BIKE]: "engine=fossgis_osrm_bike",
|
||||||
|
[RoutingTransportationType.TRANSIT]: null,
|
||||||
|
[RoutingTransportationType.CAR]: "engine=fossgis_osrm_car",
|
||||||
|
},
|
||||||
|
[RoutingType.GOOGLE_MAPS]: {
|
||||||
|
[RoutingTransportationType.FOOT]: "dirflg=w",
|
||||||
|
[RoutingTransportationType.BIKE]: "dirflg=b",
|
||||||
|
[RoutingTransportationType.TRANSIT]: "dirflg=r",
|
||||||
|
[RoutingTransportationType.CAR]: "driving",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
get physicalAddress(): Address | null {
|
get physicalAddress(): Address | null {
|
||||||
if (!this.event.physicalAddress) return null;
|
if (!this.event.physicalAddress) return null;
|
||||||
|
|
||||||
|
@ -190,6 +316,50 @@ export default class EventMetadataSidebar extends Vue {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
makeNavigationPath(
|
||||||
|
transportationType: RoutingTransportationType
|
||||||
|
): string | undefined {
|
||||||
|
const geometry = this.physicalAddress?.geom;
|
||||||
|
if (geometry) {
|
||||||
|
const routingType = this.config.maps.routing.type;
|
||||||
|
/**
|
||||||
|
* build urls to routing map
|
||||||
|
*/
|
||||||
|
if (!this.RoutingParamType[routingType][transportationType]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const urlGeometry = geometry.split(";").reverse().join(",");
|
||||||
|
|
||||||
|
switch (routingType) {
|
||||||
|
case RoutingType.GOOGLE_MAPS:
|
||||||
|
return `https://maps.google.com/?saddr=Current+Location&daddr=${urlGeometry}&${this.RoutingParamType[routingType][transportationType]}`;
|
||||||
|
case RoutingType.OPENSTREETMAP:
|
||||||
|
default: {
|
||||||
|
const bboxX = geometry.split(";").reverse()[0];
|
||||||
|
const bboxY = geometry.split(";").reverse()[1];
|
||||||
|
return `https://www.openstreetmap.org/directions?from=&to=${urlGeometry}&${this.RoutingParamType[routingType][transportationType]}#map=14/${bboxX}/${bboxY}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get addressLinkToRouteByCar(): undefined | string {
|
||||||
|
return this.makeNavigationPath(RoutingTransportationType.CAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
get addressLinkToRouteByBike(): undefined | string {
|
||||||
|
return this.makeNavigationPath(RoutingTransportationType.BIKE);
|
||||||
|
}
|
||||||
|
|
||||||
|
get addressLinkToRouteByFeet(): undefined | string {
|
||||||
|
return this.makeNavigationPath(RoutingTransportationType.FOOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
get addressLinkToRouteByTransit(): undefined | string {
|
||||||
|
return this.makeNavigationPath(RoutingTransportationType.TRANSIT);
|
||||||
|
}
|
||||||
|
|
||||||
urlToHostname(url: string): string | null {
|
urlToHostname(url: string): string | null {
|
||||||
try {
|
try {
|
||||||
return new URL(url).hostname;
|
return new URL(url).hostname;
|
||||||
|
@ -222,10 +392,6 @@ export default class EventMetadataSidebar extends Vue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get userTimezone(): string | undefined {
|
|
||||||
return this.user?.settings?.timezone;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -244,6 +410,23 @@ export default class EventMetadataSidebar extends Vue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $violet-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-container {
|
||||||
|
width: 60vw;
|
||||||
|
height: 60vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.object-cover {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
div.address-wrapper {
|
div.address-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -255,6 +438,50 @@ div.address-wrapper {
|
||||||
.map-show-button {
|
.map-show-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
address {
|
||||||
|
font-style: normal;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
span.addressDescription {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex: 1 0 auto;
|
||||||
|
min-width: 100%;
|
||||||
|
max-width: 4rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:not(.addressDescription) {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-modal {
|
||||||
|
.modal-card-head {
|
||||||
|
justify-content: flex-end;
|
||||||
|
button.delete {
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
section.map {
|
||||||
|
height: calc(100% - 8rem);
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.map-footer {
|
||||||
|
p.address {
|
||||||
|
margin: 1rem auto;
|
||||||
|
}
|
||||||
|
div.buttons {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue