mirror of
https://github.com/WowUp/WowUp.git
synced 2026-04-23 15:27:03 -04:00
Add the ability to switch providers where applicable
Fix issues with the context menu width? Fix an issue with the updated at time being NaN
This commit is contained in:
@@ -97,7 +97,7 @@ function createWindow(): BrowserWindow {
|
||||
title: "WowUp",
|
||||
titleBarStyle: "hidden",
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, "preload.js"),
|
||||
// preload: path.join(__dirname, "preload.js"),
|
||||
nodeIntegration: true,
|
||||
allowRunningInsecureContent: argv.serve ? true : false,
|
||||
webSecurity: false,
|
||||
|
||||
@@ -1,80 +1,58 @@
|
||||
<div class="addon-column row align-items-center">
|
||||
<div class="thumbnail-container">
|
||||
<div
|
||||
*ngIf="listItem.hasThumbnail === true"
|
||||
class="addon-logo-container bg-secondary-3"
|
||||
[style.backgroundImage]="'url(' + listItem.addon.thumbnailUrl + ')'"
|
||||
></div>
|
||||
<div *ngIf="listItem.hasThumbnail === true" class="addon-logo-container bg-secondary-3"
|
||||
[style.backgroundImage]="'url(' + listItem.addon.thumbnailUrl + ')'"></div>
|
||||
<div *ngIf="listItem.hasThumbnail === false" class="addon-logo-container">
|
||||
<div class="addon-logo-letter text-3">
|
||||
{{ listItem.thumbnailLetter }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
*ngIf="listItem.isBetaChannel || listItem.isAlphaChannel"
|
||||
class="channel bg-secondary-3"
|
||||
[ngClass]="{
|
||||
<div *ngIf="listItem.isBetaChannel || listItem.isAlphaChannel" class="channel bg-secondary-3" [ngClass]="{
|
||||
beta: listItem.isBetaChannel,
|
||||
alpha: listItem.isAlphaChannel
|
||||
}"
|
||||
>
|
||||
}">
|
||||
{{ listItem.isAlphaChannel ? "Alpha" : "Beta" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a class="addon-title hover-text-2 mat-subheading-2" (click)="viewDetails()" [ngClass]="{ 'text-3': listItem.isIgnored }">{{
|
||||
<a class="addon-title hover-text-2 mat-subheading-2" (click)="viewDetails()"
|
||||
[ngClass]="{ 'text-3': listItem.isIgnored }">{{
|
||||
listItem.addon.name
|
||||
}}</a>
|
||||
<div class="addon-funding">
|
||||
<a
|
||||
*ngIf="listItem.addon.patreonFundingLink"
|
||||
appExternalLink
|
||||
[href]="listItem.addon.patreonFundingLink"
|
||||
matTooltip="Support the author on Patreon"
|
||||
>
|
||||
<a *ngIf="listItem.addon.patreonFundingLink" appExternalLink [href]="listItem.addon.patreonFundingLink"
|
||||
matTooltip="Support the author on Patreon">
|
||||
<img class="funding-icon" src="assets/images/patreon_logo_small.png" />
|
||||
</a>
|
||||
<a
|
||||
*ngIf="listItem.addon.githubFundingLink"
|
||||
appExternalLink
|
||||
[href]="listItem.addon.githubFundingLink"
|
||||
matTooltip="Support the author on GitHub"
|
||||
>
|
||||
<a *ngIf="listItem.addon.githubFundingLink" appExternalLink [href]="listItem.addon.githubFundingLink"
|
||||
matTooltip="Support the author on GitHub">
|
||||
<img class="funding-icon" src="assets/images/github_logo_small.png" />
|
||||
</a>
|
||||
<a
|
||||
*ngIf="listItem.addon.customFundingLink"
|
||||
appExternalLink
|
||||
[href]="listItem.addon.customFundingLink"
|
||||
matTooltip="Support this author"
|
||||
>
|
||||
<a *ngIf="listItem.addon.customFundingLink" appExternalLink [href]="listItem.addon.customFundingLink"
|
||||
matTooltip="Support this author">
|
||||
<img class="funding-icon" src="assets/images/custom_funding_logo_small.png" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="addon-version text-2 row align-items-center" [ngClass]="{ ignored: listItem.isIgnored }">
|
||||
<div *ngIf="this.listItem.isAutoUpdate === true" class="mr-2">
|
||||
<mat-icon
|
||||
class="auto-update-icon text-2"
|
||||
[matTooltip]="'PAGES.MY_ADDONS.TABLE.AUTO_UPDATE_ICON_TOOLTIP' | translate"
|
||||
svgIcon="far:clock"
|
||||
>
|
||||
<div *ngIf="addonUtils.hasMultipleProviders(listItem.addon)" class="mr-2">
|
||||
<mat-icon class="auto-update-icon" svgIcon="fas:code-branch" [matTooltip]="'This addon has multiple providers'">
|
||||
</mat-icon>
|
||||
</div>
|
||||
<div
|
||||
*ngIf="hasRequiredDependencies()"
|
||||
class="mr-2"
|
||||
[matTooltip]="'COMMON.DEPENDENCY.TOOLTIP' | translate: dependencyTooltip"
|
||||
>
|
||||
<div *ngIf="this.listItem.isAutoUpdate === true" class="mr-2">
|
||||
<mat-icon class="auto-update-icon text-2"
|
||||
[matTooltip]="'PAGES.MY_ADDONS.TABLE.AUTO_UPDATE_ICON_TOOLTIP' | translate" svgIcon="far:clock">
|
||||
</mat-icon>
|
||||
</div>
|
||||
<div *ngIf="hasRequiredDependencies()" class="mr-2"
|
||||
[matTooltip]="'COMMON.DEPENDENCY.TOOLTIP' | translate: dependencyTooltip">
|
||||
<mat-icon class="auto-update-icon" svgIcon="fas:link"></mat-icon>
|
||||
</div>
|
||||
{{ listItem.addon.installedVersion }}
|
||||
<div
|
||||
class="update-available row"
|
||||
*ngIf="showUpdateToVersion && listItem.addon.latestVersion !== listItem.addon.installedVersion"
|
||||
>
|
||||
<div class="update-available row"
|
||||
*ngIf="showUpdateToVersion && listItem.addon.latestVersion !== listItem.addon.installedVersion">
|
||||
<mat-icon class="upgrade-icon" svgIcon="fas:play"></mat-icon>
|
||||
<div>{{ listItem.addon.latestVersion }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
||||
import { AddonDependencyType } from "app/models/wowup/addon-dependency-type";
|
||||
import { AddonViewModel } from "../../business-objects/my-addon-list-item";
|
||||
import * as AddonUtils from "../../utils/addon.utils";
|
||||
|
||||
@Component({
|
||||
selector: "app-my-addons-addon-cell",
|
||||
@@ -13,6 +14,8 @@ export class MyAddonsAddonCellComponent implements OnInit {
|
||||
|
||||
@Output() onViewDetails: EventEmitter<AddonViewModel> = new EventEmitter();
|
||||
|
||||
public addonUtils = AddonUtils;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
@@ -2,6 +2,11 @@ import { WowClientType } from "../models/warcraft/wow-client-type";
|
||||
import { AddonChannelType } from "../models/wowup/addon-channel-type";
|
||||
import { AddonDependency } from "../models/wowup/addon-dependency";
|
||||
|
||||
export interface AddonExternalId {
|
||||
providerName: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface Addon {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -30,5 +35,6 @@ export interface Addon {
|
||||
summary?: string;
|
||||
screenshotUrls?: string[];
|
||||
releasedAt?: Date;
|
||||
externalIds?: AddonExternalId[];
|
||||
dependencies?: AddonDependency[];
|
||||
}
|
||||
|
||||
@@ -12,4 +12,5 @@ export interface Toc {
|
||||
wowInterfaceId?: string;
|
||||
tukUiProjectId?: string;
|
||||
tukUiProjectFolders?: string;
|
||||
loadOnDemand?: string;
|
||||
}
|
||||
|
||||
@@ -30,19 +30,17 @@
|
||||
<div class="button-container">
|
||||
<button mat-flat-button color="primary" [matTooltip]="'PAGES.MY_ADDONS.UPDATE_ALL_BUTTON_TOOLTIP' | translate"
|
||||
[disabled]="enableControls === false || enableUpdateAll === false" (click)="onUpdateAll()"
|
||||
(contextmenu)="onUpdateAllContext($event)" appUserActionTracker category="MyAddons" action="UpdateAll">
|
||||
(contextmenu)="onUpdateAllContext($event)">
|
||||
{{ "PAGES.MY_ADDONS.UPDATE_ALL_BUTTON" | translate }}
|
||||
</button>
|
||||
<button mat-flat-button color="primary"
|
||||
[matTooltip]="'PAGES.MY_ADDONS.CHECK_UPDATES_BUTTON_TOOLTIP' | translate"
|
||||
[disabled]="enableControls === false" (click)="onRefresh()" appUserActionTracker category="MyAddons"
|
||||
action="CheckUpdates">
|
||||
[disabled]="enableControls === false" (click)="onRefresh()">
|
||||
{{ "PAGES.MY_ADDONS.CHECK_UPDATES_BUTTON" | translate }}
|
||||
</button>
|
||||
<button mat-flat-button color="primary"
|
||||
[matTooltip]="'PAGES.MY_ADDONS.RESCAN_FOLDERS_BUTTON_TOOLTIP' | translate"
|
||||
[disabled]="enableControls === false" (click)="onReScan()" appUserActionTracker category="MyAddons"
|
||||
action="ReScanFolders">
|
||||
[disabled]="enableControls === false" (click)="onReScan()">
|
||||
{{ "PAGES.MY_ADDONS.RESCAN_FOLDERS_BUTTON" | translate }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -135,7 +133,7 @@
|
||||
{{ "PAGES.MY_ADDONS.TABLE.PROVIDER_COLUMN_HEADER" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element" class="cell-padding">
|
||||
<div *ngIf="element.addon.providerName !== 'WowUp'">
|
||||
<div class="row" *ngIf="element.addon.providerName !== 'WowUp'">
|
||||
{{ element.addon.providerName }}
|
||||
</div>
|
||||
<div *ngIf="element.addon.providerName === 'WowUp'" class="addon-provider">
|
||||
@@ -194,49 +192,55 @@
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-checkbox class="mat-menu-item" [checked]="listItem.addon.isIgnored"
|
||||
(change)="onClickIgnoreAddon($event, listItem)" appUserActionTracker category="MyAddons" action="IgnoreAddon"
|
||||
[label]="listItem.addon.name">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.IGNORE_ADDON_BUTTON" | translate }}
|
||||
</mat-checkbox>
|
||||
<mat-checkbox *ngIf="listItem.addon.isIgnored === false" class="mat-menu-item"
|
||||
[checked]="listItem.addon.autoUpdateEnabled" (change)="onClickAutoUpdateAddon($event, listItem)"
|
||||
appUserActionTracker category="MyAddons" action="AutoUpdateAddon" [label]="listItem.addon.name">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.AUTO_UPDATE_ADDON_BUTTON" | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="mat-menu-item">
|
||||
<mat-checkbox [checked]="listItem.addon.isIgnored" (change)="onClickIgnoreAddon($event, listItem)">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.IGNORE_ADDON_BUTTON" | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div *ngIf="listItem.addon.isIgnored === false" class="mat-menu-item">
|
||||
<mat-checkbox [checked]="listItem.addon.autoUpdateEnabled" (change)="onClickAutoUpdateAddon($event, listItem)">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.AUTO_UPDATE_ADDON_BUTTON" | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<button mat-menu-item [matMenuTriggerFor]="addonChannels">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.CHANNEL_SUBMENT_TITLE" | translate }}
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.CHANNEL_SUBMENU_TITLE" | translate }}
|
||||
</button>
|
||||
<button mat-menu-item (click)="onShowfolder(listItem.addon)" appUserActionTracker category="MyAddons"
|
||||
action="ShowAddonFolder" [label]="listItem.addon.name">
|
||||
<button *ngIf="addonUtils.hasMultipleProviders(listItem.addon)" mat-menu-item [matMenuTriggerFor]="addonProviders">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.PROVIDER_SUBMENU_TITLE" | translate }}
|
||||
</button>
|
||||
<button mat-menu-item (click)="onShowfolder(listItem.addon)">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.SHOW_FOLDER" | translate }}
|
||||
</button>
|
||||
<button mat-menu-item (click)="onReInstallAddon(listItem)" appUserActionTracker category="MyAddons"
|
||||
action="ReInstallAddon" [label]="listItem.addon.name">
|
||||
<button mat-menu-item (click)="onReInstallAddon(listItem)">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.REINSTALL_ADDON_BUTTON" | translate }}
|
||||
</button>
|
||||
<mat-divider></mat-divider>
|
||||
<button mat-menu-item (click)="onRemoveAddon(listItem.addon)" appUserActionTracker category="MyAddons"
|
||||
action="RemoveAddon" [label]="listItem.addon.name">
|
||||
<button mat-menu-item (click)="onRemoveAddon(listItem.addon)">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.REMOVE_ADDON_BUTTON" | translate }}
|
||||
</button>
|
||||
<mat-menu #addonChannels="matMenu" class="addon-context-menu">
|
||||
<mat-radio-group class="vertical-radio-group" [ngModel]="listItem.addon.channelType"
|
||||
(change)="onSelectedAddonChannelChange($event, listItem)">
|
||||
<mat-radio-button class="mat-menu-item" [value]="0" appUserActionTracker category="MyAddons"
|
||||
action="SetStableAddonChannel" [label]="listItem.addon.name">
|
||||
<mat-radio-button class="mat-menu-item" [value]="0">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.STABLE_ADDON_CHANNEL" | translate }}
|
||||
</mat-radio-button>
|
||||
<mat-radio-button class="mat-menu-item" [value]="1" appUserActionTracker category="MyAddons"
|
||||
action="SetBetaAddonChannel" [label]="listItem.addon.name">
|
||||
<mat-radio-button class="mat-menu-item" [value]="1">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.BETA_ADDON_CHANNEL" | translate }}
|
||||
</mat-radio-button>
|
||||
<mat-radio-button class="mat-menu-item" [value]="2" appUserActionTracker category="MyAddons"
|
||||
action="SetAlphaAddonChannel" [label]="listItem.addon.name">
|
||||
<mat-radio-button class="mat-menu-item" [value]="2">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.ALPHA_ADDON_CHANNEL" | translate }}
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</mat-menu>
|
||||
<mat-menu #addonProviders="matMenu" class="addon-context-menu">
|
||||
<mat-radio-group class="vertical-radio-group" [value]="listItem.addon.providerName"
|
||||
(change)="onSelectedProviderChange($event, listItem)">
|
||||
<mat-radio-button *ngFor="let provider of addonUtils.getAllProviders(listItem.addon)" class="mat-menu-item"
|
||||
[value]="provider.providerName">
|
||||
{{ provider.providerName }}
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</mat-menu>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
|
||||
@@ -258,7 +262,7 @@
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.AUTO_UPDATE_ADDON_BUTTON" | translate }}
|
||||
</mat-checkbox>
|
||||
<button mat-menu-item [matMenuTriggerFor]="addonChannels">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.CHANNEL_SUBMENT_TITLE" | translate }}
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.CHANNEL_SUBMENU_TITLE" | translate }}
|
||||
</button>
|
||||
<button mat-menu-item (click)="onReInstallAddons(listItems)">
|
||||
{{ "PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.REINSTALL_ADDON_BUTTON" | translate }}
|
||||
@@ -306,12 +310,10 @@
|
||||
</div>
|
||||
<mat-menu #updateAllContextMenu="matMenu" class="addon-context-menu">
|
||||
<ng-template matMenuContent let-columns="columns">
|
||||
<button mat-menu-item (click)="onUpdateAllRetailClassic()" appUserActionTracker category="MyAddons"
|
||||
action="UpdateAllClassicRetail">
|
||||
<button mat-menu-item (click)="onUpdateAllRetailClassic()">
|
||||
{{ "PAGES.MY_ADDONS.UPDATE_ALL_CONTEXT_MENU.UPDATE_RETAIL_CLASSIC_BUTTON" | translate }}
|
||||
</button>
|
||||
<button mat-menu-item (click)="onUpdateAllClients()" appUserActionTracker category="MyAddons"
|
||||
action="UpdateAllClients">
|
||||
<button mat-menu-item (click)="onUpdateAllClients()">
|
||||
{{ "PAGES.MY_ADDONS.UPDATE_ALL_CONTEXT_MENU.UPDATE_ALL_CLIENTS_BUTTON" | translate }}
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
@@ -111,6 +111,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
height: 11px;
|
||||
width: 11px;
|
||||
}
|
||||
|
||||
.addon-provider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -20,8 +20,8 @@ import { MatTableDataSource } from "@angular/material/table";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { AddonUpdateEvent } from "app/models/wowup/addon-update-event";
|
||||
import * as _ from "lodash";
|
||||
import { BehaviorSubject, from, Observable, Subscription } from "rxjs";
|
||||
import { filter, map } from "rxjs/operators";
|
||||
import { BehaviorSubject, from, Subscription } from "rxjs";
|
||||
import { map } from "rxjs/operators";
|
||||
import { AddonViewModel } from "../../business-objects/my-addon-list-item";
|
||||
import { AddonDetailComponent, AddonDetailModel } from "../../components/addon-detail/addon-detail.component";
|
||||
import { ConfirmDialogComponent } from "../../components/confirm-dialog/confirm-dialog.component";
|
||||
@@ -29,7 +29,6 @@ import { Addon } from "../../entities/addon";
|
||||
import { WowClientType } from "../../models/warcraft/wow-client-type";
|
||||
import { AddonInstallState } from "../../models/wowup/addon-install-state";
|
||||
import { ColumnState } from "../../models/wowup/column-state";
|
||||
import { SelectItem } from "../../models/wowup/select-item";
|
||||
import { ElectronService } from "../../services";
|
||||
import { AddonService } from "../../services/addons/addon.service";
|
||||
import { SessionService } from "../../services/session/session.service";
|
||||
@@ -38,6 +37,8 @@ import { WowUpService } from "../../services/wowup/wowup.service";
|
||||
import { getEnumName } from "../../utils/enum.utils";
|
||||
import { stringIncludes } from "../../utils/string.utils";
|
||||
import { WowUpAddonService } from "../../services/wowup/wowup-addon.service";
|
||||
import * as AddonUtils from "../../utils/addon.utils";
|
||||
import { AlertDialogComponent } from "../../components/alert-dialog/alert-dialog.component";
|
||||
|
||||
@Component({
|
||||
selector: "app-my-addons",
|
||||
@@ -71,6 +72,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
public enableUpdateAll = false;
|
||||
public activeSort = "sortOrder";
|
||||
public activeSortDirection = "asc";
|
||||
public addonUtils = AddonUtils;
|
||||
|
||||
public columns: ColumnState[] = [
|
||||
{
|
||||
@@ -542,6 +544,39 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
public onSelectedProviderChange(evt: MatRadioChange, listItem: AddonViewModel) {
|
||||
const messageData = {
|
||||
addonName: listItem.addon.name,
|
||||
providerName: evt.value,
|
||||
};
|
||||
|
||||
const dialogRef = this._dialog.open(ConfirmDialogComponent, {
|
||||
data: {
|
||||
title: this._translateService.instant("PAGES.MY_ADDONS.CHANGE_ADDON_PROVIDER_CONFIRMATION.TITLE"),
|
||||
message: this._translateService.instant(
|
||||
"PAGES.MY_ADDONS.CHANGE_ADDON_PROVIDER_CONFIRMATION.MESSAGE",
|
||||
messageData
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(async (result) => {
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const externalId = _.find(listItem.addon.externalIds, (extid) => extid.providerName === evt.value);
|
||||
this.addonService.setProvider(listItem.addon, externalId.id, externalId.providerName, this.selectedClient);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
const errorTitle = this._translateService.instant("DIALOGS.ALERT.ERROR_TITLE");
|
||||
const errorMessage = this._translateService.instant("COMMON.ERRORS.CHANGE_PROVIDER_ERROR", messageData);
|
||||
this.showErrorMessage(errorTitle, errorMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public onSelectedAddonChannelChange(evt: MatRadioChange, listItem: AddonViewModel) {
|
||||
this.onSelectedAddonsChannelChange(evt, [listItem]);
|
||||
}
|
||||
@@ -566,14 +601,19 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
return `COMMON.ENUM.ADDON_CHANNEL_TYPE.${channelType.toUpperCase()}`;
|
||||
}
|
||||
|
||||
private lazyLoad() {
|
||||
private async lazyLoad() {
|
||||
if (this._lazyLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._lazyLoaded = true;
|
||||
this.isBusy = true;
|
||||
this.enableControls = false;
|
||||
|
||||
console.debug("LAZY LOAD");
|
||||
|
||||
await this.addonService.backfillAddons();
|
||||
|
||||
const selectedClientSubscription = this._sessionService.selectedClientType$
|
||||
.pipe(
|
||||
map((clientType) => {
|
||||
@@ -789,4 +829,15 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
this.enableUpdateAll = this.sortedListItems.some((li) => !li.isIgnored && (li.needsInstall || li.needsUpdate));
|
||||
this.setPageContextText();
|
||||
};
|
||||
|
||||
private showErrorMessage(title: string, message: string) {
|
||||
const dialogRef = this._dialog.open(AlertDialogComponent, {
|
||||
minWidth: 250,
|
||||
data: {
|
||||
title,
|
||||
message,
|
||||
},
|
||||
});
|
||||
dialogRef.afterClosed().subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@ export class RelativeDurationPipe implements PipeTransform {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (isNaN(then.getTime())) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const seconds = Math.round((now.getTime() - then.getTime()) / 1000);
|
||||
const minutes = Math.round(seconds / 60);
|
||||
|
||||
@@ -19,7 +19,6 @@ export class AddonProviderFactory {
|
||||
private _cachingService: CachingService,
|
||||
private _electronService: ElectronService,
|
||||
private _httpClient: HttpClient,
|
||||
private _sessionService: SessionService,
|
||||
private _fileService: FileService
|
||||
) {}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ import { Injectable } from "@angular/core";
|
||||
import { AddonDependency } from "app/models/wowup/addon-dependency";
|
||||
import { AddonDependencyType } from "app/models/wowup/addon-dependency-type";
|
||||
import { AddonSearchResultDependency } from "app/models/wowup/addon-search-result-dependency";
|
||||
import { Toc } from "app/models/wowup/toc";
|
||||
import { ADDON_PROVIDER_CURSEFORGE, ADDON_PROVIDER_TUKUI, ADDON_PROVIDER_WOWINTERFACE } from "common/constants";
|
||||
import * as fs from "fs";
|
||||
import * as _ from "lodash";
|
||||
import * as path from "path";
|
||||
@@ -11,7 +13,7 @@ import * as slug from "slug";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { AddonProvider } from "../../addon-providers/addon-provider";
|
||||
import { CurseAddonProvider } from "../../addon-providers/curse-addon-provider";
|
||||
import { Addon } from "../../entities/addon";
|
||||
import { Addon, AddonExternalId } from "../../entities/addon";
|
||||
import { WowClientType } from "../../models/warcraft/wow-client-type";
|
||||
import { AddonChannelType } from "../../models/wowup/addon-channel-type";
|
||||
import { AddonFolder } from "../../models/wowup/addon-folder";
|
||||
@@ -19,7 +21,7 @@ import { AddonInstallState } from "../../models/wowup/addon-install-state";
|
||||
import { AddonSearchResult } from "../../models/wowup/addon-search-result";
|
||||
import { AddonSearchResultFile } from "../../models/wowup/addon-search-result-file";
|
||||
import { AddonUpdateEvent } from "../../models/wowup/addon-update-event";
|
||||
import { getEnumName } from "../../utils/enum.utils";
|
||||
import { getEnumList, getEnumName } from "../../utils/enum.utils";
|
||||
import { AnalyticsService } from "../analytics/analytics.service";
|
||||
import { DownloadSevice } from "../download/download.service";
|
||||
import { FileService } from "../files/file.service";
|
||||
@@ -286,6 +288,8 @@ export class AddonService {
|
||||
|
||||
await this.installDependencies(addon, onUpdate);
|
||||
|
||||
await this.backfillAddon(addon);
|
||||
|
||||
queueItem.completion.resolve();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
@@ -581,6 +585,7 @@ export class AddonService {
|
||||
}
|
||||
|
||||
const matchedAddonFolders = addonFolders.filter((addonFolder) => !!addonFolder.matchingAddon);
|
||||
matchedAddonFolders.forEach((maf) => this.setExternalIds(maf.matchingAddon, maf.toc));
|
||||
const matchedGroups = _.groupBy(
|
||||
matchedAddonFolders,
|
||||
(addonFolder) => `${addonFolder.matchingAddon.providerName}${addonFolder.matchingAddon.externalId}`
|
||||
@@ -588,7 +593,59 @@ export class AddonService {
|
||||
|
||||
console.log(Object.keys(matchedGroups));
|
||||
|
||||
return Object.values(matchedGroups).map((value) => value[0].matchingAddon);
|
||||
return Object.values(matchedGroups).map(
|
||||
(value) => _.orderBy(value, (v) => v.matchingAddon.externalIds.length).reverse()[0].matchingAddon
|
||||
);
|
||||
}
|
||||
|
||||
private setExternalIds(addon: Addon, toc: Toc) {
|
||||
if (!toc) {
|
||||
return;
|
||||
}
|
||||
|
||||
const externalIds: AddonExternalId[] = [];
|
||||
if (toc.wowInterfaceId) {
|
||||
externalIds.push({
|
||||
id: toc.wowInterfaceId,
|
||||
providerName: ADDON_PROVIDER_WOWINTERFACE,
|
||||
});
|
||||
}
|
||||
|
||||
if (toc.tukUiProjectId) {
|
||||
externalIds.push({
|
||||
id: toc.tukUiProjectId,
|
||||
providerName: ADDON_PROVIDER_TUKUI,
|
||||
});
|
||||
}
|
||||
|
||||
if (toc.curseProjectId) {
|
||||
externalIds.push({
|
||||
id: toc.curseProjectId,
|
||||
providerName: ADDON_PROVIDER_CURSEFORGE,
|
||||
});
|
||||
}
|
||||
|
||||
addon.externalIds = externalIds;
|
||||
}
|
||||
|
||||
public async setProvider(addon: Addon, externalId: string, providerName: string, clientType: WowClientType) {
|
||||
const provider = this.getProvider(providerName);
|
||||
if (!provider) {
|
||||
throw new Error(`Provider not found: ${providerName}`);
|
||||
}
|
||||
|
||||
console.debug(`Setting new provider: ${providerName}`);
|
||||
const externalAddon = await this.getAddon(externalId, providerName, clientType).toPromise();
|
||||
if (!externalAddon) {
|
||||
throw new Error(`External addon not found: ${providerName}|${externalId}`);
|
||||
}
|
||||
|
||||
console.debug("externalAdd", externalAddon);
|
||||
|
||||
this.removeAddon(addon, false);
|
||||
|
||||
this._addonStorage.set(externalAddon.id, externalAddon);
|
||||
this.installAddon(externalAddon.id);
|
||||
}
|
||||
|
||||
public getFeaturedAddons(clientType: WowClientType): Observable<AddonSearchResult[]> {
|
||||
@@ -607,60 +664,51 @@ export class AddonService {
|
||||
return !!this.getByExternalId(externalId, clientType);
|
||||
}
|
||||
|
||||
public async backfillAddons() {
|
||||
console.debug("backfillAddons");
|
||||
const clientTypes = getEnumList<WowClientType>(WowClientType).filter(
|
||||
(clientType) => clientType !== WowClientType.None
|
||||
);
|
||||
|
||||
for (let clientType of clientTypes) {
|
||||
const addons = this._addonStorage.getAllForClientType(clientType);
|
||||
for (let addon of addons) {
|
||||
await this.backfillAddon(addon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async backfillAddon(addon: Addon) {
|
||||
if (addon.externalIds) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tocPaths = this.getTocPaths(addon);
|
||||
console.debug("tocPaths", tocPaths);
|
||||
const tocFiles = await Promise.all(_.map(tocPaths, (tocPath) => this._tocService.parse(tocPath)));
|
||||
const orderedTocFiles = _.orderBy(tocFiles, ["wowInterfaceId", "loadOnDemand"], ["desc", "asc"]);
|
||||
const primaryToc = _.first(orderedTocFiles);
|
||||
this.setExternalIds(addon, primaryToc);
|
||||
this.saveAddon(addon);
|
||||
}
|
||||
|
||||
public getTocPaths(addon: Addon) {
|
||||
const addonFolderPath = this._warcraftService.getAddonFolderPath(addon.clientType);
|
||||
const installedFolders = this.getInstalledFolders(addon);
|
||||
|
||||
return _.map(installedFolders, (installedFolder) =>
|
||||
path.join(addonFolderPath, installedFolder, `${installedFolder}.toc`)
|
||||
);
|
||||
}
|
||||
|
||||
private getProvider(providerName: string) {
|
||||
return this._addonProviders.find((provider) => provider.name === providerName);
|
||||
}
|
||||
|
||||
private getAllStoredAddons(clientType: WowClientType) {
|
||||
const addons: Addon[] = [];
|
||||
|
||||
this._addonStorage.query((store) => {
|
||||
for (const result of store) {
|
||||
addons.push(result[1] as Addon);
|
||||
}
|
||||
});
|
||||
|
||||
return addons;
|
||||
}
|
||||
|
||||
private async getLocalAddons(clientType: WowClientType): Promise<any> {
|
||||
const addonFolders = await this._warcraftService.listAddons(clientType);
|
||||
const addons: Addon[] = [];
|
||||
console.log("addonFolders", addonFolders);
|
||||
|
||||
for (const folder of addonFolders) {
|
||||
try {
|
||||
let addon: Addon;
|
||||
|
||||
if (folder.toc.curseProjectId) {
|
||||
addon = await this.getCurseAddonById(folder, clientType);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!addon) {
|
||||
continue;
|
||||
}
|
||||
|
||||
addons.push(addon);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
return addons;
|
||||
}
|
||||
|
||||
private getAddonProvider(addonUri: URL): AddonProvider {
|
||||
return this._addonProviders.find((provider) => provider.isValidAddonUri(addonUri));
|
||||
}
|
||||
|
||||
private async getCurseAddonById(addonFolder: AddonFolder, clientType: WowClientType) {
|
||||
const curseProvider = this._addonProviders.find((p) => p instanceof CurseAddonProvider);
|
||||
const searchResult = await curseProvider.getById(addonFolder.toc.curseProjectId, clientType).toPromise();
|
||||
const latestFile = this.getLatestFile(searchResult, AddonChannelType.Stable);
|
||||
return this.createAddon(addonFolder.name, searchResult, latestFile, clientType);
|
||||
}
|
||||
|
||||
private getLatestFile(searchResult: AddonSearchResult, channelType: AddonChannelType): AddonSearchResultFile {
|
||||
let files = _.filter(searchResult.files, (f: AddonSearchResultFile) => f.channelType <= channelType);
|
||||
files = _.orderBy(files, ["releaseDate"]).reverse();
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
faPlay,
|
||||
faBug,
|
||||
faLink,
|
||||
faInfoCircle,
|
||||
faCodeBranch,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { faQuestionCircle, faClock } from "@fortawesome/free-regular-svg-icons";
|
||||
import { faDiscord, faGithub } from "@fortawesome/free-brands-svg-icons";
|
||||
@@ -33,6 +35,8 @@ export class IconService {
|
||||
this.addSvg(faLink);
|
||||
this.addSvg(faDiscord);
|
||||
this.addSvg(faGithub);
|
||||
this.addSvg(faInfoCircle);
|
||||
this.addSvg(faCodeBranch);
|
||||
}
|
||||
|
||||
async addSvg(icon: IconDefinition) {
|
||||
|
||||
@@ -25,6 +25,7 @@ export class TocService {
|
||||
dependencies: this.getValue("Dependencies", tocText),
|
||||
tukUiProjectId: this.getValue("X-Tukui-ProjectID", tocText),
|
||||
tukUiProjectFolders: this.getValue("X-Tukui-ProjectFolders", tocText),
|
||||
loadOnDemand: this.getValue("LoadOnDemand", tocText),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
14
wowup-electron/src/app/utils/addon.utils.ts
Normal file
14
wowup-electron/src/app/utils/addon.utils.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { orderBy, filter } from "lodash";
|
||||
import { Addon } from "../entities/addon";
|
||||
|
||||
export function getAllProviders(addon: Addon) {
|
||||
return orderBy(addon.externalIds, ["providerName"], ["asc"]);
|
||||
}
|
||||
|
||||
export function getProviders(addon: Addon) {
|
||||
return filter(getAllProviders(addon), (extId) => extId.providerName !== addon.providerName);
|
||||
}
|
||||
|
||||
export function hasMultipleProviders(addon: Addon) {
|
||||
return getProviders(addon).length > 0;
|
||||
}
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "Stabil"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Laden..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "Anzeigen auf"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "Okay"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Alpha",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "Automatisch aktualisieren",
|
||||
"BETA_ADDON_CHANNEL": "Beta",
|
||||
"CHANNEL_SUBMENT_TITLE": "Kanal",
|
||||
"CHANNEL_SUBMENU_TITLE": "Kanal",
|
||||
"IGNORE_ADDON_BUTTON": "Ignorieren",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "Neu installieren",
|
||||
"REMOVE_ADDON_BUTTON": "Entfernen",
|
||||
"SHOW_FOLDER": "Dateiordner anzeigen",
|
||||
"STABLE_ADDON_CHANNEL": "Stabil"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Updates prüfen",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Nach neuen Addon-Updates suchen",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "World of Warcraft",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "Stable"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Loading..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "View on"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "Okay"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Alpha",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "Auto Update",
|
||||
"BETA_ADDON_CHANNEL": "Beta",
|
||||
"CHANNEL_SUBMENT_TITLE": "Channel",
|
||||
"CHANNEL_SUBMENU_TITLE": "Channel",
|
||||
"IGNORE_ADDON_BUTTON": "Ignore",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "Re-Install",
|
||||
"REMOVE_ADDON_BUTTON": "Remove",
|
||||
"SHOW_FOLDER": "Show Folder",
|
||||
"STABLE_ADDON_CHANNEL": "Stable"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Check Updates",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Check for latest addon updates",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "World of Warcraft",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "Estable"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Cargando..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "Ver en"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "Aceptar"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Alfa",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "Actualización automática",
|
||||
"BETA_ADDON_CHANNEL": "Beta",
|
||||
"CHANNEL_SUBMENT_TITLE": "Canal",
|
||||
"CHANNEL_SUBMENU_TITLE": "Canal",
|
||||
"IGNORE_ADDON_BUTTON": "Ignorar",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "Reinstalar",
|
||||
"REMOVE_ADDON_BUTTON": "Eliminar",
|
||||
"SHOW_FOLDER": "Mostrar Carpeta",
|
||||
"STABLE_ADDON_CHANNEL": "Estable"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Buscar Actualizaciones",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Busca las últimas actualizaciones de los addons",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "World of Warcraft",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "Stable"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Chargement..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "Voir sur"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "Ok"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Alpha",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "Mise à jour automatique",
|
||||
"BETA_ADDON_CHANNEL": "Bêta",
|
||||
"CHANNEL_SUBMENT_TITLE": "Canal",
|
||||
"CHANNEL_SUBMENU_TITLE": "Canal",
|
||||
"IGNORE_ADDON_BUTTON": "Ignorer",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "Réinstaller",
|
||||
"REMOVE_ADDON_BUTTON": "Désinstaller",
|
||||
"SHOW_FOLDER": "Montrer le dossier",
|
||||
"STABLE_ADDON_CHANNEL": "Stable"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Vérifier les mises à jour",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Vérifier les dernières mises à jour des modules complémentaires",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "World of Warcraft",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "Stabile"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Caricamento in corso..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "Visualizza su"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "Ok"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Alfa",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "Aggiornamento Automatico",
|
||||
"BETA_ADDON_CHANNEL": "Beta",
|
||||
"CHANNEL_SUBMENT_TITLE": "Canale",
|
||||
"CHANNEL_SUBMENU_TITLE": "Canale",
|
||||
"IGNORE_ADDON_BUTTON": "Ignora",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "Reinstalla",
|
||||
"REMOVE_ADDON_BUTTON": "Rimuovi",
|
||||
"SHOW_FOLDER": "Mostra cartella",
|
||||
"STABLE_ADDON_CHANNEL": "Stabile"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Controlla Aggiornamenti",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Controlla gli ultimi aggiornamenti degli addons",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "World of Warcraft",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "안정"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "불러오는 중..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "다음에서 보기: "
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "확인"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "알파",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "자동 업데이트",
|
||||
"BETA_ADDON_CHANNEL": "베타",
|
||||
"CHANNEL_SUBMENT_TITLE": "채널",
|
||||
"CHANNEL_SUBMENU_TITLE": "채널",
|
||||
"IGNORE_ADDON_BUTTON": "관리제외",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "재설치",
|
||||
"REMOVE_ADDON_BUTTON": "삭제",
|
||||
"SHOW_FOLDER": "디렉토리 보기",
|
||||
"STABLE_ADDON_CHANNEL": "안정"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "업데이트 체크",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "최신 애드온 업데이트를 체크",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "월드 오브 워크래프트",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "Stable"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Laster..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "View on"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "Okey"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Alpha",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "Oppdater Automatisk",
|
||||
"BETA_ADDON_CHANNEL": "Beta",
|
||||
"CHANNEL_SUBMENT_TITLE": "Kanal",
|
||||
"CHANNEL_SUBMENU_TITLE": "Kanal",
|
||||
"IGNORE_ADDON_BUTTON": "Ignorer",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "Re-Installer",
|
||||
"REMOVE_ADDON_BUTTON": "Fjern",
|
||||
"SHOW_FOLDER": "Vis Mappe",
|
||||
"STABLE_ADDON_CHANNEL": "Stable"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Finn Oppdateringer",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Finn de siste oppdateringene til utvidelsene dine",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "World of Warcraft",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "Estável"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Carregando..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "View on"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "Ok"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Alfa",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "Atualização Automática",
|
||||
"BETA_ADDON_CHANNEL": "Beta",
|
||||
"CHANNEL_SUBMENT_TITLE": "Canal",
|
||||
"CHANNEL_SUBMENU_TITLE": "Canal",
|
||||
"IGNORE_ADDON_BUTTON": "Ignorar",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "Reinstalar",
|
||||
"REMOVE_ADDON_BUTTON": "Remover",
|
||||
"SHOW_FOLDER": "Mostrar Pasta",
|
||||
"STABLE_ADDON_CHANNEL": "Estável"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Verificar Atualizações",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Verificar atualizações recentes",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "World of Warcraft",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "Стабильная"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Загрузка..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "Посмотреть на"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "Окей"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Альфа",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "Автообновление",
|
||||
"BETA_ADDON_CHANNEL": "Бета",
|
||||
"CHANNEL_SUBMENT_TITLE": "Тип выпуска",
|
||||
"CHANNEL_SUBMENU_TITLE": "Тип выпуска",
|
||||
"IGNORE_ADDON_BUTTON": "Пропускать",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "Переустановить",
|
||||
"REMOVE_ADDON_BUTTON": "Удалить",
|
||||
"SHOW_FOLDER": "Показать папку",
|
||||
"STABLE_ADDON_CHANNEL": "Стабильная"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Проверить обновления",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Проверить наличие последних обновлений модификации",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "World of Warcraft",
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
"STABLE": "稳定版"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "正在加载..."
|
||||
},
|
||||
@@ -92,6 +95,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "在该网站上查看:"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"POSITIVE_BUTTON": "确定"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -156,13 +160,18 @@
|
||||
"ALPHA_ADDON_CHANNEL": "Alpha",
|
||||
"AUTO_UPDATE_ADDON_BUTTON": "自动更新",
|
||||
"BETA_ADDON_CHANNEL": "Beta",
|
||||
"CHANNEL_SUBMENT_TITLE": "更新通道",
|
||||
"CHANNEL_SUBMENU_TITLE": "更新通道",
|
||||
"IGNORE_ADDON_BUTTON": "忽略",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"REINSTALL_ADDON_BUTTON": "重新安装",
|
||||
"REMOVE_ADDON_BUTTON": "删除",
|
||||
"SHOW_FOLDER": "打开文件夹",
|
||||
"STABLE_ADDON_CHANNEL": "稳定版"
|
||||
},
|
||||
"CHANGE_ADDON_PROVIDER_CONFIRMATION": {
|
||||
"MESSAGE": "Do you want to change the addon provider for {addonName} to {providerName}? This operation will uninstall your existing addon and replace it with a copy from the new provider.",
|
||||
"TITLE": "Change Addon Provider?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "检查更新",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "检查最新的插件更新",
|
||||
"CLIENT_TYPE_SELECT_LABEL": "魔兽世界",
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
export const ADDON_PROVIDER_WOWINTERFACE = "WowInterface";
|
||||
export const ADDON_PROVIDER_CURSEFORGE = "Curse";
|
||||
export const ADDON_PROVIDER_TUKUI = "TukUI";
|
||||
|
||||
// IPC CHANNELS
|
||||
export const DOWNLOAD_FILE_CHANNEL = "download-file";
|
||||
export const COPY_DIRECTORY_CHANNEL = "copy-directory";
|
||||
export const CREATE_DIRECTORY_CHANNEL = "create-directory";
|
||||
|
||||
Reference in New Issue
Block a user