remaining location and event image related changes from fomo

Co-authored-by: unkonkret <unkonkret@systemli.org>
This commit is contained in:
778a69cd 2023-03-15 19:28:05 +01:00
parent dea5e5d24c
commit 1bcf288c14
2 changed files with 270 additions and 32 deletions

View file

@ -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>

View file

@ -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="map-show-button" class="addressDescription"
@click="$emit('showMapModal', true)" :title="physicalAddress.poiInfos.name"
v-if="physicalAddress.geom" >
{{ physicalAddress.poiInfos.name }}
</p>
<p class="has-text-grey-dark">
{{ physicalAddress.poiInfos.alternativeName }}
</p>
</address>
</div>
<span
class="map-show-button"
@click="showMap = !showMap"
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>