Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download callback refactor #1594

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/components/mixins/DownloadMixin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
import Vue from 'vue';
import Component from 'vue-class-component';

import ThunderstoreMod from "../../model/ThunderstoreMod";
import R2Error from "../../model/errors/R2Error";
import Game from "../../model/game/Game";
import Profile from "../../model/Profile";
import ThunderstoreCombo from "../../model/ThunderstoreCombo";
import ThunderstoreMod from "../../model/ThunderstoreMod";
import { installModsAndResolveConflicts } from "../../utils/ProfileUtils";


@Component
Expand All @@ -29,5 +32,13 @@ export default class DownloadMixin extends Vue {
get profile(): Profile {
return this.$store.getters['profile/activeProfile'];
}

async downloadCompletedCallback(downloadedMods: ThunderstoreCombo[]): Promise<void> {
try {
await installModsAndResolveConflicts(downloadedMods, this.profile.asImmutableProfile(), this.$store);
} catch (e) {
this.$store.commit('error/handleError', R2Error.fromThrownValue(e));
}
}
}
</script>
155 changes: 88 additions & 67 deletions src/components/views/DownloadModModal.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<template>
<div>
<div id='downloadProgressModal' :class="['modal', {'is-active':downloadingMod}]" v-if="downloadObject !== null">
<div id='downloadProgressModal' :class="['modal', {'is-active':downloadingMod}]" v-if="$store.state.download.downloadObject !== null">
<div class="modal-background" @click="downloadingMod = false;"></div>
<div class='modal-content'>
<div class='notification is-info'>
<h3 class='title'>Downloading {{downloadObject.modName}}</h3>
<p>{{Math.floor(downloadObject.progress)}}% complete</p>
<h3 class='title'>Downloading {{$store.state.download.downloadObject.modName}}</h3>
<p>{{Math.floor($store.state.download.downloadObject.progress)}}% complete</p>
<Progress
:max='100'
:value='downloadObject.progress'
:value='$store.state.download.downloadObject.progress'
:className="['is-dark']"
/>
</div>
Expand Down Expand Up @@ -43,22 +43,23 @@

import { mixins } from "vue-class-component";
import { Component } from 'vue-property-decorator';
import ThunderstoreMod from '../../model/ThunderstoreMod';
import { Store } from "vuex";

import { Progress } from '../all';
import ModalCard from '../ModalCard.vue';
import DownloadModVersionSelectModal from "../../components/views/DownloadModVersionSelectModal.vue";
import DownloadMixin from "../mixins/DownloadMixin.vue";
import StatusEnum from '../../model/enums/StatusEnum';
import R2Error from '../../model/errors/R2Error';
import ManifestV2 from '../../model/ManifestV2';
import Profile from '../../model/Profile';
import ThunderstoreMod from '../../model/ThunderstoreMod';
import ThunderstoreVersion from '../../model/ThunderstoreVersion';
import ThunderstoreDownloaderProvider from '../../providers/ror2/downloading/ThunderstoreDownloaderProvider';
import R2Error from '../../model/errors/R2Error';
import StatusEnum from '../../model/enums/StatusEnum';
import ThunderstoreCombo from '../../model/ThunderstoreCombo';
import ConflictManagementProvider from '../../providers/generic/installing/ConflictManagementProvider';
import ProfileInstallerProvider from '../../providers/ror2/installing/ProfileInstallerProvider';
import ThunderstoreDownloaderProvider from '../../providers/ror2/downloading/ThunderstoreDownloaderProvider';
import ProfileModList from '../../r2mm/mods/ProfileModList';
import Profile from '../../model/Profile';
import { Progress } from '../all';
import ConflictManagementProvider from '../../providers/generic/installing/ConflictManagementProvider';
import ModalCard from '../ModalCard.vue';
import { installModsToProfile } from '../../utils/ProfileUtils';
import DownloadMixin from "../mixins/DownloadMixin.vue";
import DownloadModVersionSelectModal from "../../components/views/DownloadModVersionSelectModal.vue";

