Files
interview-demo-code/frontend/spa/src/components/FullScreenImageViewer.vue
Nikita Kiselev 3cc82e45f0
Some checks are pending
Telegram Mini App Shop Builder / Compute version metadata (push) Waiting to run
Telegram Mini App Shop Builder / Run Frontend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run Backend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Waiting to run
Telegram Mini App Shop Builder / Build module. (push) Blocked by required conditions
Telegram Mini App Shop Builder / release (push) Blocked by required conditions
Squashed commit message
2026-03-11 23:02:54 +03:00

82 lines
2.1 KiB
Vue

<template>
<div class="fullscreen-image-viewer fixed z-200 top-0 inset-0 flex justify-center align-center flex-col h-full bg-black">
<Swiper
:zoom="true"
:navigation="true"
:pagination="{
type: 'fraction',
}"
:initialSlide="activeIndex"
:modules="[Zoom, Navigation, Pagination]"
class="mySwiper w-full h-full"
@slider-move="vibrate"
>
<SwiperSlide v-for="image in images">
<div class="swiper-zoom-container">
<img :src="image.largeURL" :alt="image.alt" class="w-full h-full"/>
</div>
</SwiperSlide>
</Swiper>
<button
class="absolute z-50 text-white text-xl right-5 cursor-pointer"
style="top: calc(var(--tg-safe-area-inset-top, 5px) + var(--tg-content-safe-area-inset-top, 5px))"
@click="onClose"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
class="size-10">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/>
</svg>
</button>
</div>
</template>
<script setup>
import {Navigation, Pagination, Zoom} from "swiper/modules";
import {Swiper, SwiperSlide} from "swiper/vue";
import {onMounted} from "vue";
import {useHapticFeedback} from "@/composables/useHapticFeedback.js";
const props = defineProps({
images: {
type: Array,
default: () => [],
},
activeIndex: {
type: Number,
default: 0,
},
});
const emits = defineEmits(['close']);
const haptic = useHapticFeedback();
let canVibrate = true;
function vibrate() {
if (!canVibrate) return;
haptic.impactOccurred('soft');
canVibrate = false;
setTimeout(() => {
canVibrate = true;
}, 50);
}
function onClose() {
haptic.impactOccurred('medium');
emits('close');
}
</script>
<style>
.fullscreen-image-viewer .swiper-button-next,
.fullscreen-image-viewer .swiper-button-prev {
color: white;
mix-blend-mode: difference;
}
.fullscreen-image-viewer .swiper-pagination-fraction {
bottom: calc(var(--tg-safe-area-inset-bottom, 0px) + var(--tg-content-safe-area-inset-bottom, px));
}
</style>