mirror of
https://github.com/WowUp/WowUp.git
synced 2026-04-24 07:47:29 -04:00
Merge branch 'develop' into dogo-patch-1
This commit is contained in:
@@ -5,4 +5,8 @@ phases:
|
||||
commands:
|
||||
- echo Install phase...
|
||||
- cd wowup-electron
|
||||
- npm i
|
||||
- npm i
|
||||
build:
|
||||
commands:
|
||||
- echo Build phase...
|
||||
- npm run electron:publish:never
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "wowup",
|
||||
"productName": "WowUp",
|
||||
"version": "2.0.0-beta.18",
|
||||
"version": "2.0.0-beta.19",
|
||||
"description": "Word of Warcraft addon updater",
|
||||
"homepage": "https://wowup.io",
|
||||
"author": {
|
||||
|
||||
@@ -26,6 +26,7 @@ export interface AddonProvider {
|
||||
getById(addonId: string, clientType: WowClientType): Observable<AddonSearchResult>;
|
||||
|
||||
isValidAddonUri(addonUri: URL): boolean;
|
||||
isValidAddonId(addonId: string): boolean;
|
||||
|
||||
onPostInstall(addon: Addon): void;
|
||||
|
||||
|
||||
@@ -342,6 +342,10 @@ export class CurseAddonProvider implements AddonProvider {
|
||||
return addonUri.host && addonUri.host.endsWith("curseforge.com") && addonUri.pathname.startsWith("/wow/addons");
|
||||
}
|
||||
|
||||
isValidAddonId(addonId: string): boolean {
|
||||
return !!addonId && !isNaN(parseInt(addonId, 10));
|
||||
}
|
||||
|
||||
onPostInstall(addon: Addon): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -148,6 +148,10 @@ export class GitHubAddonProvider implements AddonProvider {
|
||||
return addonUri.host && addonUri.host.endsWith("github.com");
|
||||
}
|
||||
|
||||
public isValidAddonId(addonId: string): boolean {
|
||||
return addonId.indexOf("/") !== -1;
|
||||
}
|
||||
|
||||
public onPostInstall(addon: Addon): void {}
|
||||
|
||||
public async scan(
|
||||
|
||||
@@ -108,6 +108,10 @@ export class TukUiAddonProvider implements AddonProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
isValidAddonId(addonId: string): boolean {
|
||||
return !!addonId && !isNaN(parseInt(addonId, 10));
|
||||
}
|
||||
|
||||
onPostInstall(addon: Addon): void {}
|
||||
|
||||
async scan(
|
||||
|
||||
@@ -88,17 +88,21 @@ export class WowInterfaceAddonProvider implements AddonProvider {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
getById(addonId: string, clientType: WowClientType): Observable<AddonSearchResult> {
|
||||
public getById(addonId: string, clientType: WowClientType): Observable<AddonSearchResult> {
|
||||
return from(this._circuitBreaker.fire(addonId)).pipe(
|
||||
map((result) => (result ? this.toAddonSearchResult(result, "") : undefined))
|
||||
);
|
||||
}
|
||||
|
||||
isValidAddonUri(addonUri: URL): boolean {
|
||||
public isValidAddonUri(addonUri: URL): boolean {
|
||||
return addonUri.host && addonUri.host.endsWith("wowinterface.com");
|
||||
}
|
||||
|
||||
onPostInstall(addon: Addon): void {
|
||||
public isValidAddonId(addonId: string): boolean {
|
||||
return !!addonId && !isNaN(parseInt(addonId, 10));
|
||||
}
|
||||
|
||||
public onPostInstall(addon: Addon): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,10 @@ export class WowUpAddonProvider implements AddonProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
isValidAddonId(addonId: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
onPostInstall(addon: Addon): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
</div>
|
||||
<div class="addon-version text-2 row align-items-center" [ngClass]="{ ignored: listItem.isIgnored }">
|
||||
<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 class="auto-update-icon" svgIcon="fas:code-branch"
|
||||
[matTooltip]="'PAGES.MY_ADDONS.MULTIPLE_PROVIDERS_TOOLTIP' | translate">
|
||||
</mat-icon>
|
||||
</div>
|
||||
<div *ngIf="this.listItem.isAutoUpdate === true" class="mr-2">
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
"PAGES.OPTIONS.WOW.CLIENT_TYPE_PATH_LABEL" | translate: { clientTypeName: (clientTypeName | translate) }
|
||||
}}</mat-label>
|
||||
<input matInput disabled [value]="clientLocation" />
|
||||
<button mat-button color="accent" *ngIf="clientLocation" matSuffix mat-icon-button aria-label="Clear"
|
||||
(click)="clearInstallPath()">
|
||||
<mat-icon svgIcon="fas:times"></mat-icon>
|
||||
</button>
|
||||
<mat-hint class="text-2">
|
||||
{{
|
||||
"PAGES.OPTIONS.WOW.CLIENT_TYPE_INPUT_HINT"
|
||||
|
||||
@@ -2,9 +2,12 @@ import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from "@angular
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { MatSelectChange } from "@angular/material/select";
|
||||
import { MatSlideToggleChange } from "@angular/material/slide-toggle";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import * as _ from "lodash";
|
||||
import { map } from "lodash";
|
||||
import * as path from "path";
|
||||
import { Subscription } from "rxjs";
|
||||
import { from, Subscription } from "rxjs";
|
||||
import { switchMap } from "rxjs/operators";
|
||||
import { WowClientType } from "../../models/warcraft/wow-client-type";
|
||||
import { AddonChannelType } from "../../models/wowup/addon-channel-type";
|
||||
import { ElectronService } from "../../services";
|
||||
@@ -12,6 +15,7 @@ import { WarcraftService } from "../../services/warcraft/warcraft.service";
|
||||
import { WowUpService } from "../../services/wowup/wowup.service";
|
||||
import { getEnumList, getEnumName } from "../../utils/enum.utils";
|
||||
import { AlertDialogComponent } from "../alert-dialog/alert-dialog.component";
|
||||
import { ConfirmDialogComponent } from "../confirm-dialog/confirm-dialog.component";
|
||||
|
||||
@Component({
|
||||
selector: "app-wow-client-options",
|
||||
@@ -40,7 +44,8 @@ export class WowClientOptionsComponent implements OnInit, OnDestroy {
|
||||
private _electronService: ElectronService,
|
||||
private _warcraftService: WarcraftService,
|
||||
private _wowupService: WowUpService,
|
||||
private _cdRef: ChangeDetectorRef
|
||||
private _cdRef: ChangeDetectorRef,
|
||||
private _translateService: TranslateService
|
||||
) {
|
||||
this.addonChannelInfos = this.getAddonChannelInfos();
|
||||
|
||||
@@ -75,6 +80,32 @@ export class WowClientOptionsComponent implements OnInit, OnDestroy {
|
||||
this._wowupService.setDefaultAutoUpdate(this.clientType, evt.checked);
|
||||
}
|
||||
|
||||
public async clearInstallPath() {
|
||||
const dialogRef = this._dialog.open(ConfirmDialogComponent, {
|
||||
data: {
|
||||
title: this._translateService.instant("PAGES.OPTIONS.WOW.CLEAR_INSTALL_LOCATION_DIALOG.TITLE"),
|
||||
message: this._translateService.instant("PAGES.OPTIONS.WOW.CLEAR_INSTALL_LOCATION_DIALOG.MESSAGE", {
|
||||
clientName: this._translateService.instant(this.clientTypeName),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
const result = await dialogRef.afterClosed().toPromise();
|
||||
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this._warcraftService.removeWowFolderPath(this.clientType).toPromise();
|
||||
this.clientLocation = "";
|
||||
this._cdRef.detectChanges();
|
||||
console.debug("Remove client location complete");
|
||||
} catch (e) {
|
||||
console.error("Failed to remove location", e);
|
||||
}
|
||||
}
|
||||
|
||||
async onSelectClientPath() {
|
||||
const selectedPath = await this.selectWowClientPath(this.clientType);
|
||||
if (selectedPath) {
|
||||
|
||||
@@ -3,12 +3,17 @@ 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 {
|
||||
ADDON_PROVIDER_CURSEFORGE,
|
||||
ADDON_PROVIDER_TUKUI,
|
||||
ADDON_PROVIDER_WOWINTERFACE,
|
||||
ERROR_ADDON_ALREADY_INSTALLED,
|
||||
} from "common/constants";
|
||||
import * as fs from "fs";
|
||||
import * as _ from "lodash";
|
||||
import * as path from "path";
|
||||
import { forkJoin, from, Observable, Subject } from "rxjs";
|
||||
import { map, mergeMap } from "rxjs/operators";
|
||||
import { filter, first, map, mergeMap, switchMap } from "rxjs/operators";
|
||||
import * as slug from "slug";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { AddonProvider } from "../../addon-providers/addon-provider";
|
||||
@@ -69,6 +74,16 @@ export class AddonService {
|
||||
this._installQueue.pipe(mergeMap((item) => from(this.processInstallQueue(item)), 3)).subscribe((addonName) => {
|
||||
console.log("Install complete", addonName);
|
||||
});
|
||||
|
||||
// Attempt to remove addons for clients that were lost
|
||||
this._warcraftService.installedClientTypes$
|
||||
.pipe(
|
||||
filter((clientTypes) => !!clientTypes),
|
||||
switchMap((clientTypes) => from(this.reconcileOrphanAddons(clientTypes)))
|
||||
)
|
||||
.subscribe(() => {
|
||||
console.debug("reconcileOrphanAddons complete");
|
||||
});
|
||||
}
|
||||
|
||||
public saveAddon(addon: Addon) {
|
||||
@@ -217,7 +232,7 @@ export class AddonService {
|
||||
addonId,
|
||||
onUpdate,
|
||||
completion,
|
||||
originalAddon: originalAddon ? { ...originalAddon } : undefined
|
||||
originalAddon: originalAddon ? { ...originalAddon } : undefined,
|
||||
});
|
||||
|
||||
return promise;
|
||||
@@ -306,8 +321,9 @@ export class AddonService {
|
||||
|
||||
this._addonStorage.set(addon.id, addon);
|
||||
|
||||
const actionLabel = `${getEnumName(WowClientType, addon.clientType)}|${addon.providerName}|${addon.externalId}|${addon.name
|
||||
}`;
|
||||
const actionLabel = `${getEnumName(WowClientType, addon.clientType)}|${addon.providerName}|${addon.externalId}|${
|
||||
addon.name
|
||||
}`;
|
||||
this._analyticsService.trackAction("install-addon", {
|
||||
clientType: getEnumName(WowClientType, addon.clientType),
|
||||
provider: addon.providerName,
|
||||
@@ -486,13 +502,15 @@ export class AddonService {
|
||||
.filter((f) => !!f);
|
||||
}
|
||||
|
||||
public async removeAddon(addon: Addon, removeDependencies: boolean = false) {
|
||||
public async removeAddon(addon: Addon, removeDependencies: boolean = false, removeDirectories: boolean = true) {
|
||||
const installedDirectories = addon.installedFolders?.split(",") ?? [];
|
||||
|
||||
const addonFolderPath = this._warcraftService.getAddonFolderPath(addon.clientType);
|
||||
for (let directory of installedDirectories) {
|
||||
const addonDirectory = path.join(addonFolderPath, directory);
|
||||
await this._fileService.remove(addonDirectory);
|
||||
|
||||
if (removeDirectories) {
|
||||
for (let directory of installedDirectories) {
|
||||
const addonDirectory = path.join(addonFolderPath, directory);
|
||||
await this._fileService.remove(addonDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
this._addonStorage.remove(addon);
|
||||
@@ -647,44 +665,51 @@ export class AddonService {
|
||||
}
|
||||
|
||||
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,
|
||||
});
|
||||
}
|
||||
this.insertExternalId(externalIds, ADDON_PROVIDER_WOWINTERFACE, toc.wowInterfaceId);
|
||||
this.insertExternalId(externalIds, ADDON_PROVIDER_TUKUI, toc.tukUiProjectId);
|
||||
this.insertExternalId(externalIds, ADDON_PROVIDER_CURSEFORGE, toc.curseProjectId);
|
||||
|
||||
//If the addon does not include the current external id add it
|
||||
if (!this.containsOwnExternalId(addon, externalIds)) {
|
||||
externalIds.push({
|
||||
id: addon.externalId,
|
||||
providerName: addon.providerName
|
||||
});
|
||||
this.insertExternalId(externalIds, addon.providerName, addon.externalId);
|
||||
}
|
||||
|
||||
addon.externalIds = externalIds;
|
||||
}
|
||||
|
||||
public insertExternalId(externalIds: AddonExternalId[], providerName: string, addonId?: string) {
|
||||
if (!addonId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const exists =
|
||||
_.findIndex(externalIds, (extId) => extId.id === addonId && extId.providerName === providerName) !== -1;
|
||||
|
||||
if (exists) {
|
||||
console.debug(`External id exists ${providerName}|${addonId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.getProvider(providerName).isValidAddonId(addonId)) {
|
||||
externalIds.push({
|
||||
id: addonId,
|
||||
providerName: providerName,
|
||||
});
|
||||
} else {
|
||||
console.debug(`Invalid provider id ${providerName}|${addonId}`);
|
||||
}
|
||||
}
|
||||
|
||||
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}`);
|
||||
}
|
||||
|
||||
if (this.isInstalled(externalId, clientType)) {
|
||||
throw new Error(ERROR_ADDON_ALREADY_INSTALLED);
|
||||
}
|
||||
|
||||
const externalAddon = await this.getAddon(externalId, providerName, clientType).toPromise();
|
||||
if (!externalAddon) {
|
||||
throw new Error(`External addon not found: ${providerName}|${externalId}`);
|
||||
@@ -693,7 +718,21 @@ export class AddonService {
|
||||
this.saveAddon(externalAddon);
|
||||
await this.installAddon(externalAddon.id, undefined, addon);
|
||||
|
||||
await this.removeAddon(addon, false);
|
||||
await this.removeAddon(addon, false, false);
|
||||
}
|
||||
|
||||
public async reconcileOrphanAddons(installedClientTypes: WowClientType[]) {
|
||||
console.debug("reconcileOrphanAddons", installedClientTypes);
|
||||
const clientTypes = this._warcraftService.getAllClientTypes();
|
||||
const unusedClients = _.difference(clientTypes, installedClientTypes);
|
||||
console.debug("unusedClients", unusedClients);
|
||||
|
||||
for (let clientType of unusedClients) {
|
||||
const addons = this._addonStorage.getAllForClientType(clientType);
|
||||
for (let addon of addons) {
|
||||
await this.removeAddon(addon, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public reconcileExternalIds(newAddon: Addon, oldAddon: Addon) {
|
||||
@@ -701,14 +740,21 @@ export class AddonService {
|
||||
return;
|
||||
}
|
||||
|
||||
oldAddon.externalIds.forEach(oldExtId => {
|
||||
const match = newAddon.externalIds.find(newExtId => newExtId.id === oldExtId.id && newExtId.providerName === oldExtId.providerName);
|
||||
// Ensure all previously existing external ids are brought along during the swap
|
||||
// some addons are not always the same between providers ;)
|
||||
oldAddon.externalIds.forEach((oldExtId) => {
|
||||
const match = newAddon.externalIds.find(
|
||||
(newExtId) => newExtId.id === oldExtId.id && newExtId.providerName === oldExtId.providerName
|
||||
);
|
||||
if (match) {
|
||||
return;
|
||||
}
|
||||
console.log(`Reconciling external id: ${oldExtId.providerName}|${oldExtId.id}`);
|
||||
newAddon.externalIds.push({ ...oldExtId });
|
||||
})
|
||||
});
|
||||
|
||||
// Remove external ids that are not valid that we may have saved previously
|
||||
_.remove(newAddon.externalIds, (extId) => !this.getProvider(extId.providerName).isValidAddonId(extId.id));
|
||||
|
||||
this.saveAddon(newAddon);
|
||||
}
|
||||
@@ -730,9 +776,7 @@ export class AddonService {
|
||||
}
|
||||
|
||||
public async backfillAddons() {
|
||||
const clientTypes = getEnumList<WowClientType>(WowClientType).filter(
|
||||
(clientType) => clientType !== WowClientType.None
|
||||
);
|
||||
const clientTypes = this._warcraftService.getAllClientTypes();
|
||||
|
||||
for (let clientType of clientTypes) {
|
||||
const addons = this._addonStorage.getAllForClientType(clientType);
|
||||
@@ -761,7 +805,7 @@ export class AddonService {
|
||||
|
||||
public containsOwnExternalId(addon: Addon, array?: AddonExternalId[]): boolean {
|
||||
const arr = array || addon.externalIds;
|
||||
const result = arr && !!arr.find(ext => ext.id === addon.externalId && ext.providerName === addon.providerName);
|
||||
const result = arr && !!arr.find((ext) => ext.id === addon.externalId && ext.providerName === addon.providerName);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -819,6 +863,7 @@ export class AddonService {
|
||||
summary: searchResult.summary,
|
||||
screenshotUrls: searchResult.screenshotUrls,
|
||||
dependencies,
|
||||
externalChannel: getEnumName(AddonChannelType, latestFile.channelType),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
import { filter, first, map } from "rxjs/operators";
|
||||
import { first as ldFirst } from "lodash";
|
||||
import { WowClientType } from "../../models/warcraft/wow-client-type";
|
||||
import { WarcraftService } from "../warcraft/warcraft.service";
|
||||
import { WowUpService } from "../wowup/wowup.service";
|
||||
@@ -23,6 +24,22 @@ export class SessionService {
|
||||
|
||||
constructor(private _warcraftService: WarcraftService, private _wowUpService: WowUpService) {
|
||||
this.loadInitialClientType().pipe(first()).subscribe();
|
||||
|
||||
this._warcraftService.installedClientTypes$
|
||||
.pipe(filter((clientTypes) => !!clientTypes))
|
||||
.subscribe((clientTypes) => this.onInstalledClientsChange(clientTypes));
|
||||
}
|
||||
|
||||
public onInstalledClientsChange(installedClientTypes: WowClientType[]) {
|
||||
if (!installedClientTypes.length) {
|
||||
this._selectedClientTypeSrc.next(WowClientType.None);
|
||||
}
|
||||
|
||||
if (installedClientTypes.indexOf(this.selectedClientType) !== -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectedClientType = ldFirst(installedClientTypes);
|
||||
}
|
||||
|
||||
public autoUpdateComplete() {
|
||||
|
||||
@@ -36,4 +36,8 @@ export class PreferenceStorageService {
|
||||
public getObject<T>(key: string): T | undefined {
|
||||
return this._store.get(key, undefined) as T;
|
||||
}
|
||||
|
||||
public remove(key: string): void {
|
||||
this._store.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ export class WarcraftService {
|
||||
private readonly _impl: WarcraftServiceImpl;
|
||||
private readonly _productsSrc = new BehaviorSubject<InstalledProduct[]>([]);
|
||||
private readonly _installedClientTypesSrc = new BehaviorSubject<WowClientType[] | undefined>(undefined);
|
||||
private readonly _allClientTypes = getEnumList<WowClientType>(WowClientType).filter(
|
||||
(clientType) => clientType !== WowClientType.None
|
||||
);
|
||||
|
||||
private _productDbPath = "";
|
||||
|
||||
@@ -108,12 +111,14 @@ export class WarcraftService {
|
||||
return path.join(fullClientPath, INTERFACE_FOLDER_NAME, ADDON_FOLDER_NAME);
|
||||
}
|
||||
|
||||
public getAllClientTypes() {
|
||||
return [...this._allClientTypes];
|
||||
}
|
||||
|
||||
public async getWowClientTypes() {
|
||||
const clients: WowClientType[] = [];
|
||||
|
||||
const clientTypes = getEnumList<WowClientType>(WowClientType).filter(
|
||||
(clientType) => clientType !== WowClientType.None
|
||||
);
|
||||
const clientTypes = this.getAllClientTypes();
|
||||
|
||||
for (let clientType of clientTypes) {
|
||||
const clientLocation = this.getClientLocation(clientType);
|
||||
@@ -142,9 +147,7 @@ export class WarcraftService {
|
||||
const installedProducts = this.decodeProducts(this._productDbPath);
|
||||
this._productsSrc.next(installedProducts);
|
||||
|
||||
const clientTypes = getEnumList<WowClientType>(WowClientType).filter(
|
||||
(clientType) => clientType !== WowClientType.None
|
||||
);
|
||||
const clientTypes = this.getAllClientTypes();
|
||||
|
||||
for (const clientType of clientTypes) {
|
||||
const clientLocation = this.getClientLocation(clientType);
|
||||
@@ -169,6 +172,8 @@ export class WarcraftService {
|
||||
this.setClientLocation(clientType, productLocation);
|
||||
}
|
||||
|
||||
this.broadcastInstalledClients().subscribe();
|
||||
|
||||
return installedProducts;
|
||||
}
|
||||
|
||||
@@ -235,6 +240,13 @@ export class WarcraftService {
|
||||
return this._preferenceStorageService.set(clientLocationKey, clientPath);
|
||||
}
|
||||
|
||||
public removeWowFolderPath(clientType: WowClientType) {
|
||||
const clientLocationKey = this.getClientLocationKey(clientType);
|
||||
this._preferenceStorageService.remove(clientLocationKey);
|
||||
|
||||
return this.broadcastInstalledClients();
|
||||
}
|
||||
|
||||
public setWowFolderPath(clientType: WowClientType, folderPath: string): boolean {
|
||||
const relativePath = this.getClientRelativePath(clientType, folderPath);
|
||||
|
||||
@@ -337,6 +349,12 @@ export class WarcraftService {
|
||||
}
|
||||
}
|
||||
|
||||
private broadcastInstalledClients() {
|
||||
return from(this.getWowClientTypes()).pipe(
|
||||
map((wowClientTypes) => this._installedClientTypesSrc.next(wowClientTypes))
|
||||
);
|
||||
}
|
||||
|
||||
private decodeProducts(productDbPath: string) {
|
||||
if (this._electronService.isLinux) {
|
||||
return [];
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
{
|
||||
"ChangeLogs": [
|
||||
{
|
||||
"Version": "2.0.0-beta.19",
|
||||
"changes": [
|
||||
"Add the ability to clear an installation path",
|
||||
"Add the ability to have addons removed for installations that are missing",
|
||||
"Fix some issues related to switching providers"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Version": "2.0.0-beta.18",
|
||||
"changes": [
|
||||
@@ -9,9 +17,7 @@
|
||||
},
|
||||
{
|
||||
"Version": "2.0.0-beta.17",
|
||||
"changes": [
|
||||
"Bug fixes"
|
||||
]
|
||||
"changes": ["Bug fixes"]
|
||||
},
|
||||
{
|
||||
"Version": "2.0.0-beta.16",
|
||||
@@ -33,10 +39,7 @@
|
||||
},
|
||||
{
|
||||
"Version": "2.0.0-beta.15",
|
||||
"changes": [
|
||||
"Fix an issue where light/dark themes could overlap",
|
||||
"Fix an issue with a nested translate call"
|
||||
]
|
||||
"changes": ["Fix an issue where light/dark themes could overlap", "Fix an issue with a nested translate call"]
|
||||
},
|
||||
{
|
||||
"Version": "2.0.0-beta.14",
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
"THEME": {
|
||||
"ALLIANCE": "Allianz",
|
||||
"DEFAULT": "Standard",
|
||||
"GROUP_DARK": "Dark",
|
||||
"GROUP_LIGHT": "Light",
|
||||
"GROUP_DARK": "Dunkel",
|
||||
"GROUP_LIGHT": "Hell",
|
||||
"HORDE": "Horde"
|
||||
},
|
||||
"WOWUP_UPDATE": {
|
||||
@@ -68,13 +68,13 @@
|
||||
"e+0": "{count}",
|
||||
"e+1": "{count}",
|
||||
"e+2": "{count}",
|
||||
"e+3": "{count} thousand",
|
||||
"e+4": "{count} thousand",
|
||||
"e+5": "{count} thousand",
|
||||
"e+6": "{count} million",
|
||||
"e+7": "{count} million",
|
||||
"e+8": "{count} million",
|
||||
"e+9": "{count} billion"
|
||||
"e+3": "{count} Tausend",
|
||||
"e+4": "{count} Tausend",
|
||||
"e+5": "{count} Tausend",
|
||||
"e+6": "{count} Millionen",
|
||||
"e+7": "{count} Millionen",
|
||||
"e+8": "{count} Millionen",
|
||||
"e+9": "{count} Milliarden"
|
||||
},
|
||||
"ENUM": {
|
||||
"ADDON_CHANNEL_TYPE": {
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
"CHANGE_PROVIDER_ERROR": "Anbieterwechsel von {addonName} nach {providerName} fehlgeschlagen"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Laden..."
|
||||
@@ -168,15 +168,15 @@
|
||||
"BETA_ADDON_CHANNEL": "Beta",
|
||||
"CHANNEL_SUBMENU_TITLE": "Kanal",
|
||||
"IGNORE_ADDON_BUTTON": "Ignorieren",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"PROVIDER_SUBMENU_TITLE": "Anbieter",
|
||||
"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?"
|
||||
"MESSAGE": "Möchtest du den Addon Anbieter für {addonName} auf {providerName} festlegen? Dies wird das aktuelle Addon deinstallieren und durch eine Version vom neuen Anbieter ersetzen.",
|
||||
"TITLE": "Addon Anbieter wechsel?"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Updates prüfen",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Nach neuen Addon-Updates suchen",
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "Spalten anzeigen"
|
||||
},
|
||||
"FILTER_LABEL": "Filter",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count} {count, plural, =1{Addon} other{Addons}}",
|
||||
"JOIN_DISCORD": "Schreibe mit uns auf Discord",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "Neu installierte Addons werden standardmäßig auf Auto-Update gesetzt",
|
||||
"AUTO_UPDATE_LABEL": "Automatisch aktualisieren",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "Der Order, der den {clientTypeName} Clientorder \"{clientFolderName}\" enthält",
|
||||
"CLIENT_TYPE_PATH_LABEL": "{clientTypeName} Pfad",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "Standard-Addon-Kanal",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "Show Columns"
|
||||
},
|
||||
"FILTER_LABEL": "Filter",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count} {count, plural, =1{addon} other{addons}}",
|
||||
"JOIN_DISCORD": "Chat with us on Discord",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "Newly installed addons will be set to auto update by default",
|
||||
"AUTO_UPDATE_LABEL": "Auto Update",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "The folder that contains the {clientTypeName} client folder \"{clientFolderName}\"",
|
||||
"CLIENT_TYPE_PATH_LABEL": "{clientTypeName} path",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "Default Addon Channel",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "Mostrar Columna"
|
||||
},
|
||||
"FILTER_LABEL": "Filtro",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count} {count, plural, =1{addon} other{addons}}",
|
||||
"JOIN_DISCORD": "Charle con nosotros en Discord",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "Los addons instalados después de activar esta opción se configurarán para actualizarse automáticamente de forma predeterminada",
|
||||
"AUTO_UPDATE_LABEL": "Actualización automática",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "La carpeta que contiene la versión {clientTypeName} del cliente de World of Warcraft \"{clientFolderName}\"",
|
||||
"CLIENT_TYPE_PATH_LABEL": "Ruta de {clientTypeName}",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "Canal de Addons Predeterminado",
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
"THEME": {
|
||||
"ALLIANCE": "Alliance",
|
||||
"DEFAULT": "Défaut",
|
||||
"GROUP_DARK": "Dark",
|
||||
"GROUP_LIGHT": "Light",
|
||||
"GROUP_DARK": "Sombre",
|
||||
"GROUP_LIGHT": "Clair",
|
||||
"HORDE": "Horde"
|
||||
},
|
||||
"WOWUP_UPDATE": {
|
||||
@@ -48,9 +48,9 @@
|
||||
"CLIENT_TYPES": {
|
||||
"BETA": "Beta",
|
||||
"CLASSIC": "Classic",
|
||||
"CLASSICPTR": "Classic PTR",
|
||||
"CLASSICPTR": "PTR Classic",
|
||||
"RETAIL": "Retail",
|
||||
"RETAILPTR": "Retail PTR"
|
||||
"RETAILPTR": "PTR Retail"
|
||||
},
|
||||
"DATES": {
|
||||
"DATETIME_SHORT": "{d, date, short} {d, time, short}",
|
||||
@@ -68,13 +68,13 @@
|
||||
"e+0": "{count}",
|
||||
"e+1": "{count}",
|
||||
"e+2": "{count}",
|
||||
"e+3": "{count} thousand",
|
||||
"e+4": "{count} thousand",
|
||||
"e+5": "{count} thousand",
|
||||
"e+6": "{count} million",
|
||||
"e+7": "{count} million",
|
||||
"e+8": "{count} million",
|
||||
"e+9": "{count} billion"
|
||||
"e+3": "{count} {count, plural, one{millier} other{{count} milliers}}",
|
||||
"e+4": "{count} milliers",
|
||||
"e+5": "{count} milliers",
|
||||
"e+6": "{count} {count, plural, one{million} other{{count} millions}} ",
|
||||
"e+7": "{count} millions",
|
||||
"e+8": "{count} millions",
|
||||
"e+9": "{count} {count, plural, one{milliard} other{{count} milliards}} "
|
||||
},
|
||||
"ENUM": {
|
||||
"ADDON_CHANNEL_TYPE": {
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
"CHANGE_PROVIDER_ERROR": "Impossible de changer le fournisseur {providerName} pour l´addon {addonName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Chargement..."
|
||||
@@ -101,7 +101,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "Voir sur"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"ERROR_TITLE": "Erreur",
|
||||
"POSITIVE_BUTTON": "Ok"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -168,15 +168,15 @@
|
||||
"BETA_ADDON_CHANNEL": "Bêta",
|
||||
"CHANNEL_SUBMENU_TITLE": "Canal",
|
||||
"IGNORE_ADDON_BUTTON": "Ignorer",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"PROVIDER_SUBMENU_TITLE": "Fournisseurs",
|
||||
"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?"
|
||||
"MESSAGE": "Souhaitez-vous changer le fournisseur d´addons pour {addonName} par {providerName}? Cette opération désinstallera l´addon existant et le remplacera par une copie du nouveau fournisseur.",
|
||||
"TITLE": "Changer de fournisseur d´addon"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Vérifier les mises à jour",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Vérifier les dernières mises à jour des modules complémentaires",
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "Afficher les colonnes"
|
||||
},
|
||||
"FILTER_LABEL": "Filter",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count} {count, plural, =1{addon} other{addons}}",
|
||||
"JOIN_DISCORD": "Discutez avec nous sur Discord",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "Les addons nouvellement installés seront mises à jour automatiquement par défaut",
|
||||
"AUTO_UPDATE_LABEL": "Mise à jour automatique",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "Ce dossier contient le client {clientTypeName} avec le dossier \"{clientFolderName}\"",
|
||||
"CLIENT_TYPE_PATH_LABEL": "Chemin de {clientTypeName}",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "Canal d'extension par défaut",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"APP": {
|
||||
"AUTO_UPDATE_NOTIFICATION_BODY": "Automaticamente {count, plural, =1{aggiornato} other{aggiornati}} {count} {count, plural, =1{addon} other{addons}}.",
|
||||
"AUTO_UPDATE_NOTIFICATION_TITLE": "Aggiornamenti automatici",
|
||||
"AUTO_UPDATE_NOTIFICATION_TITLE": "Aggiornamenti Automatici",
|
||||
"SYSTEM_TRAY": {
|
||||
"CHECK_UPDATE": "Controlla Aggiornamenti...",
|
||||
"QUIT_ACTION": "Chiudi",
|
||||
@@ -10,21 +10,21 @@
|
||||
"THEME": {
|
||||
"ALLIANCE": "Alleanza",
|
||||
"DEFAULT": "Default",
|
||||
"GROUP_DARK": "Dark",
|
||||
"GROUP_LIGHT": "Light",
|
||||
"GROUP_DARK": "Scuro",
|
||||
"GROUP_LIGHT": "Chiaro",
|
||||
"HORDE": "Orda"
|
||||
},
|
||||
"WOWUP_UPDATE": {
|
||||
"DOWNLOADED_TOOLTIP": "Installa l'aggiornamento di WowUp",
|
||||
"INSTALL_MESSAGE": "Vuoi riavviare WowUp per installare l'aggiornamento?",
|
||||
"INSTALL_TITLE": "Aggiornamento di Wowup pronto",
|
||||
"NOT_AVAILABLE": "L'ultima versione di Wowup è già installata",
|
||||
"NOT_AVAILABLE": "È già installata l'ultima versione di Wowup",
|
||||
"PORTABLE_DOWNLOAD_MESSAGE": "Vuoi scaricare manualmente l'ultima versione portatile?\n\nDovrai chiudere l'applicazione manualmente e sovrascrivere la nuova versione.",
|
||||
"PORTABLE_DOWNLOAD_TITLE": "Richiesto Download Manuale",
|
||||
"SNACKBAR_ACTION": "Aggiorna",
|
||||
"SNACKBAR_TEXT": "È disponibile una nuova versione di WowUp",
|
||||
"TOOLTIP": "L'aggiornamento di WowUp è pronto per l'installazione",
|
||||
"UPDATE_ERROR": "Errore nell'ottenere l'ultima versione di Wowup"
|
||||
"TOOLTIP": "Aggiornamento di WowUp disponibile",
|
||||
"UPDATE_ERROR": "Fallito nell'ottenere l'ultima versione di Wowup"
|
||||
}
|
||||
},
|
||||
"COMMON": {
|
||||
@@ -57,8 +57,8 @@
|
||||
"DAYS_AGO": "{count} {count, plural, one{giorno} other{giorni}} fa",
|
||||
"HOURS_AGO": "{count} {count, plural, one{ora} other{ore}} fa",
|
||||
"JUST_NOW": "Ora",
|
||||
"MONTHS_AGO": "{count} {count, plural, one{month} other{months}} ago",
|
||||
"YEARS_AGO": "{count} {count, plural, one{year} other{years}} ago",
|
||||
"MONTHS_AGO": "{count} {count, plural, one{mese} other{mesi}} fa",
|
||||
"YEARS_AGO": "{count} {count, plural, one{mese} other{mesi}} fa",
|
||||
"YESTERDAY": "Ieri"
|
||||
},
|
||||
"DEPENDENCY": {
|
||||
@@ -68,13 +68,13 @@
|
||||
"e+0": "{count}",
|
||||
"e+1": "{count}",
|
||||
"e+2": "{count}",
|
||||
"e+3": "{count} thousand",
|
||||
"e+4": "{count} thousand",
|
||||
"e+5": "{count} thousand",
|
||||
"e+6": "{count} million",
|
||||
"e+7": "{count} million",
|
||||
"e+8": "{count} million",
|
||||
"e+9": "{count} billion"
|
||||
"e+3": "{count} {count, plural, one{mille} other{{count} mila}}",
|
||||
"e+4": "{count} {count, plural, one{mille} other{{count} mila}}",
|
||||
"e+5": "{count} {count, plural, one{mille} other{{count} mila}}",
|
||||
"e+6": "{count} {count, plural, one{milione} other{milioni}}",
|
||||
"e+7": "{count} {count, plural, one{milione} other{milioni}}",
|
||||
"e+8": "{count} {count, plural, one{milione} other{milioni}}",
|
||||
"e+9": "{count} {count, plural, one{bilione} other{bilioni}}"
|
||||
},
|
||||
"ENUM": {
|
||||
"ADDON_CHANNEL_TYPE": {
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
"CHANGE_PROVIDER_ERROR": "Failed to change provider for {addonName} to {providerName}"
|
||||
"CHANGE_PROVIDER_ERROR": "Fallito nel cambiare provider per {addonName} con {providerName}"
|
||||
},
|
||||
"PROGRESS_SPINNER": {
|
||||
"LOADING": "Caricamento in corso..."
|
||||
@@ -101,7 +101,7 @@
|
||||
"VIEW_ON_PROVIDER_PREFIX": "Visualizza su"
|
||||
},
|
||||
"ALERT": {
|
||||
"ERROR_TITLE": "Error",
|
||||
"ERROR_TITLE": "Errore",
|
||||
"POSITIVE_BUTTON": "Ok"
|
||||
},
|
||||
"CONFIRM": {
|
||||
@@ -113,7 +113,7 @@
|
||||
"ADDON_URL_INPUT_PLACEHOLDER": "URL di esempio GitHub o WowInterface",
|
||||
"CLOSE_BUTTON": "Chiudi",
|
||||
"DESCRIPTION": "Se si desidera installare un addon direttamente da un URL incollarlo qui sotto per iniziare.",
|
||||
"DOWNLOAD_COUNT": "{textCount} {count, plural, one{download} other{downloads}} on {provider}",
|
||||
"DOWNLOAD_COUNT": "{textCount} {count, plural, one{download} other{downloads}} su {provider}",
|
||||
"ERROR": {
|
||||
"FAILED_TO_CONNECT": "Impossibile connettersi all'API, per favore riprovare più tardi.",
|
||||
"INSTALL_FAILED": "Qualcosa è andato storto nell'installazione dell'addon, per favore riprovare.\n\nSe questo messaggio continua ad apparire puoi chiederci aiuto su Discord, in #wow-support channel.",
|
||||
@@ -175,8 +175,8 @@
|
||||
"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?"
|
||||
"MESSAGE": "Vuoi cambiare il provider dell'addon {addonName} con {providerName}? Questa operazione disinstallerà il tuo addon esistente e lo sostituirà con una copia dal nuovo provider.",
|
||||
"TITLE": "Cambiare Provider dell'Addon??"
|
||||
},
|
||||
"CHECK_UPDATES_BUTTON": "Controlla Aggiornamenti",
|
||||
"CHECK_UPDATES_BUTTON_TOOLTIP": "Controlla gli ultimi aggiornamenti degli addons",
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "Mostra Colonne"
|
||||
},
|
||||
"FILTER_LABEL": "Filtra",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count} {count, plural, =1{addon} other{addons}}",
|
||||
"JOIN_DISCORD": "Contattaci su Discord",
|
||||
@@ -206,7 +207,7 @@
|
||||
"ADDON_COLUMN_HEADER": "Addon",
|
||||
"ADDON_INSTALL_BUTTON": "Installa",
|
||||
"ADDON_UPDATE_BUTTON": "Aggiorna",
|
||||
"AUTHOR_COLUMN_HEADER": "Autore",
|
||||
"AUTHOR_COLUMN_HEADER": "Autore/i",
|
||||
"AUTO_UPDATE_ICON_TOOLTIP": "Aggiornamento automatico abilitato",
|
||||
"GAME_VERSION_COLUMN_HEADER": "Versione Del Gioco",
|
||||
"LATEST_VERSION_COLUMN_HEADER": "Ultima Versione",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "I nuovi addons installati saranno impostati di default per l'aggiornamento automatico ",
|
||||
"AUTO_UPDATE_LABEL": "Aggiornamento Automatico",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "La cartella che contiene {clientTypeName}: \"{clientFolderName}\"",
|
||||
"CLIENT_TYPE_PATH_LABEL": "{clientTypeName} path",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "Canale Addon Predefinito",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "컬럼 보기"
|
||||
},
|
||||
"FILTER_LABEL": "필터",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count}개의 애드온",
|
||||
"JOIN_DISCORD": "디스코드 입장",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "새로 설치되는 애드온의 자동업데이트 옵션을 활성화합니다.",
|
||||
"AUTO_UPDATE_LABEL": "자동 업데이트",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "\"{clientFolderName}\" 디렉토리를 포함하는 위치",
|
||||
"CLIENT_TYPE_PATH_LABEL": "{clientTypeName} 설치 위치",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "기본 애드온 채널",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "Vis Kolonner"
|
||||
},
|
||||
"FILTER_LABEL": "Filter",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count} {count, plural, =1{utvidelse} other{utvidelser}}",
|
||||
"JOIN_DISCORD": "Chat med oss på Discord",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "Nye utvidelser du installerer vil bli satt til å oppdateres automatisk",
|
||||
"AUTO_UPDATE_LABEL": "Automatisk Oppdatering",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "Mappen som inneholder {clientTypeName} klientmappe \"{clientFolderName}\"",
|
||||
"CLIENT_TYPE_PATH_LABEL": "{clientTypeName} filbane",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "Standard kanal for utvidelser",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "Exibir Colunas"
|
||||
},
|
||||
"FILTER_LABEL": "Filtrar",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count} {count, plural, =1{Addon} other{Addons}}",
|
||||
"JOIN_DISCORD": "Converse conosco no Discord",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "Addons recém-instalados serão definidos para atualizar automáticamente por padrão",
|
||||
"AUTO_UPDATE_LABEL": "Atualização Automática",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "A pasta \"{clientFolderName}\" que contém o {clientTypeName}",
|
||||
"CLIENT_TYPE_PATH_LABEL": "Pasta {clientTypeName}",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "Canal de Addon Padrão",
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
"BETA_ADDON_CHANNEL": "Бета",
|
||||
"CHANNEL_SUBMENU_TITLE": "Тип выпуска",
|
||||
"IGNORE_ADDON_BUTTON": "Пропускать",
|
||||
"PROVIDER_SUBMENU_TITLE": "Providers",
|
||||
"PROVIDER_SUBMENU_TITLE": "Источники",
|
||||
"REINSTALL_ADDON_BUTTON": "Переустановить",
|
||||
"REMOVE_ADDON_BUTTON": "Удалить",
|
||||
"SHOW_FOLDER": "Показать папку",
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "Показать колонки"
|
||||
},
|
||||
"FILTER_LABEL": "Фильтр",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "{count} {count, plural, one{модификация} few{модификации} other{модификаций}}",
|
||||
"JOIN_DISCORD": "Общайтесь с нами в Discord",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "Новые установленные модификации будут автоматически обновляться по умолчанию",
|
||||
"AUTO_UPDATE_LABEL": "Автообновление",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "Папка которая содержит папку клиента {clientTypeName} – \"{clientFolderName}\"",
|
||||
"CLIENT_TYPE_PATH_LABEL": "Путь для {clientTypeName}",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "Тип выпуска модификации по умолчанию",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "顯示列表項"
|
||||
},
|
||||
"FILTER_LABEL": "篩選",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "共 {count} 個插件",
|
||||
"JOIN_DISCORD": "在 Discord 上與我們交流(英語)",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "新安裝的插件將預設設定為自動更新",
|
||||
"AUTO_UPDATE_LABEL": "自動更新",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "請選擇 {clientTypeName} 客戶端路徑(\"{clientFolderName}\" 的上級路徑)",
|
||||
"CLIENT_TYPE_PATH_LABEL": "{clientTypeName} 路徑",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "預設插件更新通道",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"TITLE": "显示列表项"
|
||||
},
|
||||
"FILTER_LABEL": "筛选",
|
||||
"MULTIPLE_PROVIDERS_TOOLTIP": "This addon has multiple providers",
|
||||
"PAGE_CONTEXT_FOOTER": {
|
||||
"ADDONS_INSTALLED": "共 {count} 个插件",
|
||||
"JOIN_DISCORD": "在 Discord 上与我们交流(英语)",
|
||||
@@ -276,6 +277,10 @@
|
||||
"WOW": {
|
||||
"AUTO_UPDATE_DESCRIPTION": "新安装的插件将默认设置为自动更新",
|
||||
"AUTO_UPDATE_LABEL": "自动更新",
|
||||
"CLEAR_INSTALL_LOCATION_DIALOG": {
|
||||
"MESSAGE": "Are you sure you want to clear the install path for {clientName}? This will remove all stored addon information for this client.\n\nYour addon folders will not be removed.",
|
||||
"TITLE": "Clear Install Location?"
|
||||
},
|
||||
"CLIENT_TYPE_INPUT_HINT": "请选择 {clientTypeName} 客户端路径(\"{clientFolderName}\" 的上级路径)",
|
||||
"CLIENT_TYPE_PATH_LABEL": "{clientTypeName} 路径",
|
||||
"DEFAULT_ADDON_CHANNEL_LABEL": "默认插件更新通道",
|
||||
|
||||
@@ -61,3 +61,6 @@ export const ALLIANCE_THEME = "alliance-theme";
|
||||
export const ALLIANCE_LIGHT_THEME = "alliance-theme-light-theme";
|
||||
export const DEFAULT_BG_COLOR = "#444444";
|
||||
export const DEFAULT_LIGHT_BG_COLOR = "#ebedef";
|
||||
|
||||
// ERRORS
|
||||
export const ERROR_ADDON_ALREADY_INSTALLED = "ERROR_ADDON_ALREADY_INSTALLED"
|
||||
|
||||
Reference in New Issue
Block a user