From eb092ce0fba054eac6a54ea15a40fe7dbda970e2 Mon Sep 17 00:00:00 2001 From: jliddev Date: Tue, 11 Jan 2022 09:45:15 -0600 Subject: [PATCH] Add the getall route for wago Fix some wago caching issues Fix some async startup issues --- .../addon-providers/wago-addon-provider.ts | 86 +++++++++++++++---- wowup-electron/src/app/app.component.ts | 4 +- wowup-electron/src/app/app.module.ts | 20 ++++- .../install-from-url-dialog.component.ts | 2 +- .../client-selector.component.ts | 4 +- .../common/webview/webview.component.ts | 2 +- .../options-addon-section.component.ts | 8 +- .../options-wow-section.component.ts | 2 +- .../wow-client-options.component.ts | 4 +- .../wtf-explorer/wtf-explorer.component.ts | 2 +- .../pages/get-addons/get-addons.component.ts | 8 +- .../pages/my-addons/my-addons.component.ts | 18 ++-- .../services/addons/addon.provider.factory.ts | 54 ++++++------ .../src/app/services/addons/addon.service.ts | 2 +- .../app/services/session/session.service.ts | 18 ++-- .../warcraft/warcraft-installation.service.ts | 4 +- 16 files changed, 155 insertions(+), 83 deletions(-) diff --git a/wowup-electron/src/app/addon-providers/wago-addon-provider.ts b/wowup-electron/src/app/addon-providers/wago-addon-provider.ts index f4447c7c..82624fe3 100644 --- a/wowup-electron/src/app/addon-providers/wago-addon-provider.ts +++ b/wowup-electron/src/app/addon-providers/wago-addon-provider.ts @@ -23,6 +23,7 @@ import { getGameVersion } from "../utils/addon.utils"; import { getEnumName } from "../utils/enum.utils"; import { convertMarkdown } from "../utils/markdown.utlils"; import { AddonProvider, GetAllResult } from "./addon-provider"; +import { SourceRemovedAddonError } from "../errors"; declare type WagoGameVersion = "retail" | "classic" | "bc"; declare type WagoStability = "stable" | "beta" | "alpha"; @@ -139,6 +140,15 @@ interface WagoPopularAddonsResponse { data: WagoSearchResponseItem[]; } +interface WagoRecentsRequest { + game_version: WagoGameVersion; + addons: string[]; +} + +interface WagoRecentsResponse { + addons: { [addonId: string]: WagoScanAddon }; +} + const WAGO_BASE_URL = "https://addons.wago.io/api/external"; const WAGO_AD_URL = "https://addons.wago.io/wowup_ad"; const WAGO_AD_REFERRER = "https://wago.io"; @@ -164,13 +174,14 @@ export class WagoAddonProvider extends AddonProvider { public adRequired = true; public allowEdit = true; public allowReinstall = true; + public allowChannelChange = true; public constructor( private _electronService: ElectronService, private _cachingService: CachingService, - private _networkService: NetworkService, private _warcraftService: WarcraftService, - private _tocService: TocService + private _tocService: TocService, + _networkService: NetworkService ) { super(); @@ -193,10 +204,7 @@ export class WagoAddonProvider extends AddonProvider { addonFolders: AddonFolder[] ): Promise { const gameVersion = this.getGameVersion(installation.clientType); - - console.time("WagoScan"); const scanResults = await this.getScanResults(addonFolders); - console.timeEnd("WagoScan"); const request: WagoFingerprintRequest = { game_version: gameVersion, @@ -222,7 +230,7 @@ export class WagoAddonProvider extends AddonProvider { console.debug(`[wago] scan`, request); console.debug(JSON.stringify(request)); - const matchResult = await this.sendMatchesRequest(request); + const matchResult = await this.sendMatchesRequest(installation, request); console.debug(`[wago] matchResult`, matchResult); const scanResultMap: { [folder: string]: WagoScanAddon } = {}; @@ -278,7 +286,7 @@ export class WagoAddonProvider extends AddonProvider { url.searchParams.set("game_version", this.getGameVersion(installation.clientType)); const response = await this._cachingService.transaction( - url.toString(), + `${installation.id}|${url.toString()}`, () => this._circuitBreaker.getJson(url, this.getRequestHeaders()), WAGO_FEATURED_ADDONS_CACHE_TIME_SEC ); @@ -307,7 +315,7 @@ export class WagoAddonProvider extends AddonProvider { url.searchParams.set("stability", this.getStability(channelType)); const response = await this._cachingService.transaction( - url.toString(), + `${installation.id}|${query}|${url.toString()}`, () => this._circuitBreaker.getJson(url, this.getRequestHeaders()), WAGO_SEARCH_CACHE_TIME_SEC ); @@ -371,14 +379,36 @@ export class WagoAddonProvider extends AddonProvider { } // used when checking for new addon updates - public async getAll(): Promise { + public async getAll(installation: WowInstallation, addonIds: string[]): Promise { await this.ensureToken().toPromise(); - console.debug(`[wago] getAll`); + const url = new URL(`${WAGO_BASE_URL}/addons/_recents`).toString(); + const request: WagoRecentsRequest = { + game_version: this.getGameVersion(installation.clientType), + addons: [...addonIds], + }; + + const response = await this._cachingService.transaction( + `${installation.id}|${url.toString()}`, + () => this._circuitBreaker.postJson(url, request, this.getRequestHeaders()), + WAGO_DETAILS_CACHE_TIME_SEC + ); + + const searchResults: AddonSearchResult[] = []; + for (const [addonId, addon] of Object.entries(response.addons)) { + searchResults.push(this.toSearchResultFromScan(addon)); + } + + const missingAddonIds = _.filter( + addonIds, + (addonId) => _.find(searchResults, (sr) => sr.externalId === addonId) === undefined + ); + + const deletedErrors = _.map(missingAddonIds, (addonId) => new SourceRemovedAddonError(addonId, undefined)); return Promise.resolve({ - errors: [], - searchResults: [], + errors: [...deletedErrors], + searchResults, }); } @@ -412,15 +442,39 @@ export class WagoAddonProvider extends AddonProvider { return await prom; } - private async sendMatchesRequest(request: WagoFingerprintRequest) { + private async sendMatchesRequest(installation: WowInstallation, request: WagoFingerprintRequest) { const url = new URL(`${WAGO_BASE_URL}/addons/_match`); return await this._cachingService.transaction( - url.toString(), + `${installation.id}|${url.toString()}`, () => this._circuitBreaker.postJson(url, request, this.getRequestHeaders()), WAGO_DETAILS_CACHE_TIME_SEC ); } + private toSearchResultFromScan(item: WagoScanAddon): AddonSearchResult { + const releaseObj = item.recent_releases; + const releaseTypes = Object.keys(releaseObj); + const searchResultFiles: AddonSearchResultFile[] = []; + for (const type of releaseTypes) { + if (releaseObj[type] !== null) { + searchResultFiles.push(this.toSearchResultFileFromDetails(releaseObj[type], type as WagoStability)); + } + } + + return { + author: item.authors.join(", "), + externalId: item.id, + externalUrl: item.website_url, + name: item.name, + providerName: this.name, + thumbnailUrl: item.thumbnail, + downloadCount: 0, + files: searchResultFiles, + releasedAt: new Date(), + summary: "", + }; + } + private toSearchResultFromDetails(item: WagoAddon): AddonSearchResult { const releaseObj = item.recent_releases ?? item.recent_release; const releaseTypes = Object.keys(releaseObj); @@ -502,7 +556,6 @@ export class WagoAddonProvider extends AddonProvider { const authors = wagoScanAddon?.authors?.join(", ") ?? ""; const name = wagoScanAddon?.name ?? ""; - const downloadUrl = wagoScanAddon?.matched_release?.link ?? wagoScanAddon.matched_release.link ?? ""; const externalUrl = wagoScanAddon?.website_url ?? ""; const externalId = wagoScanAddon?.id ?? ""; const gameVersion = getGameVersion(wagoScanAddon?.matched_release?.patch); @@ -529,6 +582,7 @@ export class WagoAddonProvider extends AddonProvider { const latestVersion = validVersion.label; const externalLatestReleaseId = validVersion.id; const externalChannel = getEnumName(AddonChannelType, validVersion.addonChannelType); + const downloadUrl = validVersion.link ?? ""; return { id: uuidv4(), @@ -562,7 +616,7 @@ export class WagoAddonProvider extends AddonProvider { /** Convert a stability map of addons into a sorted list of addons */ private getSortedReleaseList(wagoScanAddon: WagoScanAddon): WagoScanReleaseSortable[] { let releaseList: WagoScanReleaseSortable[] = []; - for (let [key, value] of Object.entries(wagoScanAddon.recent_releases)) { + for (const [key, value] of Object.entries(wagoScanAddon.recent_releases)) { releaseList.push({ ...value, stability: key, addonChannelType: this.getAddonChannelType(key as WagoStability) }); } diff --git a/wowup-electron/src/app/app.component.ts b/wowup-electron/src/app/app.component.ts index d6c281b6..9da715c5 100644 --- a/wowup-electron/src/app/app.component.ts +++ b/wowup-electron/src/app/app.component.ts @@ -272,8 +272,10 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit { dialogRef .afterClosed() .pipe( + switchMap((result: ConsentDialogResult) => + from(this._addonProviderService.setProviderEnabled("Wago", result.wagoProvider)).pipe(map(() => result)) + ), switchMap((result: ConsentDialogResult) => { - this._addonProviderService.setProviderEnabled("Wago", result.wagoProvider); this._addonProviderService.updateWagoConsent(); this._analyticsService.telemetryEnabled = result.telemetry; diff --git a/wowup-electron/src/app/app.module.ts b/wowup-electron/src/app/app.module.ts index 01594017..93f9d541 100644 --- a/wowup-electron/src/app/app.module.ts +++ b/wowup-electron/src/app/app.module.ts @@ -30,15 +30,24 @@ import { HorizontalTabsComponent } from "./components/common/horizontal-tabs/hor import { CommonUiModule } from "./modules/common-ui.module"; import { FooterComponent } from "./components/common/footer/footer.component"; import { VerticalTabsComponent } from "./components/common/vertical-tabs/vertical-tabs.component"; +import { AddonProviderFactory } from "./services/addons/addon.provider.factory"; // AoT requires an exported function for factories export function httpLoaderFactory(http: HttpClient): TranslateHttpLoader { return new TranslateHttpLoader(http, "./assets/i18n/", ".json"); } -export function initializeApp(wowupService: WowUpService) { +export function initializeApp( + wowupService: WowUpService, + wowUpApiService: WowUpApiService, + addonService: AddonService, + warcraftInstallationService: WarcraftInstallationService, + iconService: IconService, + addonProviderFactory: AddonProviderFactory +) { return async (): Promise => { await wowupService.initializeLanguage(); + await addonProviderFactory.loadProviders(); }; } @@ -71,7 +80,14 @@ export function initializeApp(wowupService: WowUpService) { { provide: APP_INITIALIZER, useFactory: initializeApp, - deps: [WowUpService, WowUpApiService, AddonService, WarcraftInstallationService, IconService], + deps: [ + WowUpService, + WowUpApiService, + AddonService, + WarcraftInstallationService, + IconService, + AddonProviderFactory, + ], multi: true, }, { diff --git a/wowup-electron/src/app/components/addons/install-from-url-dialog/install-from-url-dialog.component.ts b/wowup-electron/src/app/components/addons/install-from-url-dialog/install-from-url-dialog.component.ts index 25773490..59321607 100644 --- a/wowup-electron/src/app/components/addons/install-from-url-dialog/install-from-url-dialog.component.ts +++ b/wowup-electron/src/app/components/addons/install-from-url-dialog/install-from-url-dialog.component.ts @@ -137,7 +137,7 @@ export class InstallFromUrlDialogComponent implements OnDestroy { this.hasThumbnail = !!this.addon.thumbnailUrl; this.thumbnailLetter = this.addon.name.charAt(0).toUpperCase(); - const addonInstalled = this._addonService.isInstalled( + const addonInstalled = await this._addonService.isInstalled( this.addon.externalId, this.addon.providerName, selectedInstallation diff --git a/wowup-electron/src/app/components/common/client-selector/client-selector.component.ts b/wowup-electron/src/app/components/common/client-selector/client-selector.component.ts index a3d2f42b..0a3bbf4d 100644 --- a/wowup-electron/src/app/components/common/client-selector/client-selector.component.ts +++ b/wowup-electron/src/app/components/common/client-selector/client-selector.component.ts @@ -39,9 +39,9 @@ export class ClientSelectorComponent implements OnInit { public ngOnInit(): void {} - public onClientChange(evt: any): void { + public async onClientChange(evt: any): Promise { const val: string = evt.value.toString(); - this._sessionService.setSelectedWowInstallation(val); + await this._sessionService.setSelectedWowInstallation(val); } private async mapInstallations(installations: WowInstallation[]): Promise { diff --git a/wowup-electron/src/app/components/common/webview/webview.component.ts b/wowup-electron/src/app/components/common/webview/webview.component.ts index 03913fd6..f0d33784 100644 --- a/wowup-electron/src/app/components/common/webview/webview.component.ts +++ b/wowup-electron/src/app/components/common/webview/webview.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, Input, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core"; +import { AfterViewInit, Component, ElementRef, Input, NgZone, OnDestroy, ViewChild } from "@angular/core"; import { nanoid } from "nanoid"; import { Subject, takeUntil } from "rxjs"; import { AdPageOptions } from "../../../../common/wowup/models"; diff --git a/wowup-electron/src/app/components/options/options-addon-section/options-addon-section.component.ts b/wowup-electron/src/app/components/options/options-addon-section/options-addon-section.component.ts index baa61289..f3ba8752 100644 --- a/wowup-electron/src/app/components/options/options-addon-section/options-addon-section.component.ts +++ b/wowup-electron/src/app/components/options/options-addon-section/options-addon-section.component.ts @@ -27,11 +27,11 @@ export class OptionsAddonSectionComponent implements OnInit { this.loadProviderStates(); } - public onProviderStateSelectionChange(event: MatSelectionListChange): void { - event.options.forEach((option) => { + public async onProviderStateSelectionChange(event: MatSelectionListChange): Promise { + for (const option of event.options) { const providerName: AddonProviderType = option.value; - this._addonProviderService.setProviderEnabled(providerName, option.selected); - }); + await this._addonProviderService.setProviderEnabled(providerName, option.selected); + } } private loadProviderStates() { diff --git a/wowup-electron/src/app/components/options/options-wow-section/options-wow-section.component.ts b/wowup-electron/src/app/components/options/options-wow-section/options-wow-section.component.ts index c2c8a744..b48613a9 100644 --- a/wowup-electron/src/app/components/options/options-wow-section/options-wow-section.component.ts +++ b/wowup-electron/src/app/components/options/options-wow-section/options-wow-section.component.ts @@ -72,7 +72,7 @@ export class OptionsWowSectionComponent implements OnInit { const wowInstallation = await this._warcraftInstallationService.createWowInstallationForPath(selectedPath); console.log("wowInstallation", wowInstallation); - this._warcraftInstallationService.addInstallation(wowInstallation); + await this._warcraftInstallationService.addInstallation(wowInstallation); } private showInvalidWowApplication(selectedPath: string) { diff --git a/wowup-electron/src/app/components/options/wow-client-options/wow-client-options.component.ts b/wowup-electron/src/app/components/options/wow-client-options/wow-client-options.component.ts index 510d5a41..92aa9b4f 100644 --- a/wowup-electron/src/app/components/options/wow-client-options/wow-client-options.component.ts +++ b/wowup-electron/src/app/components/options/wow-client-options/wow-client-options.component.ts @@ -178,7 +178,7 @@ export class WowClientOptionsComponent implements OnInit, OnDestroy { this._editModeSrc.next(false); } - public onClickSave(): void { + public async onClickSave(): Promise { if (!this.installationModel) { return; } @@ -189,7 +189,7 @@ export class WowClientOptionsComponent implements OnInit, OnDestroy { this.installation = { ...this.installationModel }; if (this.installation) { - this._warcraftInstallationService.updateWowInstallation(this.installation); + await this._warcraftInstallationService.updateWowInstallation(this.installation); } // if (saveAutoUpdate) { diff --git a/wowup-electron/src/app/components/options/wtf-explorer/wtf-explorer.component.ts b/wowup-electron/src/app/components/options/wtf-explorer/wtf-explorer.component.ts index b0ce098c..ae23f0c5 100644 --- a/wowup-electron/src/app/components/options/wtf-explorer/wtf-explorer.component.ts +++ b/wowup-electron/src/app/components/options/wtf-explorer/wtf-explorer.component.ts @@ -1,6 +1,6 @@ import * as _ from "lodash"; import { BehaviorSubject, from } from "rxjs"; -import { first, map, switchMap } from "rxjs/operators"; +import { first, switchMap } from "rxjs/operators"; import { Component, Input, OnDestroy, OnInit } from "@angular/core"; diff --git a/wowup-electron/src/app/pages/get-addons/get-addons.component.ts b/wowup-electron/src/app/pages/get-addons/get-addons.component.ts index ff3c5dc8..692ddf44 100644 --- a/wowup-electron/src/app/pages/get-addons/get-addons.component.ts +++ b/wowup-electron/src/app/pages/get-addons/get-addons.component.ts @@ -8,10 +8,10 @@ import { RowNode, } from "ag-grid-community"; import * as _ from "lodash"; -import { BehaviorSubject, combineLatest, from, Observable, of, Subject, Subscription } from "rxjs"; +import { BehaviorSubject, combineLatest, from, Observable, of, Subscription } from "rxjs"; import { catchError, filter, first, map, switchMap } from "rxjs/operators"; -import { ChangeDetectorRef, Component, Input, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core"; +import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit, ViewChild } from "@angular/core"; import { MatCheckboxChange } from "@angular/material/checkbox"; import { MatDialog } from "@angular/material/dialog"; import { MatMenuTrigger } from "@angular/material/menu"; @@ -487,8 +487,8 @@ export class GetAddonsComponent implements OnInit, OnDestroy { }); } - public onClientChange(): void { - this._sessionService.setSelectedWowInstallation(this.selectedInstallationId); + public async onClientChange(): Promise { + await this._sessionService.setSelectedWowInstallation(this.selectedInstallationId); } public onRefresh(): void { diff --git a/wowup-electron/src/app/pages/my-addons/my-addons.component.ts b/wowup-electron/src/app/pages/my-addons/my-addons.component.ts index 16508d18..036520f8 100644 --- a/wowup-electron/src/app/pages/my-addons/my-addons.component.ts +++ b/wowup-electron/src/app/pages/my-addons/my-addons.component.ts @@ -402,7 +402,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit { defaultState: { sort: null }, }); - this.loadSortOrder(); + this.loadSortOrder().catch((e) => console.error(e)); this.rowData$ .pipe( @@ -729,9 +729,9 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit { .subscribe(); } - public onClientChange(evt: any): void { + public async onClientChange(evt: any): Promise { const val: string = evt.value.toString(); - this._sessionService.setSelectedWowInstallation(val); + await this._sessionService.setSelectedWowInstallation(val); } public onRemoveAddon(addon: Addon): void { @@ -784,8 +784,8 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit { .subscribe(); } - public onClickIgnoreAddon(listItem: AddonViewModel): void { - this.onClickIgnoreAddons([listItem]); + public async onClickIgnoreAddon(listItem: AddonViewModel): Promise { + await this.onClickIgnoreAddons([listItem]); } public async onClickIgnoreAddons(listItems: AddonViewModel[]): Promise { @@ -815,12 +815,12 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit { } } - public onClickAutoUpdateAddon(listItem: AddonViewModel): void { - this.onClickAutoUpdateAddons([listItem]); + public async onClickAutoUpdateAddon(listItem: AddonViewModel): Promise { + await this.onClickAutoUpdateAddons([listItem]); } - public onClickAutoUpdateAddonNotifications(listItem: AddonViewModel): void { - this.onClickAutoUpdateAddonsNotifications([listItem]); + public async onClickAutoUpdateAddonNotifications(listItem: AddonViewModel): Promise { + await this.onClickAutoUpdateAddonsNotifications([listItem]); } public onRowClicked(event: RowClickedEvent): void { diff --git a/wowup-electron/src/app/services/addons/addon.provider.factory.ts b/wowup-electron/src/app/services/addons/addon.provider.factory.ts index a804936f..b38fc659 100644 --- a/wowup-electron/src/app/services/addons/addon.provider.factory.ts +++ b/wowup-electron/src/app/services/addons/addon.provider.factory.ts @@ -44,8 +44,29 @@ export class AddonProviderFactory { private _warcraftService: WarcraftService, private _wowupApiService: WowUpApiService, private _preferenceStorageService: PreferenceStorageService - ) { - this.loadProviders(); + ) {} + + /** This is part of the APP_INITIALIZER and called before the app is bootstrapped */ + public async loadProviders(): Promise { + if (this._providerMap.size !== 0) { + return; + } + const providers = [ + this.createZipAddonProvider(), + this.createRaiderIoAddonProvider(), + this.createWowUpCompanionAddonProvider(), + this.createWowUpAddonProvider(), + this.createWagoAddonProvider(), + this.createCurseAddonProvider(), + this.createTukUiAddonProvider(), + this.createWowInterfaceAddonProvider(), + this.createGitHubAddonProvider(), + ]; + + for (const provider of providers) { + await this.setProviderState(provider); + this._providerMap.set(provider.name, provider); + } } public shouldShowConsentDialog(): boolean { @@ -56,7 +77,7 @@ export class AddonProviderFactory { return this._preferenceStorageService.set(WAGO_PROMPT_KEY, true); } - public setProviderEnabled(type: AddonProviderType, enabled: boolean) { + public async setProviderEnabled(type: AddonProviderType, enabled: boolean): Promise { if (!this._providerMap.has(type)) { throw new Error("cannot set provider state, not found"); } @@ -66,7 +87,7 @@ export class AddonProviderFactory { throw new Error(`this provider is not editable: ${type}`); } - this._wowupService.setAddonProviderState({ + await this._wowupService.setAddonProviderState({ providerName: type, enabled: enabled, canEdit: true, @@ -80,9 +101,9 @@ export class AddonProviderFactory { return new WagoAddonProvider( this._electronService, this._cachingService, - this._networkService, this._warcraftService, - this._tocService + this._tocService, + this._networkService ); } @@ -239,27 +260,6 @@ export class AddonProviderFactory { return providerName !== ADDON_PROVIDER_UNKNOWN && (provider?.allowChannelChange ?? false); } - private loadProviders() { - if (this._providerMap.size === 0) { - const providers = [ - this.createZipAddonProvider(), - this.createRaiderIoAddonProvider(), - this.createWowUpCompanionAddonProvider(), - this.createWowUpAddonProvider(), - this.createWagoAddonProvider(), - this.createCurseAddonProvider(), - this.createTukUiAddonProvider(), - this.createWowInterfaceAddonProvider(), - this.createGitHubAddonProvider(), - ]; - - providers.forEach((provider) => { - this.setProviderState(provider); - this._providerMap.set(provider.name, provider); - }); - } - } - private setProviderState = async (provider: AddonProvider): Promise => { const state = await this._wowupService.getAddonProviderState(provider.name); if (state) { diff --git a/wowup-electron/src/app/services/addons/addon.service.ts b/wowup-electron/src/app/services/addons/addon.service.ts index 1df399c7..f3fd7c04 100644 --- a/wowup-electron/src/app/services/addons/addon.service.ts +++ b/wowup-electron/src/app/services/addons/addon.service.ts @@ -1210,7 +1210,7 @@ export class AddonService { } const getAllResult = await addonProvider.getAll(installation, providerAddonIds); - this.handleSyncErrors(installation, getAllResult.errors, addonProvider, addons); + await this.handleSyncErrors(installation, getAllResult.errors, addonProvider, addons); await this.handleSyncResults(getAllResult.searchResults, addons, installation); } diff --git a/wowup-electron/src/app/services/session/session.service.ts b/wowup-electron/src/app/services/session/session.service.ts index 352b3d49..9fcfc357 100644 --- a/wowup-electron/src/app/services/session/session.service.ts +++ b/wowup-electron/src/app/services/session/session.service.ts @@ -1,5 +1,5 @@ import * as _ from "lodash"; -import { BehaviorSubject, Subject } from "rxjs"; +import { BehaviorSubject, from, Subject } from "rxjs"; import { Injectable } from "@angular/core"; @@ -8,7 +8,7 @@ import { WowInstallation } from "../../../common/warcraft/wow-installation"; import { PreferenceStorageService } from "../storage/preference-storage.service"; import { WarcraftInstallationService } from "../warcraft/warcraft-installation.service"; import { ColumnState } from "../../models/wowup/column-state"; -import { map } from "rxjs/operators"; +import { map, switchMap } from "rxjs/operators"; import { WowUpAccountService } from "../wowup/wowup-account.service"; import { AddonService } from "../addons/addon.service"; import { AddonProviderFactory } from "../addons/addon.provider.factory"; @@ -70,9 +70,9 @@ export class SessionService { }) .catch((e) => console.error(e)); - this._warcraftInstallationService.wowInstallations$.subscribe((installations) => - this.onWowInstallationsChange(installations) - ); + this._warcraftInstallationService.wowInstallations$ + .pipe(switchMap((installations) => from(this.onWowInstallationsChange(installations)))) + .subscribe(); this._addonProviderService.addonProviderChange$.subscribe(() => { this.updateAdSpace(); @@ -128,7 +128,7 @@ export class SessionService { this._preferenceStorageService.set(SELECTED_DETAILS_TAB_KEY, tabType); } - public onWowInstallationsChange(wowInstallations: WowInstallation[]): void { + public async onWowInstallationsChange(wowInstallations: WowInstallation[]): Promise { if (wowInstallations.length === 0) { this._selectedHomeTabSrc.next(TAB_INDEX_SETTINGS); return; @@ -138,7 +138,7 @@ export class SessionService { if (!selectedInstall) { selectedInstall = _.first(wowInstallations); if (selectedInstall) { - this.setSelectedWowInstallation(selectedInstall.id); + await this.setSelectedWowInstallation(selectedInstall.id); } } @@ -172,7 +172,7 @@ export class SessionService { this._selectedHomeTabSrc.next(tabIndex); } - public setSelectedWowInstallation(installationId: string): void { + public async setSelectedWowInstallation(installationId: string): Promise { if (!installationId) { return; } @@ -182,7 +182,7 @@ export class SessionService { return; } - this._warcraftInstallationService.setSelectedWowInstallation(installation); + await this._warcraftInstallationService.setSelectedWowInstallation(installation); this._selectedWowInstallationSrc.next(installation); } diff --git a/wowup-electron/src/app/services/warcraft/warcraft-installation.service.ts b/wowup-electron/src/app/services/warcraft/warcraft-installation.service.ts index 4e7a04ab..c7ba923b 100644 --- a/wowup-electron/src/app/services/warcraft/warcraft-installation.service.ts +++ b/wowup-electron/src/app/services/warcraft/warcraft-installation.service.ts @@ -248,7 +248,7 @@ export class WarcraftInstallationService { }; try { - this.addInstallation(wowInstallation, false); + await this.addInstallation(wowInstallation, false); } catch (e) { // Ignore duplicate error } @@ -338,7 +338,7 @@ export class WarcraftInstallationService { selected: false, }; - this.addInstallation(installation, false); + await this.addInstallation(installation, false); return installation; }