mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-04 07:00:23 +00:00
* Map VHS video type * Advance preview format * nit * View VHS advanced preview * Disable result gallery vitest * Proper disable
137 lines
3.0 KiB
Vue
137 lines
3.0 KiB
Vue
<template>
|
|
<Galleria
|
|
v-model:visible="galleryVisible"
|
|
@update:visible="handleVisibilityChange"
|
|
:activeIndex="activeIndex"
|
|
@update:activeIndex="handleActiveIndexChange"
|
|
:value="allGalleryItems"
|
|
:showIndicators="false"
|
|
changeItemOnIndicatorHover
|
|
showItemNavigators
|
|
fullScreen
|
|
circular
|
|
:showThumbnails="false"
|
|
:pt="{
|
|
mask: {
|
|
onMousedown: onMaskMouseDown,
|
|
onMouseup: onMaskMouseUp,
|
|
'data-mask': true
|
|
}
|
|
}"
|
|
>
|
|
<template #item="{ item }">
|
|
<ComfyImage
|
|
:key="item.url"
|
|
:src="item.url"
|
|
:contain="false"
|
|
class="galleria-image"
|
|
v-if="item.isImage"
|
|
/>
|
|
<ResultVideo v-else-if="item.isVideo" :result="item" />
|
|
</template>
|
|
</Galleria>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, watch, onMounted, onUnmounted } from 'vue'
|
|
import Galleria from 'primevue/galleria'
|
|
import { ResultItemImpl } from '@/stores/queueStore'
|
|
import ComfyImage from '@/components/common/ComfyImage.vue'
|
|
import ResultVideo from './ResultVideo.vue'
|
|
|
|
const galleryVisible = ref(false)
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:activeIndex', value: number): void
|
|
}>()
|
|
|
|
const props = defineProps<{
|
|
allGalleryItems: ResultItemImpl[]
|
|
activeIndex: number
|
|
}>()
|
|
|
|
let maskMouseDownTarget: EventTarget | null = null
|
|
|
|
const onMaskMouseDown = (event: MouseEvent) => {
|
|
maskMouseDownTarget = event.target
|
|
}
|
|
|
|
const onMaskMouseUp = (event: MouseEvent) => {
|
|
const maskEl = document.querySelector('[data-mask]')
|
|
if (
|
|
galleryVisible.value &&
|
|
maskMouseDownTarget === event.target &&
|
|
maskMouseDownTarget === maskEl
|
|
) {
|
|
galleryVisible.value = false
|
|
handleVisibilityChange(false)
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => props.activeIndex,
|
|
(index) => {
|
|
if (index !== -1) {
|
|
galleryVisible.value = true
|
|
}
|
|
}
|
|
)
|
|
|
|
const handleVisibilityChange = (visible: boolean) => {
|
|
if (!visible) {
|
|
emit('update:activeIndex', -1)
|
|
}
|
|
}
|
|
|
|
const handleActiveIndexChange = (index: number) => {
|
|
emit('update:activeIndex', index)
|
|
}
|
|
|
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
if (!galleryVisible.value) return
|
|
|
|
switch (event.key) {
|
|
case 'ArrowLeft':
|
|
navigateImage(-1)
|
|
break
|
|
case 'ArrowRight':
|
|
navigateImage(1)
|
|
break
|
|
case 'Escape':
|
|
galleryVisible.value = false
|
|
handleVisibilityChange(false)
|
|
break
|
|
}
|
|
}
|
|
|
|
const navigateImage = (direction: number) => {
|
|
const newIndex =
|
|
(props.activeIndex + direction + props.allGalleryItems.length) %
|
|
props.allGalleryItems.length
|
|
emit('update:activeIndex', newIndex)
|
|
}
|
|
|
|
onMounted(() => {
|
|
window.addEventListener('keydown', handleKeyDown)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener('keydown', handleKeyDown)
|
|
})
|
|
</script>
|
|
|
|
<style>
|
|
/* PrimeVue's galleria teleports the fullscreen gallery out of subtree so we
|
|
cannot use scoped style here. */
|
|
img.galleria-image {
|
|
max-width: 100vw;
|
|
max-height: 100vh;
|
|
object-fit: contain;
|
|
}
|
|
|
|
.p-galleria-close-button {
|
|
/* Set z-index so the close button doesn't get hidden behind the image when image is large */
|
|
z-index: 1;
|
|
}
|
|
</style>
|