diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index a4eb81c7..4d780966 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -150,7 +150,7 @@ } }, "available-versions": { - "title": "Wähle eine Version", + "title": "Eine Version herunterladen", "steam-release": "Versionsseite", "dropdown": { "refresh": "Aktualisiere die Versionen", diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index 7919ac1c..7356483f 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -150,7 +150,7 @@ } }, "available-versions": { - "title": "Select a version", + "title": "Download a version", "steam-release": "Release page", "dropdown": { "refresh": "Refresh versions", diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index 04eb4532..2790779d 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -150,7 +150,7 @@ } }, "available-versions": { - "title": "Selecciona una versión", + "title": "Descargar una versión", "steam-release": "Anuncio en Steam", "dropdown": { "refresh": "Actualizar las versiones", diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 38d7f6dc..dd98d791 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -150,7 +150,7 @@ } }, "available-versions": { - "title": "Choisis une version", + "title": "Télécharger une version", "steam-release": "Notes de version", "dropdown": { "refresh": "Actualiser les versions", diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index dbe7e9c6..bf786039 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -150,7 +150,7 @@ } }, "available-versions": { - "title": "バージョンを選択", + "title": "バージョンをダウンロード", "steam-release": "リリースページ", "dropdown": { "refresh": "バージョンの更新", diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index 7378fe8c..518d8758 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -150,7 +150,7 @@ } }, "available-versions": { - "title": "Выберите версию", + "title": "Скачать версию", "steam-release": "Список изменений", "dropdown": { "refresh": "Обновить версии", diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index ecab4dd4..72bc3c5d 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -150,7 +150,7 @@ } }, "available-versions": { - "title": "選擇版本", + "title": "下載一個版本", "steam-release": "發布頁面", "dropdown": { "refresh": "刷新版本", diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index 7394b8db..06e1e3d5 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -150,7 +150,7 @@ } }, "available-versions": { - "title": "选择版本", + "title": "下载一个版本", "steam-release": "发布页面", "dropdown": { "refresh": "刷新版本", diff --git a/src/main/ipcs/static-configuration.ipcs.ts b/src/main/ipcs/static-configuration.ipcs.ts index d3dc7b93..43767db8 100644 --- a/src/main/ipcs/static-configuration.ipcs.ts +++ b/src/main/ipcs/static-configuration.ipcs.ts @@ -12,3 +12,7 @@ ipc.on("static-configuration.get", (args, reply) => { ipc.on("static-configuration.set", (args, reply) => { reply(from(staticConfig.set(args.key, args.value))); }); + +ipc.on("static-configuration.delete", (key, reply) => { + reply(of(staticConfig.delete(key))); +}); diff --git a/src/main/services/bs-launcher/bs-launcher.service.ts b/src/main/services/bs-launcher/bs-launcher.service.ts index 96011b9b..94692ccd 100644 --- a/src/main/services/bs-launcher/bs-launcher.service.ts +++ b/src/main/services/bs-launcher/bs-launcher.service.ts @@ -21,6 +21,7 @@ import { OculusLauncherService } from "./oculus-launcher.service"; import { BSVersion } from "shared/bs-version.interface"; import { BsStore } from "../../../shared/models/bs-store.enum"; import { LaunchMod, LaunchMods } from "shared/models/bs-launch/launch-option.interface"; +import { StaticConfigurationService } from "../static-configuration.service"; export class BSLauncherService { private static instance: BSLauncherService; @@ -32,6 +33,7 @@ export class BSLauncherService { private readonly remoteVersion: BSVersionLibService; private readonly steamLauncher: SteamLauncherService; private readonly oculusLauncher: OculusLauncherService; + private readonly staticConfig: StaticConfigurationService; public static getInstance(): BSLauncherService { if (!BSLauncherService.instance) { @@ -48,6 +50,7 @@ export class BSLauncherService { this.remoteVersion = BSVersionLibService.getInstance(); this.steamLauncher = SteamLauncherService.getInstance(); this.oculusLauncher = OculusLauncherService.getInstance(); + this.staticConfig = StaticConfigurationService.getInstance(); this.bsmProtocolService.on("launch", link => { log.info("Launch from bsm protocol", link.toString()); @@ -73,6 +76,8 @@ export class BSLauncherService { return throwError(() => new Error("Unable to get launcher for the provided version")); } + this.staticConfig.set("last-version-launched", launchOptions.version); + return launcher.launch(launchOptions); } diff --git a/src/main/services/bs-local-version.service.ts b/src/main/services/bs-local-version.service.ts index dcdd4e15..a224015c 100644 --- a/src/main/services/bs-local-version.service.ts +++ b/src/main/services/bs-local-version.service.ts @@ -18,6 +18,7 @@ import { Observable, Subject, catchError, finalize, from, map, switchMap, throwE import { BsStore } from "../../shared/models/bs-store.enum"; import { CustomError } from "../../shared/models/exceptions/custom-error.class"; import crypto from "crypto"; +import { StaticConfigurationService } from "./static-configuration.service"; export class BSLocalVersionService { @@ -32,6 +33,7 @@ export class BSLocalVersionService { private readonly remoteVersionService: BSVersionLibService; private readonly configService: ConfigurationService; private readonly linker: FolderLinkerService; + private readonly staticConfig: StaticConfigurationService; private readonly _loadedVersions$: Subject; public static getInstance(): BSLocalVersionService { @@ -48,6 +50,7 @@ export class BSLocalVersionService { this.remoteVersionService = BSVersionLibService.getInstance(); this.configService = ConfigurationService.getInstance(); this.linker = FolderLinkerService.getInstance(); + this.staticConfig = StaticConfigurationService.getInstance(); this._loadedVersions$ = new Subject(); } @@ -171,6 +174,24 @@ export class BSLocalVersionService { this.setCustomVersions([...this.getCustomVersions() ?? [], version]); } + private updateLastVersionLaunched(version: BSVersion, editedVersion: BSVersion): void { + const lastVersion = this.staticConfig.get("last-version-launched"); + if (!lastVersion) { + return; + } + + if ( + version.BSVersion !== lastVersion.BSVersion + || version.name !== lastVersion.name + || version.steam !== lastVersion.steam + || version.oculus !== lastVersion.oculus + ) { + return; + } + + this.staticConfig.set("last-version-launched", editedVersion); + } + private getCustomVersions(): BSVersion[]{ return this.configService.get(this.CUSTOM_VERSIONS_KEY) || []; } @@ -317,6 +338,7 @@ export class BSLocalVersionService { if(oldPath === newPath){ this.deleteCustomVersion(version); this.addCustomVersion(editedVersion); + this.updateLastVersionLaunched(version, editedVersion); return editedVersion; } @@ -327,6 +349,7 @@ export class BSLocalVersionService { return rename(oldPath, newPath).then(() => { this.deleteCustomVersion(version); this.addCustomVersion(editedVersion); + this.updateLastVersionLaunched(version, editedVersion); return editedVersion; }).catch((err: Error) => { log.error("edit version error", err, version, name, color); diff --git a/src/main/services/static-configuration.service.ts b/src/main/services/static-configuration.service.ts index 0a90c607..47e99245 100644 --- a/src/main/services/static-configuration.service.ts +++ b/src/main/services/static-configuration.service.ts @@ -89,6 +89,7 @@ export interface StaticConfigKeyValues { "disable-hadware-acceleration": boolean; "use-symlinks": boolean; "use-system-proxy": boolean; + "last-version-launched": BSVersion; // Linux Specific static configs "proton-folder": string; diff --git a/src/renderer/services/bs-version-manager.service.ts b/src/renderer/services/bs-version-manager.service.ts index 696e7d85..6d92ffa0 100644 --- a/src/renderer/services/bs-version-manager.service.ts +++ b/src/renderer/services/bs-version-manager.service.ts @@ -1,5 +1,5 @@ import { BSVersion } from "shared/bs-version.interface"; -import { BehaviorSubject, Observable, Subscription, lastValueFrom, shareReplay, throwError } from "rxjs"; +import { BehaviorSubject, Observable, Subscription, lastValueFrom, map, share, shareReplay, throwError } from "rxjs"; import { IpcService } from "./ipc.service"; import { ModalExitCode, ModalService } from "./modale.service"; import { NotificationService } from "./notification.service"; @@ -19,6 +19,7 @@ export class BSVersionManagerService { private readonly progressBar: ProgressBarService; private readonly modals: ModalService; + private askInstalledVersionsObserver$: Observable | null = null; public readonly installedVersions$: BehaviorSubject = new BehaviorSubject([]); public readonly availableVersions$: BehaviorSubject = new BehaviorSubject([]); @@ -28,7 +29,9 @@ export class BSVersionManagerService { this.notification = NotificationService.getInstance(); this.progressBar = ProgressBarService.getInstance(); this.modals = ModalService.getInstance(); - this.askAvailableVersions().then(() => this.askInstalledVersions()); + + this.askAvailableVersions(); + this.askInstalledVersions(); } public static getInstance() { @@ -54,15 +57,47 @@ export class BSVersionManagerService { }); } - public askInstalledVersions(): Promise { - return lastValueFrom(this.ipcService.sendV2("bs-version.installed-versions")).then(res => { - this.setInstalledVersions(res); - return res; - }); + public async askInstalledVersions(): Promise { + if (this.askInstalledVersionsObserver$) { + return lastValueFrom(this.askInstalledVersionsObserver$); + } + + this.askInstalledVersionsObserver$ = this.ipcService + .sendV2("bs-version.installed-versions") + .pipe( + map(versions => { + let processed = BSVersionManagerService.sortVersions(versions); + processed = BSVersionManagerService.removeDuplicateVersions(processed); + return processed; + }), + share(), + ); + + return lastValueFrom(this.askInstalledVersionsObserver$) + .then(versions => { + this.setInstalledVersions(versions); + return versions; + }) + .finally(() => { + this.askInstalledVersionsObserver$ = null; + }); } - public isVersionInstalled(version: BSVersion): boolean { - return !!this.getInstalledVersions().find(v => v.BSVersion === version.BSVersion && v.steam === version.steam && v.oculus === version.oculus); + public async isVersionInstalled(version: BSVersion): Promise { + try { + const versions: BSVersion[] = this.askInstalledVersionsObserver$ + ? await lastValueFrom(this.askInstalledVersionsObserver$) + : this.getInstalledVersions(); + + return !!versions.find(v => + v.BSVersion === version.BSVersion + && v.name === version.name + && v.steam === version.steam + && v.oculus === version.oculus + ); + } catch (error) { + return false; + } } public async editVersion(version: BSVersion): Promise { diff --git a/src/renderer/services/static-configuration.service.ts b/src/renderer/services/static-configuration.service.ts index 69d177a9..5cc93487 100644 --- a/src/renderer/services/static-configuration.service.ts +++ b/src/renderer/services/static-configuration.service.ts @@ -27,4 +27,8 @@ export class StaticConfigurationService { return lastValueFrom(this.ipc.sendV2("static-configuration.set", { key, value })); } + public delete(key: K): Promise { + return lastValueFrom(this.ipc.sendV2("static-configuration.delete", key)); + } + } diff --git a/src/renderer/windows/App.tsx b/src/renderer/windows/App.tsx index 4982b93e..e49e56e7 100644 --- a/src/renderer/windows/App.tsx +++ b/src/renderer/windows/App.tsx @@ -23,6 +23,8 @@ import { ConfigurationService } from "renderer/services/configuration.service"; import { OsDiagnosticService } from "renderer/services/os-diagnostic.service"; import { useService } from "renderer/hooks/use-service.hook"; import { SetupService } from "renderer/services/setup.service"; +import { StaticConfigurationService } from "renderer/services/static-configuration.service"; +import { BSVersionManagerService } from "renderer/services/bs-version-manager.service"; export default function App() { @@ -34,6 +36,8 @@ export default function App() { const notification = useService(NotificationService); const config = useService(ConfigurationService); const setup = useService(SetupService); + const staticConfig = useService(StaticConfigurationService); + const versionManager = useService(BSVersionManagerService); const location = useLocation(); const navigate = useNavigate(); @@ -41,10 +45,25 @@ export default function App() { useEffect(() => { setup.check() .then(() => { + navigateToDefaultPage(); checkOneClicks(); - }) + }); }, []); + const navigateToDefaultPage = async () => { + const version = await staticConfig.get("last-version-launched"); + if (!version) { + return; + } + + if (!await versionManager.isVersionInstalled(version)) { + await staticConfig.delete("last-version-launched"); + return; + } + + navigate(`/bs-version/${version.BSVersion}`, { state: version }); + }; + const checkOneClicks = async () => { if (config.get("not-remind-oneclick") === true) { diff --git a/src/shared/models/ipc/ipc-routes.ts b/src/shared/models/ipc/ipc-routes.ts index 950c2495..ce87b62d 100644 --- a/src/shared/models/ipc/ipc-routes.ts +++ b/src/shared/models/ipc/ipc-routes.ts @@ -156,6 +156,7 @@ export interface IpcChannelMapping { /* ** static-configuration.ipcs ** */ "static-configuration.get": StaticConfigGetIpcRequestResponse; "static-configuration.set": StaticConfigSetIpcRequest; + "static-configuration.delete": { request: StaticConfigKeys; response: void }; /* ** linux.ipcs ** */ "linux.verify-proton-folder": { request: void, response: boolean };