Use local downloaded thumbnail if avaliable instead of referencing external one

This commit is contained in:
arabcoders 2025-09-16 17:45:23 +03:00
parent 27893bcbf9
commit ba2bfd6c9b
3 changed files with 43 additions and 14 deletions

View file

@ -117,10 +117,8 @@
{{ formatTime(item.extras.duration) }}
</span>
</div>
<div v-if="showThumbnails && item.extras.thumbnail">
<FloatingImage
:image="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
:title="`[${item.preset}] - ${item.title}`">
<div v-if="showThumbnails && getImage(item)">
<FloatingImage :image="getImage(item)" :title="`[${item.preset}] - ${item.title}`">
<div class="is-text-overflow">
<NuxtLink target="_blank" :href="item.url">{{ item.title }}</NuxtLink>
</div>
@ -272,22 +270,17 @@
<figure class="image is-3by1">
<span v-if="'finished' === item.status && item.filename" @click="playVideo(item)" class="play-overlay">
<div class="play-icon"></div>
<img @load="(e: Event) => pImg(e)"
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
v-if="item.extras?.thumbnail" />
<img @load="(e: Event) => pImg(e)" :src="getImage(item)" v-if="getImage(item)" />
<img v-else src="/images/placeholder.png" />
</span>
<span v-else-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
class="play-overlay">
<div class="play-icon embed-icon"></div>
<img @load="(e: Event) => pImg(e)"
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
v-if="item.extras?.thumbnail" />
<img @load="(e: Event) => pImg(e)" :src="getImage(item)" v-if="getImage(item)" />
<img v-else src="/images/placeholder.png" />
</span>
<template v-else>
<img @load="(e: Event) => pImg(e)" v-if="item.extras?.thumbnail"
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))" />
<img @load="(e: Event) => pImg(e)" v-if="getImage(item)" :src="getImage(item)" />
<img v-else src="/images/placeholder.png" />
</template>
</figure>
@ -912,6 +905,18 @@ const makePath = (item: StoreItem) => {
return ''
}
const real_path = eTrim(item.download_dir, '/') + '/' + sTrim(item.filename, '/')
return real_path.replace(config.app.download_path, '').replace(/^\//, '')
return stripPath(config.app.download_path, real_path)
}
const getImage = (item: StoreItem): string => {
if (item.sidecar?.image && item.sidecar.image.length > 0) {
return uri('/api/download/' + encodeURIComponent(stripPath(config.app.download_path, item.sidecar.image[0]?.file || '')))
}
if (!item?.extras?.thumbnail) {
return '/images/placeholder.png'
}
return uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))
}
</script>

View file

@ -1,4 +1,14 @@
type ItemStatus = 'finished' | 'preparing' | 'error' | 'cancelled' | 'downloading' | 'postprocessing' | 'not_live' | 'skip' | null;
type SideCar = {
file: string
}
type sideCarSubtitle = SideCar & {
lang: string
name: string
}
type StoreItem = {
/** Unique identifier for the item */
_id: string
@ -42,6 +52,12 @@ type StoreItem = {
auto_start: boolean
/** Options for the item */
options: Record<string, unknown>
/** Sidecar associated with the item. */
sidecar: {
Unknown?: Array<SideCar>
subtitle?: Array<sideCarSubtitle>
image?: Array<SideCar>
},
/** Extras for the item */
extras: {
/** Which channel the item belongs to */

View file

@ -677,10 +677,18 @@ const enableOpacity = (): boolean => {
return true
}
const stripPath = (base_path: string, real_path: string): string => {
if (!base_path) {
return real_path
}
return real_path.replace(base_path, '').replace(/^\//, '')
}
export {
separators, convertCliOptions, getSeparatorsName, iTrim, eTrim, sTrim, ucFirst,
getValue, ag, ag_set, awaitElement, r, copyText, dEvent, makePagination, encodePath,
request, removeANSIColors, dec2hex, makeId, basename, dirname, getQueryParams,
makeDownload, formatBytes, has_data, toggleClass, cleanObject, uri, formatTime,
sleep, awaiter, encode, decode, disableOpacity, enableOpacity
sleep, awaiter, encode, decode, disableOpacity, enableOpacity, stripPath
}