From a9dadc47574181302f94857ee47252d4fa25b1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4ki?= Date: Wed, 27 Nov 2024 08:44:09 +0200 Subject: [PATCH] Change how online mod list update process works If new mod list was downloaded and stored to IndexDB successfully, but loading the mods to Vuex failed, user would end up in situation where the mod list is empty but it wouldn't be updated until a new version was available in the API. To prevent this, we now always attempt to load the mod list in to Vuex if the the mod list stored there is empty. --- src/store/modules/TsModsModule.ts | 50 +++++++++++++++++-------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/store/modules/TsModsModule.ts b/src/store/modules/TsModsModule.ts index aa5f84ce..9bb1ccc6 100644 --- a/src/store/modules/TsModsModule.ts +++ b/src/store/modules/TsModsModule.ts @@ -157,28 +157,40 @@ export const TsModsModule = { }, actions: >{ - async fetchAndProcessPackageList({dispatch}) { + async fetchAndProcessPackageList({dispatch, state}) { const packageListIndex: PackageListIndex = await dispatch('fetchPackageListIndex'); + // If the package list is up to date, only update the timestamp. Otherwise, + // fetch the new one and store it into IndexedDB. if (packageListIndex.isLatest) { - await dispatch('updateModsLastUpdated'); - return; + await dispatch('updateIndexHash', packageListIndex.hash); + } else { + const packageListChunks = await dispatch( + 'fetchPackageListChunks', + {chunkUrls: packageListIndex.content}, + ); + await dispatch( + 'updatePersistentCache', + {chunks: packageListChunks, indexHash: packageListIndex.hash}, + ); } - const packageListChunks = await dispatch( - 'fetchPackageListChunks', - {chunkUrls: packageListIndex.content}, - ); - await dispatch( - 'updatePersistentCache', - {chunks: packageListChunks, indexHash: packageListIndex.hash}, - ); - await dispatch('updateMods'); - await dispatch('profile/tryLoadModListFromDisk', null, {root: true}); - await dispatch('prewarmCache'); + // If the package list was up to date and the mod list is already loaded to + // Vuex, just update the timestamp. Otherwise, load the list from IndexedDB + // to Vuex. This needs to be done even if the index hasn't updated when the + // mod list in Vuex is empty, as this indicates an error state and otherwise + // the user would be stuck with empty list until a new index hash is + // available via the API. + if (packageListIndex.isLatest && state.mods.length > 0) { + await dispatch('updateModsLastUpdated'); + } else { + await dispatch('updateMods'); + await dispatch('profile/tryLoadModListFromDisk', null, {root: true}); + await dispatch('prewarmCache'); + } }, - async fetchPackageListIndex({dispatch, rootState}): Promise { + async fetchPackageListIndex({rootState}): Promise { const indexUrl = CdnProvider.addCdnQueryParameter(rootState.activeGame.thunderstoreUrl); const index = await retry(() => fetchAndProcessBlobFile(indexUrl), 5, 2000); @@ -191,14 +203,6 @@ export const TsModsModule = { const community = rootState.activeGame.internalFolderName; const isLatest = await PackageDb.isLatestPackageListIndex(community, index.hash); - - // Normally the hash would be updated after the mod list is successfully - // fetched and written to IndexedDB, but if the list hasn't changed, - // those step are skipped, so update the "last seen" timestamp now. - if (isLatest) { - await dispatch('updateIndexHash', index.hash); - } - return {...index, isLatest}; },