Fix: add fallback to placeholder if loading thumbnail fails
This commit is contained in:
parent
b36d9fd641
commit
d5727ca387
3 changed files with 35 additions and 17 deletions
|
|
@ -271,17 +271,17 @@
|
||||||
<figure :class="['image', thumbnail_ratio]">
|
<figure :class="['image', thumbnail_ratio]">
|
||||||
<span v-if="'finished' === item.status && item.filename" @click="playVideo(item)" class="play-overlay">
|
<span v-if="'finished' === item.status && item.filename" @click="playVideo(item)" class="play-overlay">
|
||||||
<div class="play-icon"></div>
|
<div class="play-icon"></div>
|
||||||
<img @load="(e: Event) => pImg(e)" :src="getImage(item)" v-if="getImage(item)" />
|
<img @load="pImg" @error="onImgError" :src="getImage(item)" v-if="getImage(item)" />
|
||||||
<img v-else src="/images/placeholder.png" />
|
<img v-else src="/images/placeholder.png" />
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
|
<span v-else-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
|
||||||
class="play-overlay">
|
class="play-overlay">
|
||||||
<div class="play-icon embed-icon"></div>
|
<div class="play-icon embed-icon"></div>
|
||||||
<img @load="(e: Event) => pImg(e)" :src="getImage(item)" v-if="getImage(item)" />
|
<img @load="pImg" @error="onImgError" :src="getImage(item)" v-if="getImage(item)" />
|
||||||
<img v-else src="/images/placeholder.png" />
|
<img v-else src="/images/placeholder.png" />
|
||||||
</span>
|
</span>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<img @load="(e: Event) => pImg(e)" v-if="getImage(item)" :src="getImage(item)" />
|
<img @load="pImg" @error="onImgError" v-if="getImage(item)" :src="getImage(item)" />
|
||||||
<img v-else src="/images/placeholder.png" />
|
<img v-else src="/images/placeholder.png" />
|
||||||
</template>
|
</template>
|
||||||
</figure>
|
</figure>
|
||||||
|
|
@ -847,6 +847,14 @@ const pImg = (e: Event) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onImgError = (e: Event) => {
|
||||||
|
const target = e.target as HTMLImageElement
|
||||||
|
if (target.src.endsWith('/images/placeholder.png')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
target.src = '/images/placeholder.png'
|
||||||
|
}
|
||||||
|
|
||||||
watch(video_item, (v) => {
|
watch(video_item, (v) => {
|
||||||
if (!bg_enable.value) {
|
if (!bg_enable.value) {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -193,13 +193,13 @@
|
||||||
<span v-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
|
<span v-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
|
||||||
class="play-overlay">
|
class="play-overlay">
|
||||||
<div class="play-icon embed-icon"></div>
|
<div class="play-icon embed-icon"></div>
|
||||||
<img @load="(e: Event) => pImg(e)"
|
<img @load="pImg" @error="onImgError"
|
||||||
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
|
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
|
||||||
v-if="item.extras?.thumbnail" />
|
v-if="item.extras?.thumbnail" />
|
||||||
<img v-else src="/images/placeholder.png" />
|
<img v-else src="/images/placeholder.png" />
|
||||||
</span>
|
</span>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<img @load="(e: Event) => pImg(e)" v-if="item.extras?.thumbnail"
|
<img @load="pImg" @error="onImgError" v-if="item.extras?.thumbnail"
|
||||||
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))" />
|
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))" />
|
||||||
<img v-else src="/images/placeholder.png" />
|
<img v-else src="/images/placeholder.png" />
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -579,6 +579,14 @@ const pImg = (e: Event) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onImgError = (e: Event) => {
|
||||||
|
const target = e.target as HTMLImageElement
|
||||||
|
if (target.src.endsWith('/images/placeholder.png')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
target.src = '/images/placeholder.png'
|
||||||
|
}
|
||||||
|
|
||||||
watch(embed_url, v => {
|
watch(embed_url, v => {
|
||||||
if (!bg_enable.value) {
|
if (!bg_enable.value) {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,8 @@
|
||||||
<figure class="media-left">
|
<figure class="media-left">
|
||||||
<figure class="image is-16by9 queue-thumb" :class="{ 'is-clickable': isEmbedable(entry.item.url) }"
|
<figure class="image is-16by9 queue-thumb" :class="{ 'is-clickable': isEmbedable(entry.item.url) }"
|
||||||
role="presentation" @click="openPlayer(entry.item)">
|
role="presentation" @click="openPlayer(entry.item)">
|
||||||
<img :src="resolveThumbnail(entry)" :alt="entry.item.title || 'Video thumbnail'" loading="lazy">
|
<img :src="resolveThumbnail(entry)" :alt="entry.item.title || 'Video thumbnail'" loading="lazy"
|
||||||
|
@error="onImgError">
|
||||||
<span v-if="getDurationLabel(entry.item)" class="queue-thumb__badge">
|
<span v-if="getDurationLabel(entry.item)" class="queue-thumb__badge">
|
||||||
{{ getDurationLabel(entry.item) }}
|
{{ getDurationLabel(entry.item) }}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -688,18 +689,19 @@ const loadMoreHistory = async (): Promise<void> => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup intersection observer for infinite scroll
|
const onImgError = (e: Event) => {
|
||||||
useIntersectionObserver(
|
const target = e.target as HTMLImageElement
|
||||||
loadMoreTrigger,
|
if (target.src.endsWith('/images/placeholder.png')) {
|
||||||
([entry]) => {
|
return
|
||||||
if (entry?.isIntersecting && !paginationInfo.value.isLoading && paginationInfo.value.page < paginationInfo.value.total_pages) {
|
|
||||||
loadMoreHistory()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
threshold: 0.5,
|
|
||||||
}
|
}
|
||||||
)
|
target.src = '/images/placeholder.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
useIntersectionObserver(loadMoreTrigger, ([entry]) => {
|
||||||
|
if (entry?.isIntersecting && !paginationInfo.value.isLoading && paginationInfo.value.page < paginationInfo.value.total_pages) {
|
||||||
|
loadMoreHistory()
|
||||||
|
}
|
||||||
|
}, { threshold: 0.5 })
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue