Implementace photoswipe
This commit is contained in:
@@ -19,6 +19,8 @@
|
|||||||
"chart.js": "^4.4.0",
|
"chart.js": "^4.4.0",
|
||||||
"graphql": "16.6.0",
|
"graphql": "16.6.0",
|
||||||
"graphql-tag": "2.12.6",
|
"graphql-tag": "2.12.6",
|
||||||
|
"photoswipe": "^5.4.2",
|
||||||
|
"photoswipe-dynamic-caption-plugin": "^1.2.7",
|
||||||
"pinia": "^2.0.33",
|
"pinia": "^2.0.33",
|
||||||
"quasar": "^2.12.0",
|
"quasar": "^2.12.0",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<script setup>
|
||||||
|
import {formatDatetime} from "src/composables/datetimeUtils";
|
||||||
|
import {roundWithPrecision} from "src/composables/utils";
|
||||||
|
import EmbeddedMap from "components/map/EmbeddedMap.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
photo: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="pswp-caption-content">
|
||||||
|
<strong v-if="photo.name !== ''">{{ photo.name }}</strong>
|
||||||
|
<article v-html="photo.description" v-if="photo.description !== ''"/>
|
||||||
|
<q-list>
|
||||||
|
<q-item v-if="photo.pointOfInterest">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-avatar icon="marker"></q-avatar>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
{{ photo.pointOfInterest.name }}
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item v-if="photo.exposedAt">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-avatar icon="photo_camera"></q-avatar>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
{{ formatDatetime(photo.exposedAt) }}
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item v-if="photo.gpsAltitude">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-avatar icon="height"/>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
Nadmořská výška: {{ roundWithPrecision(photo.gpsAltitude, 1) }} m
|
||||||
|
<br>
|
||||||
|
<template v-if="photo.terrainElevation">
|
||||||
|
Výška terénu: {{ roundWithPrecision(photo.terrainElevation, 1) }} m
|
||||||
|
<br>
|
||||||
|
Výška nad zemí: {{ roundWithPrecision(photo.gpsAltitude - photo.terrainElevation, 1) }} m
|
||||||
|
</template>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
|
||||||
|
|
||||||
|
<div style="height: 200px; width: 100%;">
|
||||||
|
<EmbeddedMap
|
||||||
|
v-if="photo.gpsLatitude && photo.gpsLongitude"
|
||||||
|
height="200px"
|
||||||
|
class="q-mb-sm"
|
||||||
|
:gps-latitude="photo.gpsLatitude"
|
||||||
|
:gps-longitude="photo.gpsLongitude"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
<script setup>
|
||||||
|
import {onMounted, onUnmounted, ref} from "vue";
|
||||||
|
import PhotoSwipeLightbox from "photoswipe/lightbox";
|
||||||
|
import 'photoswipe/style.css';
|
||||||
|
import "photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css";
|
||||||
|
import PhotoSwipeDynamicCaption from "photoswipe-dynamic-caption-plugin";
|
||||||
|
import MapWithMarkers from "components/map/MapWithMarkers.vue";
|
||||||
|
import {formatDatetime} from "src/composables/datetimeUtils";
|
||||||
|
import EmbeddedMap from "components/map/EmbeddedMap.vue";
|
||||||
|
import {roundWithPrecision} from "../../composables/utils";
|
||||||
|
import PhotoCaption from "components/photos/PhotoCaption.vue";
|
||||||
|
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
galleryId: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: () => "randomGalleryId"
|
||||||
|
},
|
||||||
|
photos: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let $lightbox = null;
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!$lightbox) {
|
||||||
|
$lightbox = new PhotoSwipeLightbox({
|
||||||
|
gallery: '#' + props.galleryId,
|
||||||
|
children: 'a',
|
||||||
|
pswpModule: () => import('photoswipe'),
|
||||||
|
});
|
||||||
|
|
||||||
|
let captionPlugin = new PhotoSwipeDynamicCaption($lightbox, {
|
||||||
|
type: 'auto',
|
||||||
|
});
|
||||||
|
|
||||||
|
// $lightbox.on('uiRegister', function () {
|
||||||
|
// $lightbox.pswp.ui.registerElement({
|
||||||
|
// name: 'test-button',
|
||||||
|
// order: 9,
|
||||||
|
// isButton: true,
|
||||||
|
// html: infoIcon,
|
||||||
|
// onClick: (event, el, pswp) => {
|
||||||
|
// for (const elem of document.querySelectorAll('.pswp__dynamic-caption')) {
|
||||||
|
// elem.style.display = "block";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // pswp.currSlide.dynamicCaption.element.style.display="block";
|
||||||
|
// // pswp.currSlide.dynamicCaption.element.hidden = false;
|
||||||
|
// pswp.dispatch("calcSlideSize", {slide: pswp.currSlide});
|
||||||
|
// pswp.currSlide.zoomAndPanToInitial();
|
||||||
|
//
|
||||||
|
// // captionPlugin.recalculateZoomLevelAndBounds(pswp.currSlide);
|
||||||
|
// // captionPlugin.storeAdjustedPanAreaSize(pswp.currSlide);
|
||||||
|
// // captionPlugin.storeOriginalPanAreaSize(pswp.currSlide);
|
||||||
|
// // window.resize();
|
||||||
|
// // captionPlugin.updateCaptionPosition(pswp.currSlide);
|
||||||
|
// // captionPlugin.adjustPanArea(pswp.currSlide, pswp.currSlide.zoomLevels.initial);
|
||||||
|
// // // captionPlugin.showCaption(pswp.currSlide);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
$lightbox.init();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
if ($lightbox) {
|
||||||
|
$lightbox.destroy();
|
||||||
|
$lightbox = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :id="galleryId" class="row">
|
||||||
|
<div class="col-6 col-sm-4 col-md-4 col-lg-3 q-pa-sm" v-for="photo in photos" :key="photo.id">
|
||||||
|
<a
|
||||||
|
:href="photo.url"
|
||||||
|
:data-pswp-width="photo.width"
|
||||||
|
:data-pswp-height="photo.height"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<q-img
|
||||||
|
spinner-color="primary"
|
||||||
|
class="rounded-borders"
|
||||||
|
:src="photo.thumbnailUrl"
|
||||||
|
alt=""
|
||||||
|
>
|
||||||
|
<div class="absolute-bottom" v-if="photo.name !== ''">
|
||||||
|
{{ photo.name }}
|
||||||
|
</div>
|
||||||
|
</q-img>
|
||||||
|
<PhotoCaption :photo="photo"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -3,33 +3,29 @@ import {computed, onMounted, reactive, ref, watch} from "vue";
|
|||||||
import {useQuasar} from "quasar";
|
import {useQuasar} from "quasar";
|
||||||
import {confirmObject} from "src/composables/dialog";
|
import {confirmObject} from "src/composables/dialog";
|
||||||
|
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
photos: {
|
photos: {
|
||||||
type: Array
|
type: Array
|
||||||
},
|
},
|
||||||
showActions: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const batchEdit = ref({});
|
const batchEdit = ref({});
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
for (const photo of props.photos) {
|
for (const photo of props.photos) {
|
||||||
batchEdit.value[photo.id] = false;
|
batchEdit.value[photo.id] = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits(["edit", "delete", "batch-edit", "batch-rotate", "photo-click"])
|
const emits = defineEmits(["edit", "delete", "batch-edit", "batch-rotate"])
|
||||||
|
|
||||||
const openEdit = (photo) => {
|
const openEdit = (photo) => {
|
||||||
emits("edit", photo);
|
emits("edit", photo);
|
||||||
};
|
};
|
||||||
|
|
||||||
const $q = useQuasar();
|
|
||||||
|
|
||||||
const confirmPhotoDelete = (id) => {
|
const confirmPhotoDelete = (id) => {
|
||||||
$q.dialog(confirmObject("Opravdu chces smazat tuto fotku?"))
|
$q.dialog(confirmObject("Opravdu chces smazat tuto fotku?"))
|
||||||
@@ -50,11 +46,7 @@ const confirmBatchPhotoDelete = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleImageClick = (photo, idx) => {
|
const handleImageClick = (photo, idx) => {
|
||||||
if (props.showActions) {
|
|
||||||
batchEdit.value[photo.id] = !batchEdit.value[photo.id];
|
batchEdit.value[photo.id] = !batchEdit.value[photo.id];
|
||||||
} else {
|
|
||||||
emits("photo-click", {photo, idx});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedPhotos = computed(() => {
|
const selectedPhotos = computed(() => {
|
||||||
@@ -133,13 +125,10 @@ const batchOptionsProps = computed(() => ({
|
|||||||
</div>
|
</div>
|
||||||
</q-img>
|
</q-img>
|
||||||
|
|
||||||
<q-card-actions v-if="showActions" align="right" :class="{'bg-primary': batchEdit[photo.id], 'text-white': batchEdit[photo.id]}">
|
<q-card-actions align="right" :class="{'bg-primary': batchEdit[photo.id], 'text-white': batchEdit[photo.id]}">
|
||||||
<div class="col-grow">
|
<div class="col-grow">
|
||||||
<q-checkbox v-model="batchEdit[photo.id]"/>
|
<q-checkbox v-model="batchEdit[photo.id]"/>
|
||||||
<q-icon name="star" v-if="photo.isFlightCover" color="red"/>
|
<q-icon name="star" v-if="photo.isFlightCover" color="red"/>
|
||||||
<q-icon name="place" v-if="photo.pointOfInterestId"/>
|
|
||||||
<q-icon name="gps_fixed" v-if="photo.gpsLatitude && photo.gpsLongitude"/>
|
|
||||||
<q-icon name="gps_off" v-else/>
|
|
||||||
</div>
|
</div>
|
||||||
<q-btn flat icon="edit" color="black" :to="{name: 'photoEditor', params: {id: photo.id}}"/>
|
<q-btn flat icon="edit" color="black" :to="{name: 'photoEditor', params: {id: photo.id}}"/>
|
||||||
<q-btn flat icon="info" color="blue" @click="openEdit(photo)"/>
|
<q-btn flat icon="info" color="blue" @click="openEdit(photo)"/>
|
||||||
@@ -149,7 +138,7 @@ const batchOptionsProps = computed(() => ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-page-sticky :offset="[50, 50]" position="bottom" v-if="showActions && photos.length > 0">
|
<q-page-sticky :offset="[50, 50]" position="bottom" v-if="photos.length > 0">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-actions>
|
<q-card-actions>
|
||||||
<q-checkbox v-model="checkAll" label="Vybrat vše"/>
|
<q-checkbox v-model="checkAll" label="Vybrat vše"/>
|
||||||
@@ -15,7 +15,7 @@ import {useCopilotsStore} from "stores/Copilots";
|
|||||||
import FlightFormNotes from "components/flights/form/FlightFormNotes.vue";
|
import FlightFormNotes from "components/flights/form/FlightFormNotes.vue";
|
||||||
import FlightFormPhotos from "components/flights/form/FlightFormPhotos.vue";
|
import FlightFormPhotos from "components/flights/form/FlightFormPhotos.vue";
|
||||||
import {usePhotosStore} from "stores/Photo";
|
import {usePhotosStore} from "stores/Photo";
|
||||||
import PhotosList from "components/photos/PhotosList.vue";
|
import PhotosList from "components/photos/PhotosEditorList.vue";
|
||||||
import {errorObject, successObject, warningObject} from "src/composables/dialog";
|
import {errorObject, successObject, warningObject} from "src/composables/dialog";
|
||||||
import PhotoFormDialog from "components/photos/PhotoFormDialog.vue";
|
import PhotoFormDialog from "components/photos/PhotoFormDialog.vue";
|
||||||
import FlightFormTrack from "components/flights/form/FlightFormTrack.vue";
|
import FlightFormTrack from "components/flights/form/FlightFormTrack.vue";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {useRoute, useRouter} from "vue-router";
|
import {useRoute, useRouter} from "vue-router";
|
||||||
import {onMounted, watch} from "vue";
|
import {computed, onMounted, ref, watch} from "vue";
|
||||||
import FlightDetailSkeleton from "components/flights/FlightDetailSkeleton.vue";
|
import FlightDetailSkeleton from "components/flights/FlightDetailSkeleton.vue";
|
||||||
import {fetchFlight, flight, flightName, handleDeleteFlight, loading} from "src/composables/objects/flight";
|
import {fetchFlight, flight, flightName, handleDeleteFlight, loading} from "src/composables/objects/flight";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
@@ -8,14 +8,11 @@ import FlightBasicInfo from "components/flights/FlightBasicInfo.vue";
|
|||||||
import {copyToClipboard, useQuasar} from "quasar";
|
import {copyToClipboard, useQuasar} from "quasar";
|
||||||
import {successObject} from "src/composables/dialog";
|
import {successObject} from "src/composables/dialog";
|
||||||
import {useFlightsStore} from "stores/Flights";
|
import {useFlightsStore} from "stores/Flights";
|
||||||
import PhotoCarousel from "components/photos/PhotoCarousel.vue";
|
|
||||||
import FlightTrackMap from "components/flights/FlightTrackMap.vue";
|
import FlightTrackMap from "components/flights/FlightTrackMap.vue";
|
||||||
import {useUserStore} from "stores/User";
|
import {useUserStore} from "stores/User";
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
import PhotosList from "components/photos/PhotosList.vue";
|
|
||||||
import {openDetail, openPhotoDetail, openPhotoFromList, photoData} from "src/composables/photos/photo";
|
|
||||||
import PhotoDetail from "components/photos/PhotoDetail.vue";
|
|
||||||
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
|
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
|
||||||
|
import PhotoGallery from "components/photos/PhotoGallery.vue";
|
||||||
|
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const $router = useRouter();
|
const $router = useRouter();
|
||||||
@@ -72,22 +69,26 @@ const copyLinkToClipboard = () => {
|
|||||||
<FlightDetailSkeleton v-if="loading || !flight"/>
|
<FlightDetailSkeleton v-if="loading || !flight"/>
|
||||||
|
|
||||||
<q-card class="flight-detail-card" v-else>
|
<q-card class="flight-detail-card" v-else>
|
||||||
<PhotoCarousel
|
<!-- <PhotoCarousel-->
|
||||||
:cover-photo-url="flight.coverPhoto?.url"
|
<!-- :cover-photo-url="flight.coverPhoto?.url"-->
|
||||||
:carousel-title="flightName(flight)"
|
<!-- :carousel-title="flightName(flight)"-->
|
||||||
:photos="flight.photos"
|
<!-- :photos="flight.photos"-->
|
||||||
@open-detail="openDetail"
|
<!-- />-->
|
||||||
/>
|
<q-img :src="flight.coverPhoto.url" v-if="flight.coverPhoto">
|
||||||
|
<div class="absolute-bottom custom-caption">
|
||||||
|
<div class="text-h5"> {{ flightName(flight) }} </div>
|
||||||
|
</div>
|
||||||
|
</q-img>
|
||||||
|
|
||||||
<q-card-actions class="q-my-md">
|
<q-card-actions class="q-my-md">
|
||||||
<div class="col-grow">
|
<div class="col-grow">
|
||||||
<q-btn
|
<!-- <q-btn-->
|
||||||
flat
|
<!-- flat-->
|
||||||
:to="{name: 'flightEdit', params:{id: flight.id}}"
|
<!-- :to="{name: 'flightEdit', params:{id: flight.id}}"-->
|
||||||
icon="edit"
|
<!-- icon="edit"-->
|
||||||
text-color="primary"
|
<!-- text-color="primary"-->
|
||||||
label="Upravit"
|
<!-- label="Upravit"-->
|
||||||
/>
|
<!-- />-->
|
||||||
|
|
||||||
<q-btn
|
<q-btn
|
||||||
@click="togglePublicVisibility"
|
@click="togglePublicVisibility"
|
||||||
@@ -110,19 +111,19 @@ const copyLinkToClipboard = () => {
|
|||||||
|
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<q-btn class="q-my-sm" :to="{name: 'flightEdit', params: {id: flightId, step: 'basic'}}" icon="edit" color="primary">Upravit informace</q-btn>
|
<q-btn flat class="q-my-sm" :to="{name: 'flightEdit', params: {id: flightId, step: 'basic'}}" icon="edit" color="primary">Upravit informace</q-btn>
|
||||||
</div>
|
</div>
|
||||||
<FlightBasicInfo :flight="flight" :show-copilots="true"/>
|
<FlightBasicInfo :flight="flight" :show-copilots="true"/>
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<q-btn class="q-my-sm" :to="{name: 'flightEdit', params: {id: flightId, step: 'notes'}}" icon="edit" color="primary">Upravit text</q-btn>
|
<q-btn flat class="q-my-sm" :to="{name: 'flightEdit', params: {id: flightId, step: 'notes'}}" icon="edit" color="primary">Upravit text</q-btn>
|
||||||
</div>
|
</div>
|
||||||
<article class="q-my-lg" v-html="flight.description"/>
|
<article class="q-my-lg" v-html="flight.description"/>
|
||||||
|
|
||||||
<q-separator/>
|
<q-separator/>
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<q-btn class="q-my-sm" :to="{name: 'flightEdit', params: {id: flightId, step: 'photos'}}" icon="edit" color="primary">Upravit fotky</q-btn>
|
<q-btn flat class="q-my-sm" :to="{name: 'flightEdit', params: {id: flightId, step: 'photos'}}" icon="edit" color="primary">Upravit fotky</q-btn>
|
||||||
</div>
|
</div>
|
||||||
<BasicInfoBanner
|
<BasicInfoBanner
|
||||||
v-if="flight.photos.length === 0"
|
v-if="flight.photos.length === 0"
|
||||||
@@ -130,11 +131,9 @@ const copyLinkToClipboard = () => {
|
|||||||
>
|
>
|
||||||
U tohoto letu nemáš nahrané žádné fotografie.
|
U tohoto letu nemáš nahrané žádné fotografie.
|
||||||
</BasicInfoBanner>
|
</BasicInfoBanner>
|
||||||
<PhotosList
|
<PhotoGallery
|
||||||
v-else
|
v-else
|
||||||
:photos="flight.photos"
|
:photos="flight.photos"
|
||||||
:show-actions="false"
|
|
||||||
@photo-click="openPhotoFromList"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-separator/>
|
<q-separator/>
|
||||||
@@ -154,13 +153,4 @@ const copyLinkToClipboard = () => {
|
|||||||
/>
|
/>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
<PhotoDetail
|
|
||||||
v-if="photoData"
|
|
||||||
v-model="openPhotoDetail"
|
|
||||||
:default-title="flightName(flight)"
|
|
||||||
:photo="photoData.photo"
|
|
||||||
:photos="photoData.allPhotos"
|
|
||||||
:opened-index="photoData.idx"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {useRoute} from "vue-router";
|
|||||||
import POIDetailSkeleton from "components/poi/POIDetailSkeleton.vue";
|
import POIDetailSkeleton from "components/poi/POIDetailSkeleton.vue";
|
||||||
import FAB from "components/FAB.vue";
|
import FAB from "components/FAB.vue";
|
||||||
import {fetchPoi, loading, poi} from "src/composables/objects/poi";
|
import {fetchPoi, loading, poi} from "src/composables/objects/poi";
|
||||||
import PhotosList from "components/photos/PhotosList.vue";
|
import PhotosList from "components/photos/PhotosEditorList.vue";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import EmbeddedMap from "components/map/EmbeddedMap.vue";
|
import EmbeddedMap from "components/map/EmbeddedMap.vue";
|
||||||
import {useUserStore} from "stores/User";
|
import {useUserStore} from "stores/User";
|
||||||
|
|||||||
@@ -2,17 +2,12 @@
|
|||||||
import {onMounted, watch} from "vue";
|
import {onMounted, watch} from "vue";
|
||||||
import {fetchFlight, flight, flightName, loading} from "src/composables/objects/flight";
|
import {fetchFlight, flight, flightName, loading} from "src/composables/objects/flight";
|
||||||
import {useRoute} from "vue-router";
|
import {useRoute} from "vue-router";
|
||||||
import PhotoCarousel from "components/photos/PhotoCarousel.vue";
|
|
||||||
import FlightTrackMap from "components/flights/FlightTrackMap.vue";
|
import FlightTrackMap from "components/flights/FlightTrackMap.vue";
|
||||||
import FlightBasicInfo from "components/flights/FlightBasicInfo.vue";
|
import FlightBasicInfo from "components/flights/FlightBasicInfo.vue";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import FlightDetailSkeleton from "components/flights/FlightDetailSkeleton.vue";
|
import FlightDetailSkeleton from "components/flights/FlightDetailSkeleton.vue";
|
||||||
import {fetchUser, loading as pilotLoading, user as pilot} from "src/composables/objects/user";
|
import {fetchUser, loading as pilotLoading, user as pilot} from "src/composables/objects/user";
|
||||||
import PublicProfileSkeleton from "components/profile/PublicProfileSkeleton.vue";
|
import PhotoGallery from "components/photos/PhotoGallery.vue";
|
||||||
import PilotProfileCard from "components/profile/PilotProfileCard.vue";
|
|
||||||
import PhotosList from "components/photos/PhotosList.vue";
|
|
||||||
import PhotoDetail from "components/photos/PhotoDetail.vue";
|
|
||||||
import {openDetail, openPhotoDetail, openPhotoFromList, photoData} from "src/composables/photos/photo";
|
|
||||||
|
|
||||||
const routeParams = useRoute().params;
|
const routeParams = useRoute().params;
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -41,31 +36,24 @@ watch(flight, (newVal) => {
|
|||||||
</q-banner>
|
</q-banner>
|
||||||
|
|
||||||
<q-card class="q-mx-md q-my-md flight-detail-card">
|
<q-card class="q-mx-md q-my-md flight-detail-card">
|
||||||
<PhotoCarousel
|
<q-img :src="flight.coverPhoto.url" v-if="flight.coverPhoto">
|
||||||
:default-title="flightName(flight)"
|
<div class="absolute-bottom custom-caption">
|
||||||
:cover-photo-url="flight.coverPhoto?.url"
|
<div class="text-h5"> {{ flightName(flight) }}</div>
|
||||||
:photos="flight.photos"
|
</div>
|
||||||
@open-detail="openDetail"
|
</q-img>
|
||||||
/>
|
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<FlightBasicInfo :flight="flight" :show-copilots="false"/>
|
<FlightBasicInfo :flight="flight" :show-copilots="false"/>
|
||||||
|
|
||||||
<article class="q-my-lg" v-html="flight.description"/>
|
<article class="q-my-lg" v-html="flight.description"/>
|
||||||
|
|
||||||
<PhotosList :photos="flight.photos" :show-actions="false" @photo-click="openPhotoFromList"/>
|
<PhotoGallery :photos="flight.photos"/>
|
||||||
|
|
||||||
<FlightTrackMap :flight="flight"/>
|
<FlightTrackMap :flight="flight"/>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
<PhotoDetail
|
|
||||||
v-if="photoData"
|
|
||||||
v-model="openPhotoDetail"
|
|
||||||
:default-title="flightName(flight)"
|
|
||||||
:photo="photoData.photo"
|
|
||||||
:photos="photoData.allPhotos"
|
|
||||||
:opened-index="photoData.idx"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2354,6 +2354,16 @@ path-to-regexp@0.1.7:
|
|||||||
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz"
|
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz"
|
||||||
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
|
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
|
||||||
|
|
||||||
|
photoswipe-dynamic-caption-plugin@^1.2.7:
|
||||||
|
version "1.2.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/photoswipe-dynamic-caption-plugin/-/photoswipe-dynamic-caption-plugin-1.2.7.tgz#53aa5059f1c4dccc8aa36196ff3e09baa5e537c2"
|
||||||
|
integrity sha512-5XXdXLf2381nwe7KqQvcyStiUBi9TitYXppUQTrzPwYAi4lZsmWNnNKMclM7I4QGlX6fXo42v3bgb6rlK9pY1Q==
|
||||||
|
|
||||||
|
photoswipe@^5.4.2:
|
||||||
|
version "5.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/photoswipe/-/photoswipe-5.4.2.tgz#bed976c27f876bd9c86085a022701a8cea484f7e"
|
||||||
|
integrity sha512-z5hr36nAIPOZbHJPbCJ/mQ3+ZlizttF9za5gKXKH/us1k4KNHaRbC63K1Px5sVVKUtGb/2+ixHpKqtwl0WAwvA==
|
||||||
|
|
||||||
picocolors@^1.0.0:
|
picocolors@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
|
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user