From 93a4153e5e8739bb3607b725a150186d18c86392 Mon Sep 17 00:00:00 2001 From: PikachuEXE Date: Wed, 14 Jun 2023 14:00:00 +0800 Subject: [PATCH] * Update subscription view to be able to load videos from video cache again --- .../privacy-settings/privacy-settings.js | 10 +- src/renderer/store/modules/subscriptions.js | 74 +++++--- .../views/Subscriptions/Subscriptions.js | 159 ++++++++++-------- .../views/Subscriptions/Subscriptions.vue | 2 +- 4 files changed, 143 insertions(+), 102 deletions(-) diff --git a/src/renderer/components/privacy-settings/privacy-settings.js b/src/renderer/components/privacy-settings/privacy-settings.js index 7b2a406dc4863..03d65a5f88d6f 100644 --- a/src/renderer/components/privacy-settings/privacy-settings.js +++ b/src/renderer/components/privacy-settings/privacy-settings.js @@ -110,12 +110,7 @@ export default defineComponent({ } }) - this.updateAllSubscriptionsList([]) - this.updateProfileSubscriptions({ - activeProfile: MAIN_PROFILE_ID, - videoList: [], - errorChannels: [] - }) + this.clearSubscriptionsCache() } }, @@ -129,8 +124,7 @@ export default defineComponent({ 'updateProfile', 'removeProfile', 'updateActiveProfile', - 'updateAllSubscriptionsList', - 'updateProfileSubscriptions' + 'clearSubscriptionsCache', ]) } }) diff --git a/src/renderer/store/modules/subscriptions.js b/src/renderer/store/modules/subscriptions.js index 37be7815cbcab..4ed626ca340d9 100644 --- a/src/renderer/store/modules/subscriptions.js +++ b/src/renderer/store/modules/subscriptions.js @@ -1,39 +1,71 @@ import { MAIN_PROFILE_ID } from '../../../constants' -const state = { - allSubscriptionsList: [], - profileSubscriptions: { - activeProfile: MAIN_PROFILE_ID, +const defaultState = { + subscriptionsCacheForAllSubscriptionsProfile: { + videoList: [], + }, + subscriptionsCacheForActiveProfile: { videoList: [], - errorChannels: [] - } + profileID: '', + errorChannels: [], + }, +} + +function deepCopy(obj) { + return JSON.parse(JSON.stringify(obj)) +} + +const state = { + subscriptionsCacheForAllSubscriptionsProfile: deepCopy(defaultState.subscriptionsCacheForAllSubscriptionsProfile), + subscriptionsCacheForActiveProfile: deepCopy(defaultState.subscriptionsCacheForActiveProfile), } const getters = { - getAllSubscriptionsList: () => { - return state.allSubscriptionsList + getSubscriptionsCacheForAllSubscriptionsProfile: () => { + return state.subscriptionsCacheForAllSubscriptionsProfile + }, + getSubscriptionsCacheForProfile: (state) => (profileId) => { + if (state.subscriptionsCacheForActiveProfile.profileID !== profileId) { return null } + + return state.subscriptionsCacheForActiveProfile }, - getProfileSubscriptions: () => { - return state.profileSubscriptions - } } const actions = { - updateAllSubscriptionsList ({ commit }, subscriptions) { - commit('setAllSubscriptionsList', subscriptions) + updateSubscriptionsCacheForActiveProfile: ({ commit }, payload) => { + if (payload.profileID === MAIN_PROFILE_ID) { + commit('updateSubscriptionsCacheForAllSubscriptionsProfile', { + videoList: payload.videoList, + }) + } else { + // When cache for a non default profile (the one for all subscriptions) updated + // The cache for all subscriptions could be stale at that point + commit('clearSubscriptionsCacheForAllSubscriptionsProfile') + } + + commit('updateSubscriptionsCacheForActiveProfile', payload) + }, + clearSubscriptionsCache: ({ commit }) => { + commit('clearSubscriptionsCacheForAllSubscriptionsProfile') + commit('clearSubscriptionsCacheForActiveProfile') }, - updateProfileSubscriptions ({ commit }, subscriptions) { - commit('setProfileSubscriptions', subscriptions) - } } const mutations = { - setAllSubscriptionsList (state, allSubscriptionsList) { - state.allSubscriptionsList = allSubscriptionsList + updateSubscriptionsCacheForAllSubscriptionsProfile (state, { videoList }) { + state.subscriptionsCacheForAllSubscriptionsProfile.videoList = videoList + }, + updateSubscriptionsCacheForActiveProfile (state, { profileID, videoList, errorChannels }) { + state.subscriptionsCacheForActiveProfile.profileID = profileID + state.subscriptionsCacheForActiveProfile.videoList = videoList + state.subscriptionsCacheForActiveProfile.errorChannels = errorChannels + }, + clearSubscriptionsCacheForAllSubscriptionsProfile (state) { + state.subscriptionsCacheForAllSubscriptionsProfile = deepCopy(defaultState.subscriptionsCacheForAllSubscriptionsProfile) + }, + clearSubscriptionsCacheForActiveProfile (state) { + state.subscriptionsCacheForActiveProfile = deepCopy(defaultState.subscriptionsCacheForActiveProfile) }, - setProfileSubscriptions (state, profileSubscriptions) { - state.profileSubscriptions = profileSubscriptions - } } export default { diff --git a/src/renderer/views/Subscriptions/Subscriptions.js b/src/renderer/views/Subscriptions/Subscriptions.js index c952fa66f0053..afbed4a16d081 100644 --- a/src/renderer/views/Subscriptions/Subscriptions.js +++ b/src/renderer/views/Subscriptions/Subscriptions.js @@ -30,7 +30,7 @@ export default defineComponent({ dataLimit: 100, videoList: [], errorChannels: [], - attemptedFetch: false + attemptedFetch: false, } }, computed: { @@ -65,13 +65,24 @@ export default defineComponent({ activeProfile: function () { return this.$store.getters.getActiveProfile }, + activeProfileId: function () { + return this.activeProfile._id + }, + + subscriptionsCacheForAllSubscriptionsProfile: function () { + return this.$store.getters.getSubscriptionsCacheForAllSubscriptionsProfile + }, + videoCacheForAllSubscriptionsProfilePresent: function () { + return this.subscriptionsCacheForAllSubscriptionsProfile.videoList.length > 0 + }, - profileSubscriptions: function () { - return this.$store.getters.getProfileSubscriptions + subscriptionsCacheForActiveProfile: function () { + return this.$store.getters.getSubscriptionsCacheForProfile(this.activeProfile._id) }, + videoCacheForActiveProfilePresent: function () { + if (this.subscriptionsCacheForActiveProfile == null) { return false } - allSubscriptionsList: function () { - return this.$store.getters.getAllSubscriptionsList + return this.subscriptionsCacheForActiveProfile.videoList.length > 0 }, historyCache: function () { @@ -92,12 +103,13 @@ export default defineComponent({ fetchSubscriptionsAutomatically: function() { return this.$store.getters.getFetchSubscriptionsAutomatically - } + }, }, watch: { activeProfile: async function (_) { - this.getProfileSubscriptions() - } + this.isLoading = true + this.loadVideosFromCacheSometimes() + }, }, mounted: async function () { document.addEventListener('keydown', this.keyboardShortcutHandler) @@ -108,43 +120,70 @@ export default defineComponent({ this.dataLimit = dataLimit } - if (this.profileSubscriptions.videoList.length !== 0) { - if (this.profileSubscriptions.activeProfile === this.activeProfile._id) { - const subscriptionList = JSON.parse(JSON.stringify(this.profileSubscriptions)) - if (this.hideWatchedSubs) { - this.videoList = await Promise.all(subscriptionList.videoList.filter((video) => { - const historyIndex = this.historyCache.findIndex((x) => { - return x.videoId === video.videoId - }) - - return historyIndex === -1 - })) - } else { - this.videoList = subscriptionList.videoList - this.errorChannels = subscriptionList.errorChannels - } - } else { - this.getProfileSubscriptions() - } - - this.isLoading = false - } else if (this.fetchSubscriptionsAutomatically) { - setTimeout(async () => { - this.getSubscriptions() - }, 300) - } else { - this.isLoading = false - } + this.loadVideosFromCacheSometimes() }, beforeDestroy: function () { document.removeEventListener('keydown', this.keyboardShortcutHandler) }, methods: { + loadVideosFromCacheSometimes() { + // Called on view visible (initial view rendering, tab switching, etc.) + if (this.videoCacheForActiveProfilePresent) { + this.loadVideosFromCacheForActiveProfile() + return + } + + if (this.videoCacheForAllSubscriptionsProfilePresent) { + this.loadVideosFromCacheForAllSubscriptionsProfile() + return + } + + this.maybeLoadVideosForSubscriptionsFromRemote() + }, + + async loadVideosFromCacheForActiveProfile() { + const subscriptionList = JSON.parse(JSON.stringify(this.subscriptionsCacheForActiveProfile)) + this.errorChannels = subscriptionList.errorChannels + if (this.hideWatchedSubs) { + this.videoList = await Promise.all(subscriptionList.videoList.filter((video) => { + const historyIndex = this.historyCache.findIndex((x) => { + return x.videoId === video.videoId + }) + + return historyIndex === -1 + })) + } else { + this.videoList = subscriptionList.videoList + } + this.isLoading = false + }, + + async loadVideosFromCacheForAllSubscriptionsProfile() { + const cachedVideosFromAllSubscriptions = this.subscriptionsCacheForAllSubscriptionsProfile.videoList + // Load videos from cached videos for all subscriptions + this.videoList = await Promise.all(cachedVideosFromAllSubscriptions.filter((video) => { + const channelIndex = this.activeSubscriptionList.findIndex((subscribedChannel) => { + return subscribedChannel.id === video.authorId + }) + + if (this.hideWatchedSubs) { + const historyIndex = this.historyCache.findIndex((x) => { + return x.videoId === video.videoId + }) + + return channelIndex !== -1 && historyIndex === -1 + } else { + return channelIndex !== -1 + } + })) + this.isLoading = false + }, + goToChannel: function (id) { this.$router.push({ path: `/channel/${id}` }) }, - getSubscriptions: function () { + loadVideosForSubscriptionsFromRemote: function () { if (this.activeSubscriptionList.length === 0) { this.isLoading = false this.videoList = [] @@ -209,11 +248,6 @@ export default defineComponent({ return item.durationText !== 'PREMIERE' }) } - const profileSubscriptions = { - activeProfile: this.activeProfile._id, - videoList: videoList, - errorChannels: this.errorChannels - } this.videoList = await Promise.all(videoList.filter((video) => { if (this.hideWatchedSubs) { @@ -226,43 +260,25 @@ export default defineComponent({ return true } })) - this.updateProfileSubscriptions(profileSubscriptions) + this.updateSubscriptionsCacheForActiveProfile({ + profileID: this.activeProfileId, + videoList: videoList, + errorChannels: this.errorChannels, + }) this.isLoading = false this.updateShowProgressBar(false) - - if (this.activeProfile === MAIN_PROFILE_ID) { - this.updateAllSubscriptionsList(profileSubscriptions.videoList) - } } }) }, - getProfileSubscriptions: async function () { - if (this.allSubscriptionsList.length !== 0) { - this.isLoading = true - this.videoList = await Promise.all(this.allSubscriptionsList.filter((video) => { - const channelIndex = this.activeSubscriptionList.findIndex((x) => { - return x.id === video.authorId - }) - - if (this.hideWatchedSubs) { - const historyIndex = this.historyCache.findIndex((x) => { - return x.videoId === video.videoId - }) - - return channelIndex !== -1 && historyIndex === -1 - } else { - return channelIndex !== -1 - } - })) - this.isLoading = false - } else if (this.fetchSubscriptionsAutomatically) { - this.getSubscriptions() - } else if (this.activeProfile._id === this.profileSubscriptions.activeProfile) { - this.videoList = this.profileSubscriptions.videoList + maybeLoadVideosForSubscriptionsFromRemote: async function () { + if (this.fetchSubscriptionsAutomatically) { + // `this.isLoading = false` is called inside `loadVideosForSubscriptionsFromRemote` when needed + this.loadVideosForSubscriptionsFromRemote() } else { this.videoList = [] this.attemptedFetch = false + this.isLoading = false } }, @@ -476,7 +492,7 @@ export default defineComponent({ case 'r': case 'R': if (!this.isLoading) { - this.getSubscriptions() + this.loadVideosForSubscriptionsFromRemote() } break } @@ -484,8 +500,7 @@ export default defineComponent({ ...mapActions([ 'updateShowProgressBar', - 'updateProfileSubscriptions', - 'updateAllSubscriptionsList' + 'updateSubscriptionsCacheForActiveProfile', ]), ...mapMutations([ diff --git a/src/renderer/views/Subscriptions/Subscriptions.vue b/src/renderer/views/Subscriptions/Subscriptions.vue index 23529adeb37fd..9fd269fc94383 100644 --- a/src/renderer/views/Subscriptions/Subscriptions.vue +++ b/src/renderer/views/Subscriptions/Subscriptions.vue @@ -68,7 +68,7 @@ :title="$t('Subscriptions.Refresh Subscriptions')" :size="12" theme="primary" - @click="getSubscriptions" + @click="loadVideosForSubscriptionsFromRemote" />