Update subscription cache when visiting a channel (#4667)

This commit is contained in:
absidue 2024-03-01 14:27:28 +01:00 committed by GitHub
parent 1bdeb5f67a
commit 4020139840
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 135 additions and 1 deletions

View File

@ -54,6 +54,10 @@ const actions = {
commit('updateShortsCacheByChannel', payload)
},
updateSubscriptionShortsCacheWithChannelPageShorts: ({ commit }, payload) => {
commit('updateShortsCacheWithChannelPageShorts', payload)
},
updateSubscriptionLiveCacheByChannel: ({ commit }, payload) => {
commit('updateLiveCacheByChannel', payload)
},
@ -86,6 +90,31 @@ const mutations = {
if (videos != null) { newObject.videos = videos }
state.shortsCache[channelId] = newObject
},
updateShortsCacheWithChannelPageShorts(state, { channelId, videos }) {
const cachedObject = state.shortsCache[channelId]
if (cachedObject && cachedObject.videos.length > 0) {
cachedObject.videos.forEach(cachedVideo => {
const channelVideo = videos.find(short => cachedVideo.videoId === short.videoId)
if (channelVideo) {
// authorId probably never changes, so we don't need to update that
cachedVideo.title = channelVideo.title
cachedVideo.author = channelVideo.author
// as the channel shorts page only has compact view counts for numbers above 1000 e.g. 12k
// and the RSS feeds include an exact value, we only want to overwrite it when the number is larger than the cached value
// 12345 vs 12000 => 12345
// 12345 vs 15000 => 15000
if (channelVideo.viewCount > cachedVideo.viewCount) {
cachedVideo.viewCount = channelVideo.viewCount
}
}
})
}
},
clearShortsCache(state) {
state.shortsCache = {}
},

View File

@ -33,6 +33,10 @@ import {
parseLocalListVideo,
parseLocalSubscriberCount
} from '../../helpers/api/local'
import {
addPublishedDatesInvidious,
addPublishedDatesLocal
} from '../../helpers/subscriptions'
export default defineComponent({
name: 'Channel',
@ -171,6 +175,13 @@ export default defineComponent({
return this.subscriptionInfo !== null
},
isSubscribedInAnyProfile: function () {
const profileList = this.$store.getters.getProfileList
// check the all channels profile
return profileList[0].subscriptions.some((channel) => channel.id === this.id)
},
videoLiveSelectNames: function () {
return [
this.$t('Channel.Videos.Sort Types.Newest'),
@ -767,6 +778,17 @@ export default defineComponent({
this.latestVideos = parseLocalChannelVideos(videosTab.videos, this.id, this.channelName)
this.videoContinuationData = videosTab.has_continuation ? videosTab : null
this.isElementListLoading = false
if (this.isSubscribedInAnyProfile && this.latestVideos.length > 0 && this.videoSortBy === 'newest') {
addPublishedDatesLocal(this.latestVideos)
this.updateSubscriptionVideosCacheByChannel({
channelId: this.id,
// create a copy so that we only cache the first page
// if we use the same array, the store will get angry at us for modifying it outside of the store,
// when the user clicks load more
videos: [...this.latestVideos]
})
}
} catch (err) {
console.error(err)
const errorMessage = this.$t('Local API Error (Click to copy)')
@ -825,6 +847,16 @@ export default defineComponent({
this.latestShorts = parseLocalChannelShorts(shortsTab.videos, this.id, this.channelName)
this.shortContinuationData = shortsTab.has_continuation ? shortsTab : null
this.isElementListLoading = false
if (this.isSubscribedInAnyProfile && this.latestShorts.length > 0 && this.shortSortBy === 'newest') {
// As the shorts tab API response doesn't include the published dates,
// we can't just write the results to the subscriptions cache like we do with videos and live (can't sort chronologically without the date).
// However we can still update the metadata in the cache such as the view count and title that might have changed since it was cached
this.updateSubscriptionShortsCacheWithChannelPageShorts({
channelId: this.id,
videos: this.latestShorts
})
}
} catch (err) {
console.error(err)
const errorMessage = this.$t('Local API Error (Click to copy)')
@ -883,6 +915,17 @@ export default defineComponent({
this.latestLive = parseLocalChannelVideos(liveTab.videos, this.id, this.channelName)
this.liveContinuationData = liveTab.has_continuation ? liveTab : null
this.isElementListLoading = false
if (this.isSubscribedInAnyProfile && this.latestLive.length > 0 && this.liveSortBy === 'newest') {
addPublishedDatesLocal(this.latestLive)
this.updateSubscriptionLiveCacheByChannel({
channelId: this.id,
// create a copy so that we only cache the first page
// if we use the same array, the store will get angry at us for modifying it outside of the store,
// when the user clicks load more
videos: [...this.latestLive]
})
}
} catch (err) {
console.error(err)
const errorMessage = this.$t('Local API Error (Click to copy)')
@ -1052,6 +1095,16 @@ export default defineComponent({
}
this.videoContinuationData = response.continuation || null
this.isElementListLoading = false
if (this.isSubscribedInAnyProfile && !more && this.latestVideos.length > 0 && this.videoSortBy === 'newest') {
addPublishedDatesInvidious(this.latestVideos)
this.updateSubscriptionVideosCacheByChannel({
channelId: this.id,
// create a copy so that we only cache the first page
// if we use the same array, it will also contain all the next pages
videos: [...this.latestVideos]
})
}
}).catch((err) => {
console.error(err)
const errorMessage = this.$t('Invidious API Error (Click to copy)')
@ -1101,6 +1154,17 @@ export default defineComponent({
}
this.shortContinuationData = response.continuation || null
this.isElementListLoading = false
if (this.isSubscribedInAnyProfile && !more && this.latestShorts.length > 0 && this.shortSortBy === 'newest') {
// As the shorts tab API response doesn't include the published dates,
// we can't just write the results to the subscriptions cache like we do with videos and live (can't sort chronologically without the date).
// However we can still update the metadata in the cache e.g. adding the duration, as that isn't included in the RSS feeds
// and updating the view count and title that might have changed since it was cached
this.updateSubscriptionShortsCacheWithChannelPageShorts({
channelId: this.id,
videos: this.latestShorts
})
}
}).catch((err) => {
console.error(err)
const errorMessage = this.$t('Invidious API Error (Click to copy)')
@ -1142,6 +1206,17 @@ export default defineComponent({
}
this.liveContinuationData = response.continuation || null
this.isElementListLoading = false
if (this.isSubscribedInAnyProfile && !more && this.latestLive.length > 0 && this.liveSortBy === 'newest') {
addPublishedDatesInvidious(this.latestLive)
this.updateSubscriptionLiveCacheByChannel({
channelId: this.id,
// create a copy so that we only cache the first page
// if we use the same array, the store will get angry at us for modifying it outside of the store,
// when the user clicks load more
videos: [...this.latestLive]
})
}
}).catch((err) => {
console.error(err)
const errorMessage = this.$t('Invidious API Error (Click to copy)')
@ -1559,6 +1634,19 @@ export default defineComponent({
this.latestCommunityPosts = parseLocalCommunityPosts(posts)
this.communityContinuationData = communityTab.has_continuation ? communityTab : null
if (this.latestCommunityPosts.length > 0) {
this.latestCommunityPosts.forEach(post => {
post.authorId = this.id
})
this.updateSubscriptionPostsCacheByChannel({
channelId: this.id,
// create a copy so that we only cache the first page
// if we use the same array, the store will get angry at us for modifying it outside of the store,
// when the user clicks load more
posts: [...this.latestCommunityPosts]
})
}
} catch (err) {
console.error(err)
const errorMessage = this.$t('Local API Error (Click to copy)')
@ -1610,6 +1698,19 @@ export default defineComponent({
this.latestCommunityPosts = posts
}
this.communityContinuationData = continuation
if (this.isSubscribedInAnyProfile && !more && this.latestCommunityPosts.length > 0) {
this.latestCommunityPosts.forEach(post => {
post.authorId = this.id
})
this.updateSubscriptionPostsCacheByChannel({
channelId: this.id,
// create a copy so that we only cache the first page
// if we use the same array, the store will get angry at us for modifying it outside of the store,
// when the user clicks load more
posts: [...this.latestCommunityPosts]
})
}
}).catch(async (err) => {
console.error(err)
const errorMessage = this.$t('Invidious API Error (Click to copy)')
@ -1849,7 +1950,11 @@ export default defineComponent({
...mapActions([
'showOutlines',
'updateSubscriptionDetails'
'updateSubscriptionDetails',
'updateSubscriptionVideosCacheByChannel',
'updateSubscriptionLiveCacheByChannel',
'updateSubscriptionShortsCacheWithChannelPageShorts',
'updateSubscriptionPostsCacheByChannel'
])
}
})