diff --git a/src/renderer/components/ft-list-video/ft-list-video.js b/src/renderer/components/ft-list-video/ft-list-video.js index fd58c6f67..b1fbb5592 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.js +++ b/src/renderer/components/ft-list-video/ft-list-video.js @@ -8,9 +8,11 @@ import { openExternalLink, showToast, toLocalePublicationString, - toDistractionFreeTitle + toDistractionFreeTitle, + deepCopy } from '../../helpers/utils' -import { deArrowData } from '../../helpers/sponsorblock' +import { deArrowData, deArrowThumbnail } from '../../helpers/sponsorblock' +import debounce from 'lodash.debounce' export default defineComponent({ name: 'FtListVideo', @@ -99,6 +101,7 @@ export default defineComponent({ isPremium: false, hideViews: false, addToPlaylistPromptCloseCallback: null, + debounceGetDeArrowThumbnail: null, } }, computed: { @@ -303,6 +306,14 @@ export default defineComponent({ }, thumbnail: function () { + if (this.thumbnailPreference === 'hidden') { + return require('../../assets/img/thumbnail_placeholder.svg') + } + + if (this.useDeArrowThumbnails && this.deArrowCache?.thumbnail != null) { + return this.deArrowCache.thumbnail + } + let baseUrl if (this.backendPreference === 'invidious') { baseUrl = this.currentInvidiousInstance @@ -317,8 +328,6 @@ export default defineComponent({ return `${baseUrl}/vi/${this.id}/mq2.jpg` case 'end': return `${baseUrl}/vi/${this.id}/mq3.jpg` - case 'hidden': - return require('../../assets/img/thumbnail_placeholder.svg') default: return `${baseUrl}/vi/${this.id}/mqdefault.jpg` } @@ -367,6 +376,13 @@ export default defineComponent({ } }, + displayDuration: function () { + if (this.useDeArrowTitles && (this.duration === '' || this.duration === '0:00') && this.deArrowCache?.videoDuration) { + return formatDurationAsTimestamp(this.deArrowCache.videoDuration) + } + return this.duration + }, + playlistIdTypePairFinal() { if (this.playlistId) { return { @@ -424,6 +440,10 @@ export default defineComponent({ return this.$store.getters.getUseDeArrowTitles }, + useDeArrowThumbnails: function () { + return this.$store.getters.getUseDeArrowThumbnails + }, + deArrowCache: function () { return this.$store.getters.getDeArrowCache[this.id] }, @@ -444,21 +464,54 @@ export default defineComponent({ this.parseVideoData() this.checkIfWatched() - if (this.useDeArrowTitles && !this.deArrowCache) { + if ((this.useDeArrowTitles || this.useDeArrowThumbnails) && !this.deArrowCache) { this.fetchDeArrowData() } + + if (this.useDeArrowThumbnails && this.deArrowCache && this.deArrowCache.thumbnail == null) { + if (this.debounceGetDeArrowThumbnail == null) { + this.debounceGetDeArrowThumbnail = debounce(this.fetchDeArrowThumbnail, 1000) + } + + this.debounceGetDeArrowThumbnail() + } }, methods: { + fetchDeArrowThumbnail: async function() { + if (this.thumbnailPreference === 'hidden') { return } + const videoId = this.id + const thumbnail = await deArrowThumbnail(videoId, this.deArrowCache.thumbnailTimestamp) + if (thumbnail) { + const deArrowCacheClone = deepCopy(this.deArrowCache) + deArrowCacheClone.thumbnail = thumbnail + this.$store.commit('addThumbnailToDeArrowCache', deArrowCacheClone) + } + }, fetchDeArrowData: async function() { const videoId = this.id const data = await deArrowData(this.id) - const cacheData = { videoId, title: null } + const cacheData = { videoId, title: null, videoDuration: null, thumbnail: null, thumbnailTimestamp: null } if (Array.isArray(data?.titles) && data.titles.length > 0 && (data.titles[0].locked || data.titles[0].votes >= 0)) { cacheData.title = data.titles[0].title } + if (Array.isArray(data?.thumbnails) && data.thumbnails.length > 0 && (data.thumbnails[0].locked || data.thumbnails[0].votes >= 0)) { + cacheData.thumbnailTimestamp = data.thumbnails.at(0).timestamp + } else if (data?.videoDuration != null) { + cacheData.thumbnailTimestamp = data.videoDuration * data.randomTime + } + cacheData.videoDuration = data?.videoDuration ? Math.floor(data.videoDuration) : null // Save data to cache whether data available or not to prevent duplicate requests this.$store.commit('addVideoToDeArrowCache', cacheData) + + // fetch dearrow thumbnails if enabled + if (this.useDeArrowThumbnails && this.deArrowCache?.thumbnail === null) { + if (this.debounceGetDeArrowThumbnail == null) { + this.debounceGetDeArrowThumbnail = debounce(this.fetchDeArrowThumbnail, 1000) + } + + this.debounceGetDeArrowThumbnail() + } }, handleExternalPlayer: function () { diff --git a/src/renderer/components/ft-list-video/ft-list-video.vue b/src/renderer/components/ft-list-video/ft-list-video.vue index 495b3464b..d069a53b2 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.vue +++ b/src/renderer/components/ft-list-video/ft-list-video.vue @@ -24,14 +24,14 @@ >
- {{ isLive ? $t("Video.Live") : (isUpcoming ? $t("Video.Upcoming") : duration) }} + {{ isLive ? $t("Video.Live") : (isUpcoming ? $t("Video.Upcoming") : displayDuration) }}
+