Skip to content

Commit

Permalink
Move refreshThunderstoreModList to Vuex
Browse files Browse the repository at this point in the history
As the number of callsites increases, it makes more sense to have the
method for downloading the latest mod list, storing it into IndexedDB
and loading packages to Vuex inside Vuex, so each component doesn't
need to extend the UtilityMixin just to access it.

For TSMM this also allows injecting telemetry gathering to the method
inside Vuex, and not needing to due it awkwardly in App.vue.
  • Loading branch information
anttimaki committed Dec 20, 2024
1 parent e6581bf commit 7705a26
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 39 deletions.
10 changes: 4 additions & 6 deletions src/components/ModListUpdateBanner.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<script lang="ts">
import { mixins } from 'vue-class-component';
import { Component, Watch } from 'vue-property-decorator';
import { Component, Vue, Watch } from 'vue-property-decorator';
import UtilityMixin from './mixins/UtilityMixin.vue';
import ManagerInformation from '../_managerinf/ManagerInformation';
@Component({})
export default class ModListUpdateBanner extends mixins(UtilityMixin) {
export default class ModListUpdateBanner extends Vue {
updateError = '';
get appName(): string {
Expand Down Expand Up @@ -41,10 +39,10 @@ export default class ModListUpdateBanner extends mixins(UtilityMixin) {
// Invalidate hash to force a refresh. Otherwise a scenario where
// the latest index hash is already present in IndexedDB but loading
// the package list into Vuex store has failed would cause the banner
// to just disappear when refreshThunderstoreModList skips the actual
// to just disappear when fetchAndProcessPackageList skips the actual
// update but updates the timestamp of the hash.
await this.$store.dispatch('tsMods/updateIndexHash', 'invalidated');
await this.refreshThunderstoreModList();
await this.$store.dispatch('tsMods/fetchAndProcessPackageList');
} catch (e) {
this.updateError = `${e}`;
} finally {
Expand Down
29 changes: 1 addition & 28 deletions src/components/mixins/UtilityMixin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Component from 'vue-class-component';
import R2Error from '../../model/errors/R2Error';
import CdnProvider from '../../providers/generic/connection/CdnProvider';
import { PackageListIndex } from '../../store/modules/TsModsModule';
@Component
export default class UtilityMixin extends Vue {
Expand All @@ -15,32 +14,6 @@ export default class UtilityMixin extends Vue {
setInterval(this.backgroundRefreshThunderstoreModList, this.REFRESH_INTERVAL);
}
// Wrapper to allow TSMM to inject telemetry gathering.
async refreshThunderstoreModList() {
await this._refreshThunderstoreModList();
}
async _refreshThunderstoreModList() {
const packageListIndex: PackageListIndex = await this.$store.dispatch("tsMods/fetchPackageListIndex");
if (packageListIndex.isLatest) {
await this.$store.dispatch("tsMods/updateModsLastUpdated");
return;
}
const packageListChunks = await this.$store.dispatch(
"tsMods/fetchPackageListChunks",
{chunkUrls: packageListIndex.content},
);
await this.$store.dispatch(
"tsMods/updatePersistentCache",
{chunks: packageListChunks, indexHash: packageListIndex.hash},
);
await this.$store.dispatch("tsMods/updateMods");
await this.$store.dispatch("profile/tryLoadModListFromDisk");
await this.$store.dispatch("tsMods/prewarmCache");
}
/**
* Periodically refresh the Thunderstore mod list in the background.
*
Expand All @@ -65,7 +38,7 @@ export default class UtilityMixin extends Vue {
try {
this.$store.commit("tsMods/startThunderstoreModListUpdate");
await this.refreshThunderstoreModList();
await this.$store.dispatch('tsMods/fetchAndProcessPackageList');
} catch (e) {
if (this.tsBackgroundRefreshFailed) {
console.error("Two consecutive background refresh attempts failed");
Expand Down
9 changes: 4 additions & 5 deletions src/components/settings-components/SettingsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@

<script lang="ts">
import { Watch } from 'vue-property-decorator';
import Component, { mixins } from 'vue-class-component';
import { Vue, Watch } from 'vue-property-decorator';
import Component from 'vue-class-component';
import SettingsItem from './SettingsItem.vue';
import SettingsRow from '../../model/settings/SettingsRow';
import ManagerSettings from '../../r2mm/manager/ManagerSettings';
Expand All @@ -62,7 +62,6 @@ import ManifestV2 from '../../model/ManifestV2';
import Game from '../../model/game/Game';
import { StorePlatform } from '../../model/game/StorePlatform';
import moment from 'moment';
import UtilityMixin from '../mixins/UtilityMixin.vue';
import CdnProvider from '../../providers/generic/connection/CdnProvider';
@Component({
Expand All @@ -71,7 +70,7 @@ import CdnProvider from '../../providers/generic/connection/CdnProvider';
Hero
}
})
export default class SettingsView extends mixins(UtilityMixin) {
export default class SettingsView extends Vue {
private activeTab: string = 'All';
private tabs = ['All', 'Profile', 'Locations', 'Debugging', 'Modpacks', 'Other'];
Expand Down Expand Up @@ -320,7 +319,7 @@ import CdnProvider from '../../providers/generic/connection/CdnProvider';
this.$store.commit("tsMods/setThunderstoreModListUpdateError", "");
try {
await this.refreshThunderstoreModList();
await this.$store.dispatch("tsMods/fetchAndProcessPackageList");
} catch (e) {
this.$store.commit("tsMods/setThunderstoreModListUpdateError", e);
} finally {
Expand Down
21 changes: 21 additions & 0 deletions src/store/modules/TsModsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,27 @@ export const TsModsModule = {
},

actions: <ActionTree<State, RootState>>{
async fetchAndProcessPackageList({dispatch}) {
const packageListIndex: PackageListIndex = await dispatch('fetchPackageListIndex');

if (packageListIndex.isLatest) {
await dispatch('updateModsLastUpdated');
return;
}

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');
},

async fetchPackageListIndex({dispatch, rootState}): Promise<PackageListIndex> {
const indexUrl = CdnProvider.addCdnQueryParameter(rootState.activeGame.thunderstoreUrl);
const index = await retry(() => fetchAndProcessBlobFile(indexUrl), 5, 2000);
Expand Down

0 comments on commit 7705a26

Please sign in to comment.