diff --git a/src/migrations/FolderMigration.ts b/src/migrations/FolderMigration.ts index ce9889b92..2fc65c563 100644 --- a/src/migrations/FolderMigration.ts +++ b/src/migrations/FolderMigration.ts @@ -1,25 +1,35 @@ -import PathResolver from '../r2mm/manager/PathResolver'; import * as path from 'path'; import FsProvider from '../providers/generic/file/FsProvider'; +import PathResolver from '../r2mm/manager/PathResolver'; import FileUtils from '../utils/FileUtils'; -import CacheUtil from '../r2mm/mods/CacheUtil'; -export default class FolderMigration { +/** + * Mod directory structure was changed when support for other games + * besides RoR2 was added. Update the dir structure if the old one is + * still in use. + */ +export class FolderMigration { - public static async needsMigration(): Promise { + public static async needsMigration() { const fs = FsProvider.instance; return await fs.exists(path.join(PathResolver.ROOT, "mods")); } - public static async runMigration(): Promise { - console.log("Started migration"); + public static async runMigration() { + if (!await this.needsMigration()) { + return; + } + + console.log("Started legacy directory migration"); const fs = FsProvider.instance; - await CacheUtil.clean(); - if ((await fs.exists(path.join(PathResolver.ROOT, "RiskOfRain2")))) { - await FileUtils.emptyDirectory(path.join(PathResolver.ROOT, "RiskOfRain2")); - await fs.rmdir(path.join(PathResolver.ROOT, "RiskOfRain2")); + const rorPath = path.join(PathResolver.ROOT, "RiskOfRain2"); + + if (await fs.exists(rorPath)) { + await FileUtils.emptyDirectory(rorPath); + await fs.rmdir(rorPath); } - await fs.rename(path.join(PathResolver.ROOT, "mods"), path.join(PathResolver.ROOT, "RiskOfRain2")); - } + await fs.rename(path.join(PathResolver.ROOT, "mods"), rorPath); + console.log("Directory migration done"); + } } diff --git a/src/model/game/GameManager.ts b/src/model/game/GameManager.ts index 07c3f8b37..6f5546722 100644 --- a/src/model/game/GameManager.ts +++ b/src/model/game/GameManager.ts @@ -319,4 +319,10 @@ export default class GameManager { public static unsetGame(): Game { return this._gameList.find(value => value.internalFolderName === "RiskOfRain2")!; } + + public static findByFolderName(name?: string|null) { + return name + ? this._gameList.find((game) => game.internalFolderName === name) + : undefined; + } } diff --git a/src/pages/GameSelectionScreen.vue b/src/pages/GameSelectionScreen.vue index f77a94148..906494a73 100644 --- a/src/pages/GameSelectionScreen.vue +++ b/src/pages/GameSelectionScreen.vue @@ -27,7 +27,7 @@

An update to the manager has occurred and needs to do background work.

-

The option to select a game will appear once the work has completed.

+

The options to select a game are disabled until the work has completed.

@@ -180,10 +180,10 @@ import { Component, Vue } from 'vue-property-decorator'; import Game from '../model/game/Game'; import GameManager from '../model/game/GameManager'; import Hero from '../components/Hero.vue'; -import FolderMigration from '../migrations/FolderMigration'; import PathResolver from '../r2mm/manager/PathResolver'; import * as path from 'path'; import FileUtils from '../utils/FileUtils'; +import * as ManagerUtils from '../utils/ManagerUtils'; import ManagerSettings from '../r2mm/manager/ManagerSettings'; import { StorePlatform } from '../model/game/StorePlatform'; import { GameSelectionDisplayMode } from '../model/game/GameSelectionDisplayMode'; @@ -385,61 +385,25 @@ export default class GameSelectionScreen extends Vue { } } - created() { - const self = this; + async created() { this.runningMigration = true; - FolderMigration.needsMigration() - .then(isMigrationRequired => { - if (!isMigrationRequired) { - this.runningMigration = false; - } else { - return FolderMigration.runMigration(); - } - }) - .then(() => { - this.runningMigration = false; - }) - .catch((e) => { - console.log(e); - this.runningMigration = false; - }) - .finally(() => { - ManagerSettings.getSingleton(GameManager.unsetGame()).then(settings => { - const lastSelectedGame = settings.getContext().global.lastSelectedGame; - const savedViewMode = settings.getContext().global.gameSelectionViewMode; - switch (savedViewMode) { - case "List": this.viewMode = GameSelectionViewMode.LIST; break; - case "Card": - case undefined: - this.viewMode = GameSelectionViewMode.CARD; - break; - } - if (lastSelectedGame !== null) { - const game = GameManager.gameList.find(value => value.internalFolderName === lastSelectedGame); - if (game !== undefined) { - this.selectedGame = game; - } - } - }); - ManagerSettings.getSingleton(GameManager.unsetGame()).then(value => { - this.settings = value; - this.favourites = value.getContext().global.favouriteGames || []; - if (value.getContext().global.defaultGame !== undefined) { - if (value.getContext().global.defaultStore !== undefined) { - const game = GameManager.gameList - .find(value1 => value1.internalFolderName === value.getContext().global.defaultGame)!; - - const platform = game.storePlatformMetadata.find(value1 => value1.storePlatform === value.getContext().global.defaultStore)!; - - this.selectedGame = game; - this.selectedPlatform = platform.storePlatform; - - this.proceed(); - return; - } - } - }); - }) + await this.$store.dispatch('checkMigrations'); + this.runningMigration = false; + + this.settings = await ManagerSettings.getSingleton(GameManager.unsetGame()); + const globalSettings = this.settings.getContext().global; + this.viewMode = globalSettings.gameSelectionViewMode; + this.favourites = globalSettings.favouriteGames ?? []; + this.selectedGame = GameManager.findByFolderName(globalSettings.lastSelectedGame) ?? null; + + // Skip game selection view if valid default game & platform are set. + const {defaultGame, defaultPlatform} = ManagerUtils.getDefaults(this.settings); + + if (defaultGame && defaultPlatform) { + this.selectedGame = defaultGame; + this.selectedPlatform = defaultPlatform; + this.proceed(); + } } toggleViewMode() { diff --git a/src/r2mm/manager/SettingsDexieStore.ts b/src/r2mm/manager/SettingsDexieStore.ts index 860574647..66bab4f2f 100644 --- a/src/r2mm/manager/SettingsDexieStore.ts +++ b/src/r2mm/manager/SettingsDexieStore.ts @@ -206,7 +206,7 @@ export interface ManagerSettingsInterfaceGlobal_V2 { favouriteGames: string[] | undefined; defaultGame: string | undefined; defaultStore: StorePlatform | undefined; - gameSelectionViewMode: string | undefined; + gameSelectionViewMode: GameSelectionViewMode; } /** diff --git a/src/store/index.ts b/src/store/index.ts index 55dcb2481..2a48928e0 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,5 +1,6 @@ import Vue from 'vue'; import Vuex from 'vuex'; +import { FolderMigration } from '../migrations/FolderMigration'; // import example from './module-example' @@ -16,6 +17,7 @@ export default function(/* { ssrContext } */) { localModList: [], thunderstoreModList: [], dismissedUpdateAll: false, + isMigrationChecked: false, apiConnectionError: "" }, actions: { @@ -30,6 +32,19 @@ export default function(/* { ssrContext } */) { }, updateApiConnectionError({commit}, err) { commit('setApiConnectionError', err); + }, + async checkMigrations({commit, state}) { + if (state.isMigrationChecked) { + return; + } + + try { + await FolderMigration.runMigration(); + } catch (e) { + console.error(e); + } finally { + commit('setMigrationChecked'); + } } }, mutations: { @@ -42,6 +57,9 @@ export default function(/* { ssrContext } */) { dismissUpdateAll(state) { state.dismissedUpdateAll = true; }, + setMigrationChecked(state) { + state.isMigrationChecked = true; + }, setApiConnectionError(state, err) { state.apiConnectionError = err; } diff --git a/src/utils/ManagerUtils.ts b/src/utils/ManagerUtils.ts new file mode 100644 index 000000000..cac909a4c --- /dev/null +++ b/src/utils/ManagerUtils.ts @@ -0,0 +1,18 @@ +import GameManager from "../model/game/GameManager"; +import ManagerSettings from "../r2mm/manager/ManagerSettings"; + + +/** + * Return default game selection needed to skip the game selection screen. + */ +export const getDefaults = (settings: ManagerSettings) => { + const globals = settings.getContext().global; + const defaultGame = GameManager.findByFolderName(globals.defaultGame); + const platforms = defaultGame ? defaultGame.storePlatformMetadata : []; + const defaultPlat = platforms.find(x => x.storePlatform === globals.defaultStore); + + return { + defaultGame, + defaultPlatform: defaultPlat ? defaultPlat.storePlatform : undefined + }; +}