Fix skeleton loaders for Image/Video Previews (#7094)

This pull request refines the loading and error handling logic for both
the `VideoPreview.vue` and `ImagePreview.vue` components. The main
improvements include making the loading skeleton more accurate and
visually consistent, updating how loading and error states are managed
when URLs change, and ensuring that the main media elements are hidden
while loading. These changes enhance the user experience by providing
clearer feedback during media load operations.

**Loading and error state improvements:**

* The loading skeleton in both `VideoPreview.vue` and `ImagePreview.vue`
now only appears when loading and no error is present, with updated
styling and fixed dimensions for better consistency. (`VideoPreview.vue`
[[1]](diffhunk://#diff-17b5c19b4628f22e45570b66a85ed1fc16e931dd368fe420584d487e522ab8aaL29-R41)
`ImagePreview.vue`
[[2]](diffhunk://#diff-0c0b17c5c68464e0284398ad42b823509d414c9cf297f3bc2aa2b00e0f9c2015L29-R48)
* The main video and image elements are now hidden (using the
`invisible` class) while loading, preventing display glitches before the
media is ready. (`VideoPreview.vue`
[[1]](diffhunk://#diff-17b5c19b4628f22e45570b66a85ed1fc16e931dd368fe420584d487e522ab8aaL29-R41)
`ImagePreview.vue`
[[2]](diffhunk://#diff-0c0b17c5c68464e0284398ad42b823509d414c9cf297f3bc2aa2b00e0f9c2015L29-R48)
* The loading state (`isLoading`) is now set to `true` whenever new URLs
are provided, and reset appropriately when navigating between media
items, ensuring accurate feedback to the user. (`VideoPreview.vue`
[[1]](diffhunk://#diff-17b5c19b4628f22e45570b66a85ed1fc16e931dd368fe420584d487e522ab8aaL145-R152)
`ImagePreview.vue`
[[2]](diffhunk://#diff-0c0b17c5c68464e0284398ad42b823509d414c9cf297f3bc2aa2b00e0f9c2015L164-R176)
[[3]](diffhunk://#diff-0c0b17c5c68464e0284398ad42b823509d414c9cf297f3bc2aa2b00e0f9c2015L224-R236)

**Code consistency and maintainability:**

* Both components now import and use the shared `cn` utility for
conditional class names, improving code consistency and maintainability.
(`VideoPreview.vue`
[[1]](diffhunk://#diff-17b5c19b4628f22e45570b66a85ed1fc16e931dd368fe420584d487e522ab8aaR115)
`ImagePreview.vue`
[[2]](diffhunk://#diff-0c0b17c5c68464e0284398ad42b823509d414c9cf297f3bc2aa2b00e0f9c2015R132)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7094-Fix-skeleton-loaders-for-Image-Video-Previews-2bd6d73d3650817989e1f4d597094016)
by [Unito](https://www.unito.io)
This commit is contained in:
Johnpaul Chiwetelu
2025-12-03 03:39:33 +01:00
committed by GitHub
parent 9c5f8a619c
commit d50a2fabc0
2 changed files with 28 additions and 9 deletions

View File

@@ -26,13 +26,19 @@
</div>
<!-- Loading State -->
<Skeleton v-else-if="isLoading" class="size-full" border-radius="5px" />
<Skeleton
v-if="isLoading && !videoError"
class="absolute inset-0 size-full"
border-radius="5px"
width="16rem"
height="16rem"
/>
<!-- Main Video -->
<video
v-else
v-if="!videoError"
:src="currentVideoUrl"
class="block size-full object-contain"
:class="cn('block size-full object-contain', isLoading && 'invisible')"
controls
loop
playsinline
@@ -106,6 +112,7 @@ import { useI18n } from 'vue-i18n'
import { downloadFile } from '@/base/common/downloadUtil'
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
import { cn } from '@/utils/tailwindUtil'
interface VideoPreviewProps {
/** Array of video URLs to display */
@@ -142,7 +149,7 @@ watch(
// Reset loading and error states when URLs change
actualDimensions.value = null
videoError.value = false
isLoading.value = false
isLoading.value = newUrls.length > 0
},
{ deep: true }
)

View File

@@ -26,15 +26,26 @@
</div>
<!-- Loading State -->
<Skeleton v-else-if="isLoading" class="size-full" border-radius="5px" />
<Skeleton
v-if="isLoading && !imageError"
class="absolute inset-0 size-full"
border-radius="5px"
width="16rem"
height="16rem"
/>
<!-- Main Image -->
<img
v-else
v-if="!imageError"
ref="currentImageEl"
:src="currentImageUrl"
:alt="imageAltText"
class="block size-full object-contain pointer-events-none"
:class="
cn(
'block size-full object-contain pointer-events-none',
isLoading && 'invisible'
)
"
@load="handleImageLoad"
@error="handleImageError"
/>
@@ -118,6 +129,7 @@ import { downloadFile } from '@/base/common/downloadUtil'
import { app } from '@/scripts/app'
import { useCommandStore } from '@/stores/commandStore'
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
import { cn } from '@/utils/tailwindUtil'
interface ImagePreviewProps {
/** Array of image URLs to display */
@@ -161,7 +173,7 @@ watch(
// Reset loading and error states when URLs change
actualDimensions.value = null
imageError.value = false
isLoading.value = false
isLoading.value = newUrls.length > 0
},
{ deep: true }
)
@@ -221,7 +233,7 @@ const setCurrentIndex = (index: number) => {
if (index >= 0 && index < props.imageUrls.length) {
currentIndex.value = index
actualDimensions.value = null
isLoading.value = false
isLoading.value = true
imageError.value = false
}
}