Skip to content

Commit

Permalink
Simplify download logic by omitting callback
Browse files Browse the repository at this point in the history
  • Loading branch information
VilppeRiskidev committed Jan 28, 2025
1 parent 9e730e3 commit 9ca4173
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 121 deletions.
4 changes: 4 additions & 0 deletions src/components/mixins/DownloadMixin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export default class DownloadMixin extends Vue {
this.$store.commit("closeDownloadModModal");
}
setIsModProgressModalOpen(open: boolean): void {
this.$store.commit('download/setIsModProgressModalOpen', open);
}
get isOpen(): boolean {
return this.$store.state.modals.isDownloadModModalOpen;
}
Expand Down
142 changes: 86 additions & 56 deletions src/components/views/DownloadModModal.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div>
<div id='downloadProgressModal' :class="['modal', {'is-active':$store.state.download.isModProgressModalOpen}]" v-if="$store.getters['download/currentDownload'] !== null">
<div class="modal-background" @click="$store.commit('download/setIsModProgressModalOpen', false);"></div>
<div class="modal-background" @click="setIsModProgressModalOpen(false);"></div>
<div class='modal-content'>
<div class='notification is-info'>
<h3 class='title'>Downloading {{$store.getters['download/currentDownload'].modName}}</h3>
Expand All @@ -13,7 +13,7 @@
/>
</div>
</div>
<button class="modal-close is-large" aria-label="close" @click="$store.commit('download/setIsModProgressModalOpen', false);"></button>
<button class="modal-close is-large" aria-label="close" @click="setIsModProgressModalOpen(false);"></button>
</div>
<DownloadModVersionSelectModal @download-mod="downloadHandler" />
<UpdateAllInstalledModsModal />
Expand Down Expand Up @@ -60,54 +60,65 @@ import ProfileModList from '../../r2mm/mods/ProfileModList';
store: Store<any>
): Promise<void> {
return new Promise(async (resolve, reject) => {
const tsMod = combo.getMod();
const tsVersion = combo.getVersion();
const assignId = await store.dispatch(
'download/addDownload',
[`${tsMod.getName()} (${tsVersion.getVersionNumber().toString()})`]
[`${combo.getMod().getName()} (${combo.getVersion().getVersionNumber().toString()})`]
);
setTimeout(() => {
ThunderstoreDownloaderProvider.instance.download(profile.asImmutableProfile(), tsMod, tsVersion, ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
try {
if (status === StatusEnum.FAILURE) {
store.commit('download/updateDownload', {assignId, failed: true});
if (err !== null) {
DownloadMixin.addSolutionsToError(err);
return reject(err);
}
} else if (status === StatusEnum.PENDING) {
store.commit('download/updateDownload', {assignId, progress, modName});
}
} catch (e) {
return reject(e);
}
}, async (downloadedMods: ThunderstoreCombo[]) => {
ProfileModList.requestLock(async () => {
for (const combo of downloadedMods) {
setTimeout(async () => {
let downloadedMods: ThunderstoreCombo[] = [];
try {
downloadedMods = await ThunderstoreDownloaderProvider.instance.download(
profile.asImmutableProfile(),
combo,
ignoreCache,
(progress: number, modName: string, status: number, err: R2Error | null) => {
try {
await DownloadModModal.installModAfterDownload(profile, combo.getMod(), combo.getVersion());
DownloadModModal.downloadProgressCallback(store, assignId, progress, modName, status, err);
} catch (e) {
return reject(
R2Error.fromThrownValue(e, `Failed to install mod [${combo.getMod().getFullName()}]`)
);
reject(e);
}
}
const modList = await ProfileModList.getModList(profile.asImmutableProfile());
if (!(modList instanceof R2Error)) {
const err = await ConflictManagementProvider.instance.resolveConflicts(modList, profile.asImmutableProfile());
if (err instanceof R2Error) {
return reject(err);
}
);
} catch (e) {
return reject(e);
}
await ProfileModList.requestLock(async () => {
for (const combo of downloadedMods) {
try {
await DownloadModModal.installModAfterDownload(profile, combo.getMod(), combo.getVersion());
} catch (e) {
return reject(
R2Error.fromThrownValue(e, `Failed to install mod [${combo.getMod().getFullName()}]`)
);
}
return resolve();
});
}
const modList = await ProfileModList.getModList(profile.asImmutableProfile());
if (!(modList instanceof R2Error)) {
const err = await ConflictManagementProvider.instance.resolveConflicts(modList, profile.asImmutableProfile());
if (err instanceof R2Error) {
return reject(err);
}
}
return resolve();
});
}, 1);
});
}
static downloadProgressCallback(store: Store<any>, assignId: number, progress: number, modName: string, status: number, err: R2Error | null) {
if (status === StatusEnum.FAILURE) {
store.commit('download/updateDownload', {assignId, failed: true});
if (err !== null) {
DownloadMixin.addSolutionsToError(err);
throw err;
}
} else if (status === StatusEnum.PENDING) {
store.commit('download/updateDownload', {assignId, progress, modName});
}
}
async downloadHandler(tsMod: ThunderstoreMod, tsVersion: ThunderstoreVersion) {
this.closeModal();
Expand All @@ -116,30 +127,49 @@ import ProfileModList from '../../r2mm/mods/ProfileModList';
[`${tsMod.getName()} (${tsVersion.getVersionNumber().toString()})`]
);
this.$store.commit('download/setIsModProgressModalOpen', true);
setTimeout(() => {
ThunderstoreDownloaderProvider.instance.download(this.profile.asImmutableProfile(), tsMod, tsVersion, this.ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
try {
if (status === StatusEnum.FAILURE) {
this.$store.commit('download/setIsModProgressModalOpen', false);
this.$store.commit('download/updateDownload', {assignId, failed: true});
if (err !== null) {
DownloadMixin.addSolutionsToError(err);
throw err;
}
} else if (status === StatusEnum.PENDING) {
this.$store.commit('download/updateDownload', {assignId, progress, modName});
}
} catch (e) {
this.$store.commit('error/handleError', R2Error.fromThrownValue(e));
}
}, async (downloadedMods) => {
await this.downloadCompletedCallback(downloadedMods);
this.$store.commit('download/setIsModProgressModalOpen', false);
});
this.setIsModProgressModalOpen(true);
const tsCombo = new ThunderstoreCombo();
tsCombo.setMod(tsMod);
tsCombo.setVersion(tsVersion);
setTimeout(async () => {
let downloadedMods: ThunderstoreCombo[] = [];
try {
downloadedMods = await ThunderstoreDownloaderProvider.instance.download(
this.profile.asImmutableProfile(),
tsCombo,
this.ignoreCache,
(progress, modName, status, err) => { this.downloadProgressCallback(assignId, progress, modName, status, err); }
);
} catch (e) {
this.setIsModProgressModalOpen(false);
this.$store.commit('error/handleError', R2Error.fromThrownValue(e));
return;
}
await this.downloadCompletedCallback(downloadedMods);
this.setIsModProgressModalOpen(false);
}, 1);
}
downloadProgressCallback(assignId: number, progress: number, modName: string, status: number, err: R2Error | null) {
try {
if (status === StatusEnum.FAILURE) {
this.setIsModProgressModalOpen(false);
this.$store.commit('download/updateDownload', {assignId, failed: true});
if (err !== null) {
DownloadMixin.addSolutionsToError(err);
throw err;
}
} else if (status === StatusEnum.PENDING) {
this.$store.commit('download/updateDownload', {assignId, progress, modName});
}
} catch (e) {
this.$store.commit('error/handleError', R2Error.fromThrownValue(e));
}
};
static async installModAfterDownload(profile: Profile, mod: ThunderstoreMod, version: ThunderstoreVersion): Promise<R2Error | void> {
return new Promise(async (resolve, reject) => {
const manifestMod: ManifestV2 = new ManifestV2().fromThunderstoreMod(mod, version);
Expand Down
1 change: 0 additions & 1 deletion src/components/views/DownloadModVersionSelectModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ import ModalCard from "../ModalCard.vue";
import DownloadMixin from "../../components/mixins/DownloadMixin.vue";
import R2Error from "../../model/errors/R2Error";
import ManifestV2 from "../../model/ManifestV2";
import ThunderstoreMod from "../../model/ThunderstoreMod";
import ThunderstoreVersion from "../../model/ThunderstoreVersion";
import { MOD_LOADER_VARIANTS } from "../../r2mm/installing/profile_installers/ModLoaderVariantRecord";
import * as PackageDb from "../../r2mm/manager/PackageDexieStore";
Expand Down
6 changes: 3 additions & 3 deletions src/components/views/UpdateAllInstalledModsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ export default class UpdateAllInstalledModsModal extends mixins(DownloadMixin)
modsWithUpdates.map(value => `${value.getMod().getName()} (${value.getVersion().getVersionNumber().toString()})`)
);
this.$store.commit('download/setIsModProgressModalOpen', true);
this.setIsModProgressModalOpen(true);
ThunderstoreDownloaderProvider.instance.downloadLatestOfAll(modsWithUpdates, this.ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
try {
if (status === StatusEnum.FAILURE) {
this.$store.commit('download/setIsModProgressModalOpen', false);
this.setIsModProgressModalOpen(false);
this.$store.commit('download/updateDownload', {assignId, failed: true});
if (err !== null) {
DownloadMixin.addSolutionsToError(err);
Expand All @@ -66,7 +66,7 @@ export default class UpdateAllInstalledModsModal extends mixins(DownloadMixin)
}
}, async (downloadedMods) => {
await this.downloadCompletedCallback(downloadedMods);
this.$store.commit('download/setIsModProgressModalOpen', false);
this.setIsModProgressModalOpen(false);
});
}
}
Expand Down
21 changes: 10 additions & 11 deletions src/providers/ror2/downloading/ThunderstoreDownloaderProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import ProviderUtils from '../../generic/ProviderUtils';
import ThunderstoreVersion from '../../../model/ThunderstoreVersion';
import ThunderstoreMod from '../../../model/ThunderstoreMod';
import ThunderstoreCombo from '../../../model/ThunderstoreCombo';
import R2Error from '../../../model/errors/R2Error';
import { ImmutableProfile } from '../../../model/Profile';
Expand Down Expand Up @@ -49,17 +48,17 @@ export default abstract class ThunderstoreDownloaderProvider {
/**
* A top-level method to download the latest version of a mod including its dependencies.
*
* @param profile The profile the mod is downloaded for (needed to prevent dependencies from updating existing mods).
* @param mod The mod to be downloaded.
* @param modVersion The version of the mod to download.
* @param ignoreCache Download mod even if it already exists in the cache.
* @param callback Callback to show the current state of the downloads.
* @param completedCallback Callback to perform final actions against. Only called if {@param callback} has not returned a failed status.
* @param profile The profile the mod is downloaded for (needed to prevent dependencies from updating existing mods).
* @param combo The combo to be downloaded.
* @param ignoreCache Download mod even if it already exists in the cache.
* @param totalProgressCallback Callback to show the combined state of all the downloads.
*/
public abstract download(profile: ImmutableProfile, mod: ThunderstoreMod, modVersion: ThunderstoreVersion,
ignoreCache: boolean,
callback: (progress: number, modName: string, status: number, err: R2Error | null) => void,
completedCallback: (modList: ThunderstoreCombo[]) => void): void;
public abstract download(
profile: ImmutableProfile,
combo: ThunderstoreCombo,
ignoreCache: boolean,
totalProgressCallback: (progress: number, modName: string, status: number, err: R2Error | null) => void
): Promise<ThunderstoreCombo[]>;

/**
* A top-level method to download exact versions of exported mods.
Expand Down
Loading

0 comments on commit 9ca4173

Please sign in to comment.