Lots more wago support

This commit is contained in:
jliddev
2021-11-23 11:32:21 -06:00
parent ff63ca7b39
commit bcb041cfaf
12 changed files with 341 additions and 56 deletions

View File

@@ -157,6 +157,12 @@ export function setPendingOpenUrl(...openUrls: string[]): void {
export function initializeIpcHandlers(window: BrowserWindow): void {
log.info("process.versions", process.versions);
// Just forward the token event out to the window
// this is not a handler, just a passive listener
ipcMain.on("wago-token-received", (evt, token) => {
window?.webContents?.send("wago-token-received", token);
});
// Remove the pending URLs once read so they are only able to be gotten once
handle(IPC_GET_PENDING_OPEN_URLS, (): string[] => {
const urls = PENDING_OPEN_URLS;
@@ -219,7 +225,7 @@ export function initializeIpcHandlers(window: BrowserWindow): void {
if (!Array.isArray(addons)) {
return;
}
for (const addon of addons) {
addonStore.set(addon.id, addon);
}

View File

@@ -3,7 +3,7 @@ import { WowInstallation } from "../../common/warcraft/wow-installation";
import { Observable, of } from "rxjs";
import { Addon } from "../../common/entities/addon";
import { AddonCategory, AddonChannelType } from "../../common/wowup/models";
import { AddonCategory, AddonChannelType, AdPageOptions } from "../../common/wowup/models";
import { AddonFolder } from "../models/wowup/addon-folder";
import { AddonSearchResult } from "../models/wowup/addon-search-result";
import { ProtocolSearchResult } from "../models/wowup/protocol-search-result";
@@ -44,6 +44,8 @@ export abstract class AddonProvider {
public allowViewAtSource = true;
public canShowChangelog = true;
public canBatchFetch = false;
public authRequired = false;
public adRequired = false;
public getAllBatch(installations: WowInstallation[], addonIds: string[]): Promise<GetAllBatchResult> {
return Promise.resolve({
@@ -119,4 +121,8 @@ export abstract class AddonProvider {
public async getDescription(installation: WowInstallation, externalId: string, addon?: Addon): Promise<string> {
return Promise.resolve("");
}
public getAdPageParams(): AdPageOptions | undefined {
return undefined;
}
}

View File

@@ -6,13 +6,18 @@ import { CachingService } from "../services/caching/caching-service";
import { CircuitBreakerWrapper, NetworkService } from "../services/network/network.service";
import { AddonProvider } from "./addon-provider";
import { WowInstallation } from "../../common/warcraft/wow-installation";
import { AddonChannelType } from "../../common/wowup/models";
import { AddonChannelType, AdPageOptions } from "../../common/wowup/models";
import { AddonFolder } from "../models/wowup/addon-folder";
import { WowClientGroup, WowClientType } from "../../common/warcraft/wow-client-type";
import { AppWowUpScanResult } from "../models/wowup/app-wowup-scan-result";
import { TocService } from "../services/toc/toc.service";
import { AddonSearchResult } from "../models/wowup/addon-search-result";
import { AddonSearchResultFile } from "../models/wowup/addon-search-result-file";
import { Addon } from "../../common/entities/addon";
import { convertBbcode } from "../utils/bbcode.utils";
declare type WagoGameVersion = "retail" | "classic" | "bcc";
declare type WagoStability = "stable" | "beta" | "alpha";
interface WagoFingerprintAddon {
hash: string; // hash fingerprint of the folder
@@ -26,12 +31,76 @@ interface WagoFingerprintRequest {
addons: { [folder: string]: WagoFingerprintAddon };
}
interface WagoSearchResponse {
data: WagoSearchResponseItem[];
}
interface WagoSearchResponseItem {
display_name: string;
id: string;
releases: {
alpha?: WagoSearchResponseRelease;
beta?: WagoSearchResponseRelease;
stable?: WagoSearchResponseRelease;
};
summary: string;
thumbnail_image: string;
}
interface WagoSearchResponseRelease {
download_link: string;
label: string;
created_at: string;
logical_timestamp: number; // download link expiration time
}
interface WagoAddon {
id: string;
slug: string;
display_name: string;
thumbnail_image: string;
summary: string;
description: string;
website: string;
gallery: string[];
recent_releases: {
stable?: WagoRelease;
beta?: WagoRelease;
alpha?: WagoRelease;
};
}
interface WagoRelease {
label: string;
supported_retail_patch: string;
supported_classic_patch: string;
supported_bc_patch: string;
changelog: string;
stability: WagoStability;
download_link: string;
}
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";
const WAGO_AD_USER_AGENT =
"`Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36`"; // the ad requires a normal looking user agent
const WAGO_AD_PRELOAD = "preload/wago.js";
const WAGO_SEARCH_CACHE_TIME_SEC = 20;
const WAGO_DETAILS_CACHE_TIME_SEC = 20;
export class WagoAddonProvider extends AddonProvider {
private readonly _circuitBreaker: CircuitBreakerWrapper;
private _apiToken = "";
private _enabled = true;
public readonly name = ADDON_PROVIDER_WAGO;
public readonly forceIgnore = false;
public enabled = true;
public authRequired = true;
public adRequired = true;
public allowEdit = true;
public constructor(
private _electronService: ElectronService,
@@ -47,6 +116,8 @@ export class WagoAddonProvider extends AddonProvider {
AppConfig.defaultHttpResetTimeoutMs,
AppConfig.wagoHttpTimeoutMs
);
this._electronService.on("wago-token-received", this.onWagoTokenReceived);
}
public async scan(
@@ -84,6 +155,121 @@ export class WagoAddonProvider extends AddonProvider {
console.debug(JSON.stringify(request, null, 2));
}
public async searchByQuery(
query: string,
installation: WowInstallation,
channelType?: AddonChannelType
): Promise<AddonSearchResult[]> {
if (!this._apiToken) {
console.warn("[wago] searchByQuery no api token found");
return [];
}
const url = new URL(`${WAGO_BASE_URL}/addons/_search`);
url.searchParams.set("query", query);
url.searchParams.set("game_version", this.getGameVersion(installation.clientType));
url.searchParams.set("stability", this.getStability(channelType));
const response = await this._cachingService.transaction(
url.toString(),
() => this._circuitBreaker.getJson<WagoSearchResponse>(url, this.getRequestHeaders()),
WAGO_SEARCH_CACHE_TIME_SEC
);
const searchResults = response.data?.map((item) => this.toSearchResult(item)) ?? [];
console.debug(`[wago] searchByQuery`, response, searchResults);
return searchResults;
}
public async getDescription(installation: WowInstallation, externalId: string, addon?: Addon): Promise<string> {
try {
const response = await this.getAddonById(externalId);
return convertBbcode(response?.description ?? "");
} catch (e) {
console.error(`[wago] failed to get description`, e);
return "";
}
}
public getAdPageParams(): AdPageOptions {
return {
pageUrl: WAGO_AD_URL,
referrer: WAGO_AD_REFERRER,
userAgent: WAGO_AD_USER_AGENT,
preloadFilePath: WAGO_AD_PRELOAD,
};
}
private async getAddonById(addonId: string) {
//https://addons.wago.io/api/external/addons/qv63o6bQ?game_version=retail&__debug__=true
const url = new URL(`${WAGO_BASE_URL}/addons/${addonId}`);
return await this._cachingService.transaction(
url.toString(),
() => this._circuitBreaker.getJson<WagoAddon>(url, this.getRequestHeaders()),
WAGO_DETAILS_CACHE_TIME_SEC
);
}
private toSearchResult(item: WagoSearchResponseItem): AddonSearchResult {
const releaseTypes = Object.keys(item.releases);
const searchResultFiles: AddonSearchResultFile[] = [];
for (const type of releaseTypes) {
searchResultFiles.push(this.toSearchResultFile(item.releases[type], type as WagoStability));
}
return {
author: "",
externalId: item.id,
externalUrl: "",
name: item.display_name,
providerName: this.name,
thumbnailUrl: item.thumbnail_image,
downloadCount: 0,
files: searchResultFiles,
releasedAt: new Date(),
summary: item.summary,
};
}
private toSearchResultFile(release: WagoSearchResponseRelease, stability: WagoStability): AddonSearchResultFile {
return {
channelType: this.getAddonChannelType(stability),
downloadUrl: release.download_link,
folders: [],
gameVersion: "",
releaseDate: new Date(release.created_at),
version: release.label,
dependencies: [],
};
}
private getAddonChannelType(stability: WagoStability): AddonChannelType {
switch (stability) {
case "alpha":
return AddonChannelType.Alpha;
case "beta":
return AddonChannelType.Beta;
case "stable":
default:
return AddonChannelType.Stable;
}
}
// Get the wago friendly name for our addon channel
private getStability(channelType: AddonChannelType): WagoStability {
switch (channelType) {
case AddonChannelType.Alpha:
return "alpha";
case AddonChannelType.Beta:
return "beta";
case AddonChannelType.Stable:
default:
return "stable";
}
}
// The wago name for the client type
private getGameVersion(clientType: WowClientType): WagoGameVersion {
const clientGroup = this._warcraftService.getClientGroup(clientType);
@@ -105,4 +291,17 @@ export class WagoAddonProvider extends AddonProvider {
const scanResults: AppWowUpScanResult[] = await this._electronService.invoke("wowup-get-scan-results", filePaths);
return scanResults;
};
private onWagoTokenReceived = (evt, token) => {
console.debug(`[wago] onWagoTokenReceived`, token);
this._apiToken = token;
};
private getRequestHeaders(): {
[header: string]: string | string[];
} {
return {
Authorization: `Bearer ${this._apiToken}`,
};
}
}

View File

@@ -8,7 +8,7 @@
<div class="main">
<router-outlet></router-outlet>
</div>
<div *ngIf="sessionService.adSpace$ | async" class="ad-space text-1">
<div *ngIf="sessionService.adSpace$ | async" class="ad-space text-1 bg-secondary-3">
<div class="ad-details p-3">
<div class="center-col">
<div>
@@ -22,7 +22,7 @@
</div>
</div>
<div class="ad">
<app-webview></app-webview>
<app-webview *ngFor="let params of adPageParams" [options]="params"></app-webview>
</div>
</div>
</div>

View File

@@ -35,7 +35,7 @@ import {
ZOOM_FACTOR_KEY,
} from "../common/constants";
import { Addon } from "../common/entities/addon";
import { AppUpdateState, MenuConfig, SystemTrayConfig } from "../common/wowup/models";
import { AdPageOptions, AppUpdateState, MenuConfig, SystemTrayConfig } from "../common/wowup/models";
import { AppConfig } from "../environments/environment";
import { InstallFromUrlDialogComponent } from "./components/addons/install-from-url-dialog/install-from-url-dialog.component";
import { AlertDialogComponent } from "./components/common/alert-dialog/alert-dialog.component";
@@ -83,6 +83,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
public quitEnabled?: boolean;
public showPreLoad = true;
public adPageParams: AdPageOptions[] = [];
public constructor(
private _addonService: AddonService,
@@ -135,6 +136,17 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
});
}
});
this.sessionService.adSpace$.subscribe((enabled) => {
if (enabled) {
const providers = this._addonService.getAdRequiredProviders();
this.adPageParams = providers
.map((provider) => provider.getAdPageParams())
.filter((param) => param !== undefined);
} else {
this.adPageParams = [];
}
});
}
public ngOnInit(): void {
@@ -215,9 +227,6 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
}
public ngAfterViewInit(): void {
// TODO this is driven by provider
this.sessionService.enableAdSpace(true);
from(this.createAppMenu())
.pipe(
first(),

View File

@@ -1,9 +1,12 @@
<div mat-dialog-title class="addon-detail-view">
<div class="row align-items-start mb-1">
<div class="row justify-content-center bg-secondary-4 mr-3 icon flex-shrink-0"
<div
class="row justify-content-center bg-secondary-4 mr-3 icon flex-shrink-0"
[matTooltip]="('DIALOGS.ADDON_DETAILS.ADDON_ID_PREFIX' | translate) + displayExternalId"
[cdkCopyToClipboard]="fullExternalId" (click)="onClickExternalId()">
<div *ngIf="hasIconUrl === false" class=" text-3">
[cdkCopyToClipboard]="fullExternalId"
(click)="onClickExternalId()"
>
<div *ngIf="hasIconUrl === false" class="text-3">
{{ thumbnailLetter }}
</div>
@@ -12,30 +15,34 @@
<div class="flex-grow-1 mr-1">
<h2 class="m-0 title">{{ title }}</h2>
<h3 class="m-0">{{ 'DIALOGS.ADDON_DETAILS.BY_AUTHOR' | translate:{ authorName: subtitle } }}</h3>
<h3 class="m-0">{{ "DIALOGS.ADDON_DETAILS.BY_AUTHOR" | translate: { authorName: subtitle } }}</h3>
<h4 class="m-0 text-2">{{ version }}</h4>
</div>
<mat-icon class="close-icon" color="accent" [mat-dialog-close]="true" [ngStyle]="{ cursor: 'pointer' }"
svgIcon="fas:times">
<mat-icon
class="close-icon"
color="accent"
[mat-dialog-close]="true"
[ngStyle]="{ cursor: 'pointer' }"
svgIcon="fas:times"
>
</mat-icon>
</div>
</div>
<mat-dialog-content>
<div class="row align-items-start">
</div>
<div class="row align-items-start"></div>
<div *ngIf="hasFundingLinks" class="funding-link-container p-1">
<h3 class="m-0">{{ 'DIALOGS.ADDON_DETAILS.FUNDING_LINK_TITLE' | translate }}</h3>
<h3 class="m-0">{{ "DIALOGS.ADDON_DETAILS.FUNDING_LINK_TITLE" | translate }}</h3>
<div class="row align-items-center">
<app-funding-button *ngFor="let link of fundingLinks" [funding]="link"></app-funding-button>
</div>
</div>
<!-- MISSING DEPENDENCIES -->
<div *ngIf="isUnknownProvider && isMissingUnknownDependencies">
<h3>{{'DIALOGS.ADDON_DETAILS.MISSING_DEPENDENCIES' | translate}}</h3>
<h3>{{ "DIALOGS.ADDON_DETAILS.MISSING_DEPENDENCIES" | translate }}</h3>
<ul>
<li *ngFor="let dependency of missingDependencies">{{dependency}}</li>
<li *ngFor="let dependency of missingDependencies">{{ dependency }}</li>
</ul>
</div>
<!-- DEPENDENCIES -->
@@ -46,28 +53,36 @@
</span>
</div>
<!-- TABS -->
<mat-tab-group #tabs *ngIf="isUnknownProvider === false" class="scroller" [selectedIndex]="selectedTabIndex"
(selectedTabChange)="onSelectedTabChange($event)">
<mat-tab-group
#tabs
*ngIf="isUnknownProvider === false"
class="scroller"
[selectedIndex]="selectedTabIndex"
(selectedTabChange)="onSelectedTabChange($event)"
>
<!-- SUMMARY -->
<mat-tab [label]="'DIALOGS.ADDON_DETAILS.DESCRIPTION_TAB' | translate">
<app-progress-spinner *ngIf="fetchingFullDescription === true"></app-progress-spinner>
<div #descriptionContainer class="markdown-body addon-summary text-1 mt-3" [innerHtml]="description$ | async">
</div>
<div
#descriptionContainer
class="markdown-body addon-summary text-1 mt-3"
[innerHtml]="description$ | async"
></div>
</mat-tab>
<!-- CHANGELOG -->
<mat-tab *ngIf="canShowChangelog === true" [label]="'DIALOGS.ADDON_DETAILS.CHANGELOG_TAB' | translate">
<app-progress-spinner *ngIf="fetchingChangelog === true"></app-progress-spinner>
<div *ngIf="fetchingChangelog === false && hasChangeLog === false" class="mt-3">
{{'DIALOGS.ADDON_DETAILS.NO_CHANGELOG_TEXT' |
translate}}</div>
{{ "DIALOGS.ADDON_DETAILS.NO_CHANGELOG_TEXT" | translate }}
</div>
<div #changelogContainer class="markdown-body addon-changelog text-1 mt-3" [innerHTML]="changelog$ | async"></div>
</mat-tab>
<!-- SCREENSHOTS -->
<mat-tab *ngIf="previewItems.length > 0" [label]="'DIALOGS.ADDON_DETAILS.IMAGES_TAB' | translate">
<mat-grid-list class="image-grid pt-3" cols="4" rowHeight="1:1" gutterSize="3">
<mat-grid-tile *ngFor="let image of previewItems; index as i">
<div class="image-thumb-container ">
<img class="image-thumb mat-elevation-z8" [src]="image.data.thumb" [lightbox]="i">
<div class="image-thumb-container">
<img class="image-thumb mat-elevation-z8" [src]="image.data.thumb" [lightbox]="i" />
</div>
</mat-grid-tile>
</mat-grid-list>
@@ -76,17 +91,27 @@
</mat-dialog-content>
<mat-dialog-actions *ngIf="isUnknownProvider === false">
<div class="row w-100">
<button *ngIf="showRemoveButton" mat-button color="warn" (click)="onClickRemoveAddon()"> {{
"PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.REMOVE_ADDON_BUTTON" | translate }}</button>
<button *ngIf="showRemoveButton" mat-button color="warn" (click)="onClickRemoveAddon()">
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.REMOVE_ADDON_BUTTON" | translate }}
</button>
<div class="flex-grow-1"></div>
<a #providerLink mat-button class="mr-3 text-1" appExternalLink [href]="externalUrl"
[matTooltip]="'DIALOGS.ADDON_DETAILS.VIEW_IN_BROWSER_BUTTON' | translate">{{
"DIALOGS.ADDON_DETAILS.VIEW_ON_PROVIDER_PREFIX" | translate }}
<a
*ngIf="externalUrl !== 'UNKNOWN'"
#providerLink
mat-button
class="mr-3 text-1"
appExternalLink
[href]="externalUrl"
[matTooltip]="'DIALOGS.ADDON_DETAILS.VIEW_IN_BROWSER_BUTTON' | translate"
>{{ "DIALOGS.ADDON_DETAILS.VIEW_ON_PROVIDER_PREFIX" | translate }}
{{ provider }}
</a>
<app-addon-install-button *ngIf="showInstallButton" [addonSearchResult]="model.searchResult"
(onViewUpdated)="onInstallUpdated()">
<app-addon-install-button
*ngIf="showInstallButton"
[addonSearchResult]="model.searchResult"
(onViewUpdated)="onInstallUpdated()"
>
</app-addon-install-button>
<app-addon-update-button *ngIf="showUpdateButton" [listItem]="model.listItem"></app-addon-update-button>
</div>
</mat-dialog-actions>
</mat-dialog-actions>

View File

@@ -20,7 +20,6 @@ export class OptionsAddonSectionComponent implements OnInit {
public ngOnInit(): void {
this.addonProviderStates = filter(this._addonService.getAddonProviderStates(), (provider) => provider.canEdit);
this.enabledAddonProviders.setValue(this.getEnabledProviderNames());
console.debug("addonProviderStates", this.addonProviderStates);
}
public onProviderStateSelectionChange(event: MatSelectionListChange): void {

View File

@@ -1,13 +1,13 @@
import { Directive, ElementRef, OnInit } from "@angular/core";
import { Directive, ElementRef, Input, OnDestroy, OnInit } from "@angular/core";
import { nanoid } from "nanoid";
import { AdPageOptions } from "../../common/wowup/models";
import { FileService } from "../services/files/file.service";
@Directive({
selector: "app-webview",
})
export class WebviewComponent implements OnInit {
// TODO add input URL
// TODO add input config object
export class WebviewComponent implements OnInit, OnDestroy {
@Input("options") options: AdPageOptions;
private _tag: Electron.WebviewTag;
private _id: string = nanoid();
@@ -21,24 +21,37 @@ export class WebviewComponent implements OnInit {
this.initWebview(this._element).catch((e) => console.error(e));
}
ngOnDestroy(): void {
// Clean up the webview element
if (this._tag) {
if (this._tag.isDevToolsOpened()) {
this._tag.closeDevTools();
}
this._tag = undefined;
}
this._element.nativeElement.innerHTML = 0;
}
private async initWebview(element: ElementRef) {
// ad container requires a 'normal' UA
const userAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36`;
const preloadPath = await this._fileService.getAssetFilePath("preload/wago.js");
console.log("preloadPath", preloadPath);
const pageReferrer = this.options.referrer ? `httpreferrer="${this.options.referrer}"` : "";
const userAgent = this.options.userAgent ? `useragent="${this.options.userAgent}"` : "";
const preload = this.options.preloadFilePath
? `preload="${await this._fileService.getAssetFilePath(this.options.preloadFilePath)}"`
: "";
const placeholder = document.createElement("div");
placeholder.innerHTML = `
<webview id="${this._id}"
src="https://addons.wago.io/wowup_ad"
httpreferrer="https://wago.io"
src="${this.options.pageUrl}"
${pageReferrer}
style="width: 100%; height: 100%;"
nodeintegration="false"
nodeintegrationinsubframes="false"
plugins="false"
allowpopups="false"
preload="${preloadPath}"
useragent="${userAgent}">
${preload}
${userAgent}>
</webview>`;
this._tag = placeholder.firstElementChild as Electron.WebviewTag;
@@ -50,6 +63,6 @@ export class WebviewComponent implements OnInit {
private onWebviewReady = () => {
console.debug("onWebviewReady", this._tag);
this._tag.removeEventListener("dom-ready", this.onWebviewReady);
this._tag.openDevTools();
// this._tag.openDevTools();
};
}

View File

@@ -100,6 +100,7 @@ export class AddonService {
private readonly _searchErrorSrc = new Subject<GenericProviderError>();
private readonly _installQueue = new Subject<InstallQueueItem>();
private readonly _anyUpdatesAvailableSrc = new BehaviorSubject<boolean>(false);
private readonly _addonProviderChangeSrc = new Subject<AddonProvider>();
private _activeInstalls: AddonUpdateEvent[] = [];
private _subscriptions: Subscription[] = [];
@@ -112,6 +113,7 @@ export class AddonService {
public readonly scanError$ = this._scanErrorSrc.asObservable();
public readonly searchError$ = this._searchErrorSrc.asObservable();
public readonly anyUpdatesAvailable$ = this._anyUpdatesAvailableSrc.asObservable();
public readonly addonProviderChange$ = this._addonProviderChangeSrc.asObservable();
public constructor(
private _addonStorage: AddonStorageService,
@@ -126,6 +128,7 @@ export class AddonService {
) {
// Create our base set of addon providers
this._addonProviders = addonProviderFactory.getProviders();
console.debug("_addonProviders", this._addonProviders);
// This should keep the current update queue state snapshot up to date
const addonInstalledSub = this.addonInstalled$
@@ -1831,11 +1834,14 @@ export class AddonService {
return !!this.getByExternalId(externalId, providerName, installation.id);
}
// TODO move this to a different service
public setProviderEnabled(providerName: string, enabled: boolean): void {
const provider = this.getProvider(providerName);
if (provider) {
provider.enabled = enabled;
}
this._addonProviderChangeSrc.next(provider);
}
private getProvider(providerName: string): AddonProvider | undefined {
@@ -2018,6 +2024,10 @@ export class AddonService {
return _.filter(this._addonProviders, (provider) => provider.enabled);
}
public getAdRequiredProviders(): AddonProvider[] {
return this.getEnabledAddonProviders().filter((provider) => provider.adRequired);
}
private trackInstallAction(installType: InstallType, addon: Addon) {
this._analyticsService.trackAction(USER_ACTION_ADDON_INSTALL, {
clientType: getEnumName(WowClientType, addon.clientType),

View File

@@ -10,6 +10,7 @@ import { WarcraftInstallationService } from "../warcraft/warcraft-installation.s
import { ColumnState } from "../../models/wowup/column-state";
import { map } from "rxjs/operators";
import { WowUpAccountService } from "../wowup/wowup-account.service";
import { AddonService } from "../addons/addon.service";
@Injectable({
providedIn: "root",
@@ -55,7 +56,8 @@ export class SessionService {
public constructor(
private _warcraftInstallationService: WarcraftInstallationService,
private _preferenceStorageService: PreferenceStorageService,
private _wowUpAccountService: WowUpAccountService
private _wowUpAccountService: WowUpAccountService,
private _addonService: AddonService
) {
this._selectedDetailTabType =
this._preferenceStorageService.getObject<DetailsTabType>(SELECTED_DETAILS_TAB_KEY) || "description";
@@ -63,6 +65,17 @@ export class SessionService {
this._warcraftInstallationService.wowInstallations$.subscribe((installations) =>
this.onWowInstallationsChange(installations)
);
this._addonService.addonProviderChange$.subscribe((provider) => {
this.updateAdSpace();
});
this.updateAdSpace();
}
private updateAdSpace() {
const allProviders = this._addonService.getEnabledAddonProviders();
this._adSpaceSrc.next(allProviders.findIndex((p) => p.adRequired) !== -1);
}
public get wowUpAuthToken(): string {
@@ -93,10 +106,6 @@ export class SessionService {
this._addonsChangedSrc.next(true);
}
public enableAdSpace(enabled: boolean): void {
this._adSpaceSrc.next(enabled);
}
public getSelectedDetailsTab(): DetailsTabType {
return this._selectedDetailTabType;
}

View File

@@ -88,7 +88,8 @@ declare type RendererChannels =
| "base64-encode"
| "base64-decode"
| "set-release-channel"
| "zip-list-files";
| "zip-list-files"
| "wago-token-received";
declare global {
interface Window {

View File

@@ -131,3 +131,11 @@ export interface AddonUpdatePushNotification extends PushNotificationData {
addonName: string;
addonId: string;
}
export interface AdPageOptions {
pageUrl: string;
referrer?: string;
userAgent?: string;
preloadFilePath?: string;
explanationKey?: string; // locale key of the translated explanation of this ad
}