Nahledy v detailu fotky
This commit is contained in:
@@ -10,6 +10,10 @@ const props = defineProps({
|
|||||||
coverPhotoUrl: {
|
coverPhotoUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false
|
||||||
|
},
|
||||||
|
defaultTitle: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -36,6 +40,7 @@ watch(() => props.photos, (newVal) => {
|
|||||||
swipeable
|
swipeable
|
||||||
height="auto"
|
height="auto"
|
||||||
infinite
|
infinite
|
||||||
|
v-bind="$attrs"
|
||||||
>
|
>
|
||||||
<q-carousel-slide style="padding: 0" v-for="(photo, idx) in photos" :key="photo.url" :name="photo.url">
|
<q-carousel-slide style="padding: 0" v-for="(photo, idx) in photos" :key="photo.url" :name="photo.url">
|
||||||
<q-img :src="photo.url" @click="openDetail({photo, idx, allPhotos: photos})"/>
|
<q-img :src="photo.url" @click="openDetail({photo, idx, allPhotos: photos})"/>
|
||||||
@@ -45,6 +50,7 @@ watch(() => props.photos, (newVal) => {
|
|||||||
<PhotoDetail
|
<PhotoDetail
|
||||||
v-if="photoData"
|
v-if="photoData"
|
||||||
v-model="openPhotoDetail"
|
v-model="openPhotoDetail"
|
||||||
|
:default-title="defaultTitle"
|
||||||
:photo="photoData.photo"
|
:photo="photoData.photo"
|
||||||
:photos="photoData.allPhotos"
|
:photos="photoData.allPhotos"
|
||||||
:opened-index="photoData.idx"
|
:opened-index="photoData.idx"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import EmbeddedMap from "components/map/EmbeddedMap.vue";
|
import EmbeddedMap from "components/map/EmbeddedMap.vue";
|
||||||
import {computed, onMounted, ref} from "vue";
|
import {computed, onMounted, ref, watch} from "vue";
|
||||||
import {formatDatetime} from "src/composables/datetimeUtils";
|
import {formatDatetime} from "src/composables/datetimeUtils";
|
||||||
import 'vue-inner-image-zoom/lib/vue-inner-image-zoom.css'
|
import 'vue-inner-image-zoom/lib/vue-inner-image-zoom.css'
|
||||||
import {useQuasar} from "quasar";
|
import {useQuasar} from "quasar";
|
||||||
@@ -19,6 +19,10 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
defaultTitle: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -53,10 +57,24 @@ const prevPhoto = () => {
|
|||||||
if (photoIndex.value > 0) photoIndex.value--;
|
if (photoIndex.value > 0) photoIndex.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const showDetail = (idx) => {
|
||||||
|
photoIndex.value = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
const thumbnailsRef = ref(null);
|
||||||
|
watch(photoIndex, (newVal) => {
|
||||||
|
if (!thumbnailsRef.value) return;
|
||||||
|
const thumbnailWidth = 200;
|
||||||
|
const thumbnailBarWidth = thumbnailsRef.value.$el.clientWidth;
|
||||||
|
const thumbnailPosition = newVal * thumbnailWidth;
|
||||||
|
const scrollTo = Math.max(0, thumbnailPosition - thumbnailBarWidth/2);
|
||||||
|
thumbnailsRef.value.setScrollPosition("horizontal", scrollTo, 500)
|
||||||
|
});
|
||||||
|
|
||||||
const showExtra = ref(false);
|
const showExtra = ref(false);
|
||||||
|
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const isMaximized = computed(() => $q.screen.width <= $q.screen.sizes.md);
|
const isMaximized = computed(() => $q.screen.width <= $q.screen.sizes.sm);
|
||||||
const imageFullscreen = ref(false);
|
const imageFullscreen = ref(false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -75,7 +93,7 @@ const imageFullscreen = ref(false);
|
|||||||
<q-card-section class="bg-black text-white" v-if="isMaximized">
|
<q-card-section class="bg-black text-white" v-if="isMaximized">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<strong v-if="photo.name !== ''">{{ photo.name }}</strong>
|
<strong>{{ photo.name || defaultTitle }}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-right">
|
<div class="col text-right">
|
||||||
<q-btn round text-color="white" size="sm" icon="close" @click="open = false"/>
|
<q-btn round text-color="white" size="sm" icon="close" @click="open = false"/>
|
||||||
@@ -88,8 +106,8 @@ const imageFullscreen = ref(false);
|
|||||||
<div :class="{'relative-position': true, 'image-full-height': imageFullscreen}">
|
<div :class="{'relative-position': true, 'image-full-height': imageFullscreen}">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<inner-image-zoom
|
<inner-image-zoom
|
||||||
move-type="drag"
|
:move-type="isMaximized ? 'drag' : 'pan'"
|
||||||
:zoomScale="0.5"
|
:zoomScale="0.75"
|
||||||
:hide-hint="true"
|
:hide-hint="true"
|
||||||
:after-zoom-in="() => imageFullscreen = true"
|
:after-zoom-in="() => imageFullscreen = true"
|
||||||
:after-zoom-out="() => imageFullscreen = false"
|
:after-zoom-out="() => imageFullscreen = false"
|
||||||
@@ -97,41 +115,52 @@ const imageFullscreen = ref(false);
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-btn
|
<template v-if="!imageFullscreen">
|
||||||
class="absolute all-pointer-events"
|
<q-btn
|
||||||
round
|
class="absolute all-pointer-events"
|
||||||
flat
|
round
|
||||||
icon="info"
|
flat
|
||||||
:text-color="showExtra ? 'primary' : 'white'"
|
icon="info"
|
||||||
style="background: rgba(0, 0, 0, 0.25); bottom: 16px; left: 8px"
|
:text-color="showExtra ? 'primary' : 'white'"
|
||||||
@click="showExtra = !showExtra"
|
style="background: rgba(0, 0, 0, 0.25); bottom: 16px; left: 8px"
|
||||||
/>
|
@click="showExtra = !showExtra"
|
||||||
<q-btn
|
/>
|
||||||
class="absolute all-pointer-events"
|
<q-btn
|
||||||
style="background: rgba(0, 0, 0, 0.25); top: 50%; left: 8px;"
|
class="absolute all-pointer-events"
|
||||||
@click="prevPhoto"
|
style="background: rgba(0, 0, 0, 0.25); top: 50%; left: 8px;"
|
||||||
v-if="photoIndex > 0 && !isMaximized"
|
@click="prevPhoto"
|
||||||
icon="chevron_left"
|
v-if="photoIndex > 0 && !isMaximized"
|
||||||
text-color="white"
|
icon="chevron_left"
|
||||||
flat
|
text-color="white"
|
||||||
rounded
|
flat
|
||||||
>
|
rounded
|
||||||
</q-btn>
|
/>
|
||||||
<q-btn
|
<q-btn
|
||||||
class="absolute all-pointer-events"
|
class="absolute all-pointer-events"
|
||||||
style="background: rgba(0, 0, 0, 0.25); top: 50%; right: 8px;"
|
style="background: rgba(0, 0, 0, 0.25); top: 50%; right: 8px;"
|
||||||
@click="nextPhoto"
|
@click="nextPhoto"
|
||||||
v-if="photoIndex < photos.length - 1 && !isMaximized"
|
v-if="photoIndex < photos.length - 1 && !isMaximized"
|
||||||
icon-right="chevron_right"
|
icon-right="chevron_right"
|
||||||
text-color="white"
|
text-color="white"
|
||||||
flat
|
flat
|
||||||
rounded
|
rounded
|
||||||
>
|
/>
|
||||||
</q-btn>
|
</template>
|
||||||
<strong v-if="photo.name !== '' && !isMaximized">{{ photo.name }}</strong>
|
|
||||||
<p v-if="photo.description !== ''">{{ photo.description }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<q-scroll-area ref="thumbnailsRef" style="height: 170px; width: 100%;" v-show="!imageFullscreen">
|
||||||
|
<div class="row no-wrap flex-center">
|
||||||
|
<q-img
|
||||||
|
v-for="(thumb, idx) in photos"
|
||||||
|
:key="thumb.thumbnailUrl"
|
||||||
|
:src="thumb.thumbnailUrl"
|
||||||
|
@click="showDetail(idx)"
|
||||||
|
:style="`width: 150px; ${idx === photoIndex ? 'outline: solid 2px' : ''}`"
|
||||||
|
class="q-ma-sm shadow-5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</q-scroll-area>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 q-my-md" v-if="showExtra">
|
<div class="col-12 q-my-md" v-if="showExtra">
|
||||||
<EmbeddedMap
|
<EmbeddedMap
|
||||||
@@ -141,6 +170,9 @@ const imageFullscreen = ref(false);
|
|||||||
:gps-longitude="photo.gpsLongitude"
|
:gps-longitude="photo.gpsLongitude"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<strong v-if="photo.name !== '' && !isMaximized">{{ photo.name }}</strong>
|
||||||
|
<p v-if="photo.description !== ''">{{ photo.description }}</p>
|
||||||
|
|
||||||
<q-list dense>
|
<q-list dense>
|
||||||
<q-item v-if="photo.pointOfInterest">
|
<q-item v-if="photo.pointOfInterest">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ useMeta(() => ({
|
|||||||
title: pageTitle.value !== '' ? `${pageTitle.value} - Polétání.cz` : 'Polétání.cz'
|
title: pageTitle.value !== '' ? `${pageTitle.value} - Polétání.cz` : 'Polétání.cz'
|
||||||
}));
|
}));
|
||||||
|
|
||||||
onMounted(() => {
|
// onMounted(() => {
|
||||||
if (loggedUser || useUserStore().hasAccessToken()) {
|
// if (loggedUser || useUserStore().hasAccessToken()) {
|
||||||
// poll once per 5 minutes to keep access token active
|
// // poll once per 5 minutes to keep access token active
|
||||||
setInterval(useUserStore().fetchLoggedUserDetail, 5*60*1000);
|
// setInterval(useUserStore().fetchLoggedUserDetail, 5*60*1000);
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ watch(flight, (newVal) => {
|
|||||||
|
|
||||||
<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
|
<PhotoCarousel
|
||||||
|
:default-title="flightName(flight)"
|
||||||
:cover-photo-url="flight.coverPhoto?.url"
|
:cover-photo-url="flight.coverPhoto?.url"
|
||||||
:photos="flight.photos"
|
:photos="flight.photos"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user