[backport cloud/1.42] fix: high-res image preview overflowing screen and hiding close button (#10129) (#10894)

Backport of #10129 to cloud/1.42. Clean cherry-pick.

Co-authored-by: Jin Yi <jin12cc@gmail.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Christian Byrne
2026-04-06 14:57:24 -07:00
committed by GitHub
parent 5f49e77b26
commit 0babdb4fe3
3 changed files with 21 additions and 75 deletions

View File

@@ -1,35 +1,40 @@
<!-- A image with placeholder fallback on error -->
<template>
<span
v-if="!imageBroken"
class="comfy-image-wrap"
:class="[{ contain: contain }]"
>
<span v-if="!error" :class="cn('contents', contain && 'relative')">
<img
v-if="contain"
:src="src"
:data-test="src"
class="comfy-image-blur"
class="absolute inset-0 object-cover"
:style="{ 'background-image': `url(${src})` }"
:alt="alt"
@error="handleImageError"
/>
<img
:src="src"
class="comfy-image-main"
:class="classProp"
:class="
cn(
'z-1 size-full object-cover object-center',
contain && 'absolute object-contain backdrop-blur-[10px]',
classProp
)
"
:alt="alt"
@error="handleImageError"
/>
</span>
<div v-if="imageBroken" class="broken-image-placeholder">
<i class="pi pi-image" />
<div
v-if="error"
class="m-8 flex size-full flex-col items-center justify-center"
>
<i class="pi pi-image mb-2 text-5xl" />
<span>{{ $t('g.imageFailedToLoad') }}</span>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useImage } from '@vueuse/core'
import { computed } from 'vue'
import { cn } from '@/utils/tailwindUtil'
const {
src,
@@ -46,58 +51,5 @@ const {
alt?: string
}>()
const imageBroken = ref(false)
const handleImageError = () => {
imageBroken.value = true
}
const { error } = useImage(computed(() => ({ src, alt })))
</script>
<style scoped>
.comfy-image-wrap {
display: contents;
}
.comfy-image-blur {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.comfy-image-main {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
z-index: 1;
}
.contain .comfy-image-wrap {
position: relative;
width: 100%;
height: 100%;
}
.contain .comfy-image-main {
object-fit: contain;
backdrop-filter: blur(10px);
position: absolute;
}
.broken-image-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
margin: 2rem;
}
.broken-image-placeholder i {
font-size: 3rem;
margin-bottom: 0.5rem;
}
</style>

View File

@@ -32,7 +32,7 @@
:src="item.url"
:contain="false"
:alt="item.filename"
class="galleria-image"
class="size-auto max-h-[90vh] max-w-[90vw] object-contain"
/>
<ResultVideo v-else-if="item.isVideo" :result="item" />
<ResultAudio v-else-if="item.isAudio" :result="item" />
@@ -136,12 +136,6 @@ onUnmounted(() => {
<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;

View File

@@ -1,5 +1,5 @@
<template>
<video controls width="100%" height="100%">
<video controls class="max-h-[90vh] max-w-[90vw]">
<source :src="url" :type="htmlVideoType" />
{{ $t('g.videoFailedToLoad') }}
</video>