Files
app/src/components/photos/PhotoGallery.vue
T

151 lines
3.8 KiB
Vue

<script setup>
import {computed, onMounted, onUnmounted, ref, watch} from "vue";
import 'photoswipe/style.css';
import "photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css";
import PhotoSwipeDynamicCaption from "../../../node_modules/photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.esm";
import PhotoCaption from "components/photos/PhotoCaption.vue";
import PhotoSwipeLightbox from "../../../node_modules/photoswipe/dist/photoswipe-lightbox.esm"
import PhotoSwipe from "../../../node_modules/photoswipe/dist/photoswipe.esm"
import {useRouter} from "vue-router";
import {usePhotosStore} from "stores/Photos";
import {useQuasar} from "quasar";
const props = defineProps({
galleryId: {
type: String,
required: false,
default: () => "photogallery"
},
photos: {
type: Array,
required: true
}
})
const $router = useRouter();
const $q = useQuasar();
let $lightbox = ref(null);
const initLightbox = () => {
if ($lightbox.value && $lightbox.value.pswp) {
// lightbox already initialized
return
}
$lightbox.value = new PhotoSwipeLightbox({
gallery: '#' + props.galleryId,
children: 'a',
pswpModule: () => PhotoSwipe,
});
let captionPlugin = new PhotoSwipeDynamicCaption($lightbox.value, {
type: 'auto',
});
$lightbox.value.init();
}
const isCollapsed = ref(true);
const photosCollapseLimit = computed(() => {
if ($q.screen.width <= $q.screen.sizes.sm) return 2;
else if ($q.screen.width <= $q.screen.sizes.md) return 3;
else return 4;
});
onMounted(() => {
isCollapsed.value = props.photos.length >= photosCollapseLimit.value;
});
onUnmounted(() => {
if ($lightbox.value) {
$lightbox.value.destroy();
$lightbox.value = null;
}
});
const openedPhoto = computed(() => usePhotosStore().openedPhoto);
watch(() => [openedPhoto.value, $lightbox.value], () => {
if (!openedPhoto.value) return;
if (!$lightbox.value) {
initLightbox();
}
const idx = props.photos.findIndex(p => p.id === openedPhoto.value.id);
if (idx >= 0) {
$lightbox.value.loadAndOpen(idx);
usePhotosStore().setOpenedPhoto(null);
}
}, {immediate: true});
</script>
<template>
<div :class="{'photogallery--wrapper': true, collapsed: isCollapsed}" :id="`${galleryId}-wrapper`">
<div :id="galleryId" class="row photogallery--content">
<div
v-for="photo in photos" :key="photo.id"
style="min-height: 100px"
class="col-6 col-sm-4 col-md-4 col-lg-3 q-pa-sm"
>
<a
:data-pswp-src="photo.url"
:data-pswp-width="photo.width"
:data-pswp-height="photo.height"
target="_blank"
@click="initLightbox"
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>
<a class="photogallery--collapse" v-if="isCollapsed" @click="isCollapsed = false">
<q-btn class="q-mt-lg q-mb-md" color="secondary">Rozbalit</q-btn>
</a>
</div>
</template>
<style lang="scss">
.photogallery--wrapper {
margin: 50px 0;
a:hover {
cursor: pointer
}
&.collapsed {
position: relative;
.photogallery--content {
max-height: 250px;
overflow: hidden
}
.photogallery--collapse {
display: block;
position: absolute;
width: 100%;
bottom: 0;
left: 0;
right: 0;
text-align: center;
background: rgb(255, 255, 255);
background: linear-gradient(0deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 35%, rgba(255, 255, 255, 0) 100%);
}
}
}
</style>