interface DownloadProgress {
assignId: number;
Expand All @@ -68,8 +69,6 @@ interface DownloadProgress {
failed: boolean;
}

let assignId = 0;

@Component({
components: {
DownloadModVersionSelectModal,
Expand All @@ -79,11 +78,8 @@ let assignId = 0;
})
export default class DownloadModModal extends mixins(DownloadMixin) {

downloadObject: DownloadProgress | null = null;
downloadingMod: boolean = false;

static allVersions: [number, DownloadProgress][] = [];

get ignoreCache(): boolean {
const settings = this.$store.getters['settings'];
return settings.getContext().global.ignoreCache;
Expand All @@ -92,28 +88,40 @@ let assignId = 0;
public static async downloadSpecific(
profile: Profile,
combo: ThunderstoreCombo,
ignoreCache: boolean
ignoreCache: boolean,
store: Store<any>
): Promise<void> {
return new Promise((resolve, reject) => {
const tsMod = combo.getMod();
const tsVersion = combo.getVersion();
const currentAssignId = assignId++;

store.commit('download/increaseAssignId');
const currentAssignId = store.state.download.assignId;

const progressObject = {
progress: 0,
initialMods: [`${tsMod.getName()} (${tsVersion.getVersionNumber().toString()})`],
modName: '',
assignId: currentAssignId,
failed: false,
};
DownloadModModal.allVersions.push([currentAssignId, progressObject]);

store.commit('download/pushDownloadObjectToAllVersions', {
assignId: currentAssignId,
downloadObject: progressObject
});

setTimeout(() => {
ThunderstoreDownloaderProvider.instance.download(profile.asImmutableProfile(), tsMod, tsVersion, ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
const assignIndex = DownloadModModal.allVersions.findIndex(([number, val]) => number === currentAssignId);
const assignIndex = store.state.download.allVersions.findIndex(([number, val]: [number, DownloadProgress]) => number === currentAssignId);
if (status === StatusEnum.FAILURE) {
if (err !== null) {
const existing = DownloadModModal.allVersions[assignIndex]
const existing = store.state.download.allVersions[assignIndex]
existing[1].failed = true;
DownloadModModal.allVersions[assignIndex] = [currentAssignId, existing[1]];
store.commit('download/updateDownloadObject', {
assignId: assignIndex,
downloadVersion: [currentAssignId, existing[1]]
});
DownloadModModal.addSolutionsToError(err);
return reject(err);
}
Expand All @@ -125,7 +133,10 @@ let assignId = 0;
assignId: currentAssignId,
failed: false,
}
DownloadModModal.allVersions[assignIndex] = [currentAssignId, obj];
store.commit('download/updateDownloadObject', {
assignId: assignIndex,
downloadVersion: [currentAssignId, obj]
});
}
}, async (downloadedMods: ThunderstoreCombo[]) => {
ProfileModList.requestLock(async () => {
Expand Down Expand Up @@ -155,25 +166,34 @@ let assignId = 0;
async downloadLatest() {
this.closeModal();
const modsWithUpdates: ThunderstoreCombo[] = await this.$store.dispatch('profile/getCombosWithUpdates');
const currentAssignId = assignId++;

this.$store.commit('download/increaseAssignId');
const currentAssignId = this.$store.state.download.assignId;

const progressObject = {
progress: 0,
initialMods: modsWithUpdates.map(value => `${value.getMod().getName()} (${value.getVersion().toString()})`),
modName: '',
assignId: currentAssignId,
failed: false,
};
this.downloadObject = progressObject;
DownloadModModal.allVersions.push([currentAssignId, this.downloadObject]);
this.$store.commit('download/setDownloadObject', progressObject);
this.$store.commit('download/pushDownloadObjectToAllVersions', {
assignId: currentAssignId,
downloadObject: progressObject
});
this.downloadingMod = true;
ThunderstoreDownloaderProvider.instance.downloadLatestOfAll(modsWithUpdates, this.ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
const assignIndex = DownloadModModal.allVersions.findIndex(([number, val]) => number === currentAssignId);
const assignIndex = this.$store.state.download.allVersions.findIndex(([number, val]: [number, DownloadProgress]) => number === currentAssignId);
if (status === StatusEnum.FAILURE) {
if (err !== null) {
this.downloadingMod = false;
const existing = DownloadModModal.allVersions[assignIndex]
const existing = this.$store.state.download.allVersions[assignIndex];
existing[1].failed = true;
this.$set(DownloadModModal.allVersions, assignIndex, [currentAssignId, existing[1]]);
this.$store.commit('download/updateDownloadObject', {
assignId: assignIndex,
downloadVersion: [currentAssignId, existing[1]]
});
DownloadModModal.addSolutionsToError(err);
this.$store.commit('error/handleError', err);
return;
Expand All @@ -186,36 +206,51 @@ let assignId = 0;
assignId: currentAssignId,
failed: false,
}
if (this.downloadObject!.assignId === currentAssignId) {
this.downloadObject = Object.assign({}, obj);
if (this.$store.state.download.downloadObject!.assignId === currentAssignId) {
this.$store.commit('download/setDownloadObject', obj);
}
this.$set(DownloadModModal.allVersions, assignIndex, [currentAssignId, obj]);
this.$store.commit('download/updateDownloadObject', {
assignId: assignIndex,
downloadVersion: [currentAssignId, obj]
});
}
}, this.downloadCompletedCallback);
}, (downloadedMods) => {
this.downloadCompletedCallback(downloadedMods);
this.downloadingMod = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just mentioning this in the hopes we remember to do this in the future PRs: this should be something like isDownloadProgressModalOpen and probably to be handled into ModalModule store. Ideally in a way that when one of the three modals in this file is opened, the other two are automatically closed.

});
}

downloadHandler(tsMod: ThunderstoreMod, tsVersion: ThunderstoreVersion) {
this.closeModal();
const currentAssignId = assignId++;

this.$store.commit('download/increaseAssignId');
const currentAssignId = this.$store.state.download.assignId;

const progressObject = {
progress: 0,
initialMods: [`${tsMod.getName()} (${tsVersion.getVersionNumber().toString()})`],
modName: '',
assignId: currentAssignId,
failed: false,
};
this.downloadObject = progressObject;
DownloadModModal.allVersions.push([currentAssignId, this.downloadObject]);
this.$store.commit('download/setDownloadObject', progressObject);
this.$store.commit('download/pushDownloadObjectToAllVersions', {
assignId: currentAssignId,
downloadObject: this.$store.state.download.downloadObject
});
this.downloadingMod = true;
setTimeout(() => {
ThunderstoreDownloaderProvider.instance.download(this.profile.asImmutableProfile(), tsMod, tsVersion, this.ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
const assignIndex = DownloadModModal.allVersions.findIndex(([number, val]) => number === currentAssignId);
const assignIndex = this.$store.state.download.allVersions.findIndex(([number, val]: [number, DownloadProgress]) => number === currentAssignId);
if (status === StatusEnum.FAILURE) {
if (err !== null) {
this.downloadingMod = false;
const existing = DownloadModModal.allVersions[assignIndex]
const existing = this.$store.state.download.allVersions[assignIndex];
existing[1].failed = true;
this.$set(DownloadModModal.allVersions, assignIndex, [currentAssignId, existing[1]]);
this.$store.commit('download/updateDownloadObject', {
assignId: assignIndex,
downloadVersion: [currentAssignId, existing[1]]
});
DownloadModModal.addSolutionsToError(err);
this.$store.commit('error/handleError', err);
return;
Expand All @@ -228,33 +263,19 @@ let assignId = 0;
assignId: currentAssignId,
failed: false,
}
if (this.downloadObject!.assignId === currentAssignId) {
this.downloadObject = Object.assign({}, obj);
if (this.$store.state.download.downloadObject!.assignId === currentAssignId) {
this.$store.commit('download/setDownloadObject', obj);
}
this.$set(DownloadModModal.allVersions, assignIndex, [currentAssignId, obj]);
}
}, this.downloadCompletedCallback);
}, 1);
}

async downloadCompletedCallback(downloadedMods: ThunderstoreCombo[]) {
ProfileModList.requestLock(async () => {
const profile = this.profile.asImmutableProfile();

try {
const modList = await installModsToProfile(downloadedMods, profile);
await this.$store.dispatch('profile/updateModList', modList);

const err = await ConflictManagementProvider.instance.resolveConflicts(modList, this.profile.asImmutableProfile());
if (err instanceof R2Error) {
throw err;
this.$store.commit('download/updateDownloadObject', {
assignId: assignIndex,
downloadVersion: [currentAssignId, obj]
});
}
} catch (e) {
this.$store.commit('error/handleError', R2Error.fromThrownValue(e));
} finally {
}, (downloadedMods) => {
this.downloadCompletedCallback(downloadedMods);
this.downloadingMod = false;
}
});
});
}, 1);
}

static async installModAfterDownload(profile: Profile, mod: ThunderstoreMod, version: ThunderstoreVersion): Promise<R2Error | void> {
Expand Down
5 changes: 2 additions & 3 deletions src/pages/DownloadMonitor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@

import { Component, Vue } from 'vue-property-decorator';
import { Hero } from '../components/all';
import DownloadModModal from '../components/views/DownloadModModal.vue';
import Progress from '../components/Progress.vue';
import Timeout = NodeJS.Timeout;

Expand All @@ -59,9 +58,9 @@ export default class DownloadMonitor extends Vue {
private activeDownloads: [number, any][] = [];

created() {
this.activeDownloads = [...DownloadModModal.allVersions].reverse();
this.activeDownloads = [...this.$store.state.download.allVersions].reverse();
this.refreshInterval = setInterval(() => {
this.activeDownloads = [...DownloadModModal.allVersions].reverse();
this.activeDownloads = [...this.$store.state.download.allVersions].reverse();
}, 100);
}

Expand Down
2 changes: 1 addition & 1 deletion src/pages/Manager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ import ModalCard from '../components/ModalCard.vue';
});
return;
}
DownloadModModal.downloadSpecific(this.profile, combo, ignoreCache)
DownloadModModal.downloadSpecific(this.profile, combo, ignoreCache, this.$store)
.then(async value => {
const modList = await ProfileModList.getModList(this.profile.asImmutableProfile());
if (!(modList instanceof R2Error)) {
Expand Down
2 changes: 2 additions & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Vue from 'vue';
import Vuex, { ActionContext } from 'vuex';

import ErrorModule from './modules/ErrorModule';
import { DownloadModule } from './modules/DownloadModule';
import ModalsModule from './modules/ModalsModule';
import ModFilterModule from './modules/ModFilterModule';
import ProfileModule from './modules/ProfileModule';
Expand Down Expand Up @@ -123,6 +124,7 @@ export const store = {
},
modules: {
error: ErrorModule,
download: DownloadModule,
modals: ModalsModule,
modFilters: ModFilterModule,
profile: ProfileModule,
Expand Down
Loading
Loading