mirror of
https://github.com/WowUp/WowUp.git
synced 2026-04-23 07:17:00 -04:00
Fix grid related bugs
Stop using deprecated table restore code for sorting Tweak cell padding for my addons Add more standard logging Add timing and response code logging for http calls
This commit is contained in:
@@ -116,6 +116,7 @@ export function initializeIpcHandlers(window: BrowserWindow): void {
|
||||
handle(
|
||||
IPC_CREATE_DIRECTORY_CHANNEL,
|
||||
async (evt, directoryPath: string): Promise<boolean> => {
|
||||
log.info(`[CreateDirectory] '${directoryPath}'`);
|
||||
await fs.ensureDir(directoryPath);
|
||||
return true;
|
||||
}
|
||||
@@ -304,12 +305,14 @@ export function initializeIpcHandlers(window: BrowserWindow): void {
|
||||
handle(
|
||||
IPC_COPY_FILE_CHANNEL,
|
||||
async (evt, arg: CopyFileRequest): Promise<boolean> => {
|
||||
log.info(`[FileCopy] '${arg.sourceFilePath}' -> '${arg.destinationFilePath}'`);
|
||||
await fs.copy(arg.sourceFilePath, arg.destinationFilePath);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
handle(IPC_DELETE_DIRECTORY_CHANNEL, async (evt, filePath: string) => {
|
||||
log.info(`[FileRemove] ${filePath}`);
|
||||
await fs.remove(filePath);
|
||||
|
||||
return true;
|
||||
@@ -361,11 +364,13 @@ export function initializeIpcHandlers(window: BrowserWindow): void {
|
||||
});
|
||||
|
||||
handle(IPC_RESTART_APP, () => {
|
||||
log.info(`[RestartApp]`);
|
||||
app.relaunch();
|
||||
app.quit();
|
||||
});
|
||||
|
||||
handle(IPC_QUIT_APP, () => {
|
||||
log.info(`[QuitApp]`);
|
||||
app.quit();
|
||||
});
|
||||
|
||||
@@ -391,6 +396,7 @@ export function initializeIpcHandlers(window: BrowserWindow): void {
|
||||
async function handleDownloadFile(arg: DownloadRequest) {
|
||||
try {
|
||||
const savePath = path.join(arg.outputFolder, arg.fileName);
|
||||
log.info(`[DownloadFile] '${arg.url}' -> '${savePath}'`);
|
||||
|
||||
const { data, headers } = await axios({
|
||||
url: arg.url,
|
||||
|
||||
@@ -172,7 +172,7 @@ export class WowUpAddonProvider extends AddonProvider {
|
||||
console.timeEnd("WowUpScan");
|
||||
|
||||
const fingerprints = scanResults.map((result) => result.fingerprint);
|
||||
console.log("fingerprintRequest", JSON.stringify(fingerprints));
|
||||
console.log("[WowUpFingerprints]", JSON.stringify(fingerprints));
|
||||
const fingerprintResponse = await this.getAddonsByFingerprints(fingerprints);
|
||||
|
||||
for (const scanResult of scanResults) {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="cell-container" [style.height]="'65px'">
|
||||
<div class="cell-container">
|
||||
<span class="cell-wrap">{{params.value}}</span>
|
||||
</div>
|
||||
@@ -1,4 +1,4 @@
|
||||
<footer class="bg-secondary-5 text-light-2">
|
||||
<footer class="bg-secondary-4 text-light-2">
|
||||
<a appExternalLink class="patreon-link hover-bg-secondary-2 mr-2" href="https://www.patreon.com/jliddev"
|
||||
matTooltip="{{ 'PAGES.MY_ADDONS.PAGE_CONTEXT_FOOTER.PATREON_SUPPORT' | translate }}">
|
||||
<img class="patron-img" src="assets/images/patreon_logo_small.png" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div style="padding: 4px 0;">
|
||||
<div class="addon-column row align-items-center" style="min-height: 52px;">
|
||||
<div>
|
||||
<div class="addon-column row align-items-center">
|
||||
<div class="thumbnail-container">
|
||||
<div *ngIf="listItem.hasThumbnail === true" class="addon-logo-container bg-secondary-3">
|
||||
<img [src]="listItem.addon.thumbnailUrl" loading="lazy" />
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
}
|
||||
|
||||
.addon-column {
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
padding-top: 0.6em;
|
||||
padding-bottom: 0.6em;
|
||||
|
||||
.thumbnail-container {
|
||||
margin-right: 11px;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
|
||||
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from "@angular/common/http";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { tap } from "rxjs/operators";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
@@ -10,16 +11,27 @@ export class DefaultHeadersInterceptor implements HttpInterceptor {
|
||||
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
// Get the auth token from the service.
|
||||
|
||||
console.log(`[${req.method}] ${req.urlWithParams}`);
|
||||
// Clone the request and replace the original headers with
|
||||
// cloned headers, updated with the authorization.
|
||||
// const authReq = req.clone({
|
||||
// setHeaders: {
|
||||
// // 'user-agent': USER_AGENT
|
||||
// },
|
||||
// const cloneReq = req.clone({
|
||||
// headers: req.headers.set("startTimestamp", Date.now().toString()),
|
||||
// });
|
||||
const start = Date.now();
|
||||
const method = req.method;
|
||||
const url = req.urlWithParams;
|
||||
|
||||
// send cloned request with header to the next handler.
|
||||
return next.handle(req);
|
||||
return next.handle(req).pipe(
|
||||
tap((response: any) => {
|
||||
try {
|
||||
if (response instanceof HttpResponse) {
|
||||
const t = Date.now() - start;
|
||||
console.log(`[${method}] ${url} ${response.status} ${t}ms`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
<!-- MULTI ADDON CONTEXT MENU -->
|
||||
<div style="visibility: hidden; position: fixed" #addonMultiContextMenuTrigger="matMenuTrigger"
|
||||
[style.left]="contextMenuPosition.x" [style.top]="contextMenuPosition.y" [matMenuTriggerFor]="multiContextMenu"></div>
|
||||
<mat-menu #multiContextMenu="matMenu" class="addon-context-menu bg-secondary-4">
|
||||
<mat-menu #multiContextMenu="matMenu" class="addon-context-menu bg-secondary-4 text-1">
|
||||
<ng-template matMenuContent let-listItems="listItems">
|
||||
<div class="addon-context-menu-header" translate [translateParams]="{ count: listItems.length }">
|
||||
PAGES.MY_ADDONS.ADDON_CONTEXT_MENU.ADDONS_SELECTED
|
||||
|
||||
@@ -68,6 +68,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
private isSelectedTab = false;
|
||||
private _lazyLoaded = false;
|
||||
private _isRefreshing = false;
|
||||
private _baseRowData: AddonViewModel[] = [];
|
||||
|
||||
public readonly operationError$ = this._operationErrorSrc.asObservable();
|
||||
|
||||
@@ -159,11 +160,11 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
}
|
||||
|
||||
public get enableUpdateAll(): boolean {
|
||||
return _.some(this.rowData, (row) => AddonUtils.needsUpdate(row.addon));
|
||||
return _.some(this._baseRowData, (row) => AddonUtils.needsUpdate(row.addon));
|
||||
}
|
||||
|
||||
public get hasData(): boolean {
|
||||
return this.rowData.length > 0;
|
||||
return this._baseRowData.length > 0;
|
||||
}
|
||||
|
||||
public constructor(
|
||||
@@ -185,7 +186,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
this.wowInstallations$ = warcraftInstallationService.wowInstallations$;
|
||||
|
||||
// When the search input changes debounce it a little before searching
|
||||
const filterInputSub = this.filterInput$.pipe(debounceTime(200), distinctUntilChanged()).subscribe(() => {
|
||||
const filterInputSub = this.filterInput$.pipe(debounceTime(200)).subscribe(() => {
|
||||
this.filterAddons();
|
||||
});
|
||||
|
||||
@@ -241,14 +242,14 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
}
|
||||
|
||||
public onSortChanged(evt: SortChangedEvent): void {
|
||||
const sortModel = this.gridApi.getSortModel();
|
||||
console.debug("onSortChanged", sortModel);
|
||||
this.wowUpService.setMyAddonsSortOrder(sortModel);
|
||||
}
|
||||
|
||||
public onColumnVisible(evt: ColumnVisibleEvent): void {
|
||||
const columnState = evt.columnApi.getColumnState();
|
||||
console.log("columnVisible", columnState);
|
||||
const minmialState = columnState.map((column) => {
|
||||
return {
|
||||
colId: column.colId,
|
||||
sort: column.sort,
|
||||
};
|
||||
});
|
||||
this.wowUpService.setMyAddonsSortOrder(minmialState);
|
||||
}
|
||||
|
||||
public onRowDataChanged(): void {
|
||||
@@ -273,9 +274,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
this.loadSortOrder();
|
||||
|
||||
this.rowDataChange$.pipe(debounceTime(50)).subscribe(() => {
|
||||
this.gridApi.redrawRows();
|
||||
this.gridApi.resetRowHeights();
|
||||
this._cdRef.detectChanges();
|
||||
this.redrawRows();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -297,7 +296,12 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
}
|
||||
|
||||
this.setPageContextText();
|
||||
this.lazyLoad().catch((e) => console.error(e));
|
||||
this.lazyLoad()
|
||||
.then(() => {
|
||||
this.redrawRows();
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
// window.setTimeout(() => {}, 50);
|
||||
};
|
||||
|
||||
// Get the translated value of the provider name (unknown)
|
||||
@@ -386,25 +390,26 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
return listItem.addon.warningType === undefined && this.addonService.canReinstall(listItem.addon);
|
||||
}
|
||||
|
||||
/** Handle when the user enters new text into the filter box */
|
||||
public filterAddons(): void {
|
||||
const filter = this.filter.trim().toLowerCase();
|
||||
const filtered = _.filter(this.rowData, (row) => this.filterListItem(row, filter));
|
||||
if (this.filter.length === 0) {
|
||||
this.rowData = this._baseRowData;
|
||||
this._cdRef.detectChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
this.gridApi.setRowData(filtered);
|
||||
// this.gridApi.setFilterModel({
|
||||
// name: {
|
||||
// filterType: "text",
|
||||
// type: "contains",
|
||||
// filter,
|
||||
// },
|
||||
// });
|
||||
// this.dataSource.filter = this.filter.trim().toLowerCase();
|
||||
const filter = this.filter.trim().toLowerCase();
|
||||
const filtered = _.filter(this._baseRowData, (row) => this.filterListItem(row, filter));
|
||||
|
||||
this.rowData = filtered;
|
||||
|
||||
this._cdRef.detectChanges();
|
||||
}
|
||||
|
||||
/** Handle when the user clicks the clear button on the filter input box */
|
||||
public onClearFilter(): void {
|
||||
this.filter = "";
|
||||
this.gridApi.setRowData(this.rowData);
|
||||
// this.gridApi.setFilterModel(null);
|
||||
this.filterInput$.next(this.filter);
|
||||
}
|
||||
|
||||
// TODO change this to rely on addon service now view models
|
||||
@@ -517,7 +522,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
this.gridColumnApi.setColumnVisible(column.name, event.checked);
|
||||
|
||||
if (column.name === "latestVersion") {
|
||||
const updates = [...this.rowData];
|
||||
const updates = [...this._baseRowData];
|
||||
updates.forEach((update) => (update.showUpdate = !event.checked));
|
||||
this.rowData = updates;
|
||||
}
|
||||
@@ -642,7 +647,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
|
||||
public onClickIgnoreAddons(listItems: AddonViewModel[]): void {
|
||||
const isIgnored = _.every(listItems, (listItem) => listItem.addon.isIgnored === false);
|
||||
const rows = [...this.rowData];
|
||||
const rows = [...this._baseRowData];
|
||||
try {
|
||||
for (const listItem of listItems) {
|
||||
const row = _.find(rows, (r) => r.addon.id === listItem.addon.id);
|
||||
@@ -671,7 +676,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
|
||||
public onClickAutoUpdateAddons(listItems: AddonViewModel[]): void {
|
||||
const isAutoUpdate = _.every(listItems, (listItem) => listItem.addon.autoUpdateEnabled === false);
|
||||
const rows = [...this.rowData];
|
||||
const rows = [...this._baseRowData];
|
||||
try {
|
||||
for (const listItem of listItems) {
|
||||
const row = _.find(rows, (r) => r.addon.id === listItem.addon.id);
|
||||
@@ -886,7 +891,8 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
return;
|
||||
}
|
||||
|
||||
this.rowData = [];
|
||||
this.rowData = this._baseRowData = [];
|
||||
this._cdRef.detectChanges();
|
||||
|
||||
try {
|
||||
const addons = await this.addonService.getAddons(installation, reScan);
|
||||
@@ -894,7 +900,8 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
const rowData = this.formatAddons(addons);
|
||||
this.enableControls = this.calculateControlState();
|
||||
|
||||
this.rowData = rowData;
|
||||
this._baseRowData = rowData;
|
||||
this.rowData = this._baseRowData;
|
||||
|
||||
this.isBusy = false;
|
||||
this.setPageContextText();
|
||||
@@ -994,11 +1001,17 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
|
||||
// Reorder everything by name to act as a sub-sort
|
||||
this.rowData = _.orderBy(rows, (row) => row.addon.name);
|
||||
this.gridApi.setRowData(this.rowData);
|
||||
|
||||
// Force the grid to redraw whatever row needs updated
|
||||
const rowNode = this.gridApi.getRowNode(evt.addon.id);
|
||||
this.gridApi.redrawRows({ rowNodes: [rowNode] });
|
||||
// If the user is currently filtering the table, use that.
|
||||
// if (this.filter) {
|
||||
// this.filterAddons();
|
||||
// } else {
|
||||
// this.gridApi.setRowData(this.rowData);
|
||||
|
||||
// // Force the grid to redraw whatever row needs updated
|
||||
// const rowNode = this.gridApi.getRowNode(evt.addon.id);
|
||||
// this.gridApi.redrawRows({ rowNodes: [rowNode] });
|
||||
// }
|
||||
|
||||
this.enableControls = this.calculateControlState();
|
||||
} finally {
|
||||
@@ -1024,17 +1037,23 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
|
||||
private loadSortOrder() {
|
||||
let savedSortOrder = this.wowUpService.getMyAddonsSortOrder();
|
||||
if (!Array.isArray(savedSortOrder)) {
|
||||
if (!Array.isArray(savedSortOrder) || savedSortOrder.length < 2) {
|
||||
console.info(`Legacy or missing sort order fixed`);
|
||||
this.wowUpService.setMyAddonsSortOrder([]);
|
||||
savedSortOrder = [];
|
||||
}
|
||||
|
||||
if (savedSortOrder.length > 0) {
|
||||
this.gridApi.setSortModel(savedSortOrder);
|
||||
this.gridColumnApi.setColumnState(savedSortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
private redrawRows() {
|
||||
this.gridApi?.redrawRows();
|
||||
this.gridApi?.resetRowHeights();
|
||||
this._cdRef.detectChanges();
|
||||
}
|
||||
|
||||
private createColumns(): ColDef[] {
|
||||
const baseColumn = {
|
||||
headerComponent: "contextHeader",
|
||||
@@ -1042,7 +1061,9 @@ export class MyAddonsComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
onHeaderContext: this.onHeaderContext,
|
||||
},
|
||||
cellStyle: {
|
||||
lineHeight: "65px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import { WarcraftInstallationService } from "../warcraft/warcraft-installation.s
|
||||
import { WarcraftService } from "../warcraft/warcraft.service";
|
||||
import { WowUpService } from "../wowup/wowup.service";
|
||||
import { AddonProviderFactory } from "./addon.provider.factory";
|
||||
import { capitalizeString } from "app/utils/string.utils";
|
||||
|
||||
export enum ScanUpdateType {
|
||||
Start,
|
||||
@@ -143,7 +144,6 @@ export class AddonService {
|
||||
}
|
||||
|
||||
public isInstalling(): boolean {
|
||||
console.debug(`isInstalling`, this._activeInstalls);
|
||||
return this._activeInstalls > 0;
|
||||
}
|
||||
|
||||
@@ -154,11 +154,10 @@ export class AddonService {
|
||||
|
||||
private handleLegacyInstallations(installations: WowInstallation[]): void {
|
||||
if (installations.length === 0) {
|
||||
console.debug(`No legacy addons to migrate`);
|
||||
console.debug(`No legacy installations to migrate`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.debug("handleLegacyInstallations", installations);
|
||||
const allAddons = this._addonStorage.getAll();
|
||||
|
||||
for (const addon of allAddons) {
|
||||
@@ -483,8 +482,10 @@ export class AddonService {
|
||||
throw new Error("Addon not found or invalid");
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Started update for "${addon.name}" at version "${addon.installedVersion}" to "${addon.latestVersion}"`
|
||||
this.logAddonAction(
|
||||
`Addon${capitalizeString(queueItem.installType)}`,
|
||||
addon,
|
||||
`'${addon.installedVersion}' -> '${addon.latestVersion}'`
|
||||
);
|
||||
|
||||
const installation = this._warcraftInstallationService.getWowInstallation(addon.installationId);
|
||||
@@ -531,13 +532,15 @@ export class AddonService {
|
||||
await this.installUnzippedDirectory(unzippedDirectory, installation);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
this.logAddonAction("RestoreBackup", addon, ...directoriesToBeRemoved);
|
||||
await this.restoreAddonDirectories(directoriesToBeRemoved);
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
for (const directory of directoriesToBeRemoved) {
|
||||
console.log("Removing backup", directory);
|
||||
this.logAddonAction("AddonRemoveBackup", addon, directory);
|
||||
await this._fileService.deleteIfExists(directory);
|
||||
}
|
||||
|
||||
@@ -549,11 +552,11 @@ export class AddonService {
|
||||
const removedDirectoryNames = _.difference(existingDirectoryNames, unzippedDirectoryNames);
|
||||
|
||||
if (existingDirectoryNames.length > 0) {
|
||||
console.log("Addon added new directories", addedDirectoryNames);
|
||||
this.logAddonAction("AddedDirs", addon, ...addedDirectoryNames);
|
||||
}
|
||||
|
||||
if (removedDirectoryNames.length > 0) {
|
||||
console.log("Addon removed existing directories", removedDirectoryNames);
|
||||
this.logAddonAction("DiffDirs", addon, ...removedDirectoryNames);
|
||||
}
|
||||
|
||||
addon.installedExternalReleaseId = addon.externalLatestReleaseId;
|
||||
@@ -599,7 +602,8 @@ export class AddonService {
|
||||
installState: AddonInstallState.Complete,
|
||||
progress: 100,
|
||||
});
|
||||
console.log(`Finished update for "${addon.name}" at version "${addon.installedVersion}"`);
|
||||
|
||||
this.logAddonAction(`Addon${capitalizeString(queueItem.installType)}Complete`, addon, addon.installedVersion);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
queueItem.completion.reject(err);
|
||||
@@ -628,7 +632,6 @@ export class AddonService {
|
||||
}
|
||||
return addon.name;
|
||||
} finally {
|
||||
console.debug("DECREMENT", didFinish);
|
||||
if (!didFinish) {
|
||||
this._activeInstalls -= 1;
|
||||
}
|
||||
@@ -720,11 +723,9 @@ export class AddonService {
|
||||
const currentAddonLocation = path.join(addonFolderPath, addonFolder);
|
||||
const addonFolderBackupLocation = path.join(addonFolderPath, `${addonFolder}-bak`);
|
||||
|
||||
console.log("Ensure existing backup is deleted", addonFolderBackupLocation);
|
||||
await this._fileService.deleteIfExists(addonFolderBackupLocation);
|
||||
|
||||
if (await this._fileService.pathExists(currentAddonLocation)) {
|
||||
console.log("Backing up", currentAddonLocation);
|
||||
// Create the backup dir first
|
||||
await this._fileService.createDirectory(addonFolderBackupLocation);
|
||||
|
||||
@@ -741,8 +742,13 @@ export class AddonService {
|
||||
return backupFolders;
|
||||
}
|
||||
|
||||
private logAddonAction(action: string, addon: Addon, ...extras: string[]) {
|
||||
console.log(
|
||||
`[${action}] ${addon.providerName} ${addon.externalId ?? "NO_EXT_ID"} ${addon.name} ${extras.join(" ")}`
|
||||
);
|
||||
}
|
||||
|
||||
private async restoreAddonDirectories(directories: string[]) {
|
||||
console.log("Attempting to restore addon directories based on backups");
|
||||
for (const directory of directories) {
|
||||
const originalLocation = directory.substring(0, directory.length - 4);
|
||||
|
||||
@@ -756,7 +762,6 @@ export class AddonService {
|
||||
}
|
||||
|
||||
// Move the backup folder into the original location
|
||||
console.log(`Attempting to roll back ${directory}`);
|
||||
await this._fileService.copy(directory, originalLocation);
|
||||
}
|
||||
}
|
||||
@@ -786,7 +791,7 @@ export class AddonService {
|
||||
public async getAddonByUrl(url: URL, installation: WowInstallation): Promise<AddonSearchResult | undefined> {
|
||||
const provider = this.getAddonProvider(url);
|
||||
if (!provider) {
|
||||
console.warn(`No provider found for urlL: ${url.toString()}`);
|
||||
console.warn(`No provider found for url: ${url.toString()}`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -841,6 +846,8 @@ export class AddonService {
|
||||
}
|
||||
|
||||
public async removeAddon(addon: Addon, removeDependencies = false, removeDirectories = true): Promise<void> {
|
||||
console.log(`[RemoveAddon] ${addon.providerName} ${addon.externalId ?? "NO_EXT_ID"} ${addon.name}`);
|
||||
|
||||
if (removeDirectories) {
|
||||
const installedDirectories = addon.installedFolders?.split(",") ?? [];
|
||||
const installation = this._warcraftInstallationService.getWowInstallation(addon.installationId);
|
||||
@@ -848,6 +855,9 @@ export class AddonService {
|
||||
|
||||
for (const directory of installedDirectories) {
|
||||
const addonDirectory = path.join(addonFolderPath, directory);
|
||||
console.log(
|
||||
`[RemoveAddonDirectory] ${addon.providerName} ${addon.externalId ?? "NO_EXT_ID"} ${addonDirectory}`
|
||||
);
|
||||
await this._fileService.remove(addonDirectory);
|
||||
}
|
||||
}
|
||||
@@ -1072,16 +1082,16 @@ export class AddonService {
|
||||
}
|
||||
|
||||
public async migrate(installation: WowInstallation): Promise<void> {
|
||||
console.log(`Migrating: ${installation.label}`);
|
||||
console.log(`[MigrateInstall] ${installation.label}`);
|
||||
const existingAddons = this.getAllAddons(installation);
|
||||
if (!existingAddons.length) {
|
||||
console.log(`Skipping client type: ${installation.label} no addons found`);
|
||||
console.log(`[MigrateInstall] ${installation.label} no addons found`);
|
||||
return;
|
||||
}
|
||||
|
||||
const needsMigration = _.some(existingAddons, (addon) => this.needsMigration(addon));
|
||||
if (!needsMigration) {
|
||||
console.log(`No addons needed to be migrated: ${installation.label}`);
|
||||
console.log(`[MigrateInstall] ${installation.label} No addons needed to be migrated`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1105,7 +1115,7 @@ export class AddonService {
|
||||
|
||||
private migrateAddon(addon: Addon, scannedAddons: Addon[]): void {
|
||||
if (addon.providerName === ADDON_PROVIDER_HUB_LEGACY) {
|
||||
console.log(`Updating legacy hub name: ${addon.name}`);
|
||||
console.log(`[MigrateAddon] '${addon.name}' Updating legacy hub name`);
|
||||
addon.providerName = ADDON_PROVIDER_HUB;
|
||||
this.saveAddon(addon);
|
||||
}
|
||||
@@ -1116,7 +1126,7 @@ export class AddonService {
|
||||
);
|
||||
|
||||
if (!scannedAddon) {
|
||||
console.log(`No scanned addon found ${addon.name}`);
|
||||
console.log(`[MigrateAddon] '${addon.name}' No scanned addon found`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1193,21 +1203,16 @@ export class AddonService {
|
||||
(addonFolder) => `${addonFolder.matchingAddon.providerName}${addonFolder.matchingAddon.externalId}`
|
||||
);
|
||||
|
||||
console.log(Object.keys(matchedGroups));
|
||||
|
||||
const addonList = Object.values(matchedGroups).map(
|
||||
(value) => _.orderBy(value, (v) => v.matchingAddon.externalIds.length).reverse()[0].matchingAddon
|
||||
);
|
||||
|
||||
const unmatchedFolders = addonFolders.filter((af) => this.isAddonFolderUnmatched(matchedAddonFolderNames, af));
|
||||
console.debug("unmatchedFolders", unmatchedFolders);
|
||||
|
||||
const unmatchedAddons = unmatchedFolders.map((uf) =>
|
||||
this.createUnmatchedAddon(uf, installation, matchedAddonFolderNames)
|
||||
);
|
||||
|
||||
console.debug("unmatchedAddons", unmatchedAddons);
|
||||
|
||||
addonList.push(...unmatchedAddons);
|
||||
|
||||
//Clear the changelogs since they wont always be latest
|
||||
@@ -1251,8 +1256,6 @@ export class AddonService {
|
||||
(ea) => ea.id !== addon.id && _.intersection(addon.installedFolderList, ea.installedFolderList).length > 0
|
||||
);
|
||||
|
||||
console.debug("reconcileAddonFolders", existingAddons);
|
||||
|
||||
for (const existingAddon of existingAddons) {
|
||||
if (existingAddon.providerName === ADDON_PROVIDER_UNKNOWN) {
|
||||
await this.removeAddon(existingAddon, false, false);
|
||||
|
||||
@@ -8,6 +8,7 @@ import { CircuitBreakerWrapper, NetworkService } from "../network/network.servic
|
||||
|
||||
const API_URL = AppConfig.wowUpApiUrl;
|
||||
const BLOCKLIST_CACHE_KEY = "wowup-blocklist";
|
||||
const BLOCKLIST_CACHE_TTL_SEC = 43200;
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
@@ -30,7 +31,7 @@ export class WowUpApiService {
|
||||
|
||||
return from(this._circuitBreaker.getJson<BlockListRepresentation>(url)).pipe(
|
||||
tap((response) => {
|
||||
this._cacheService.set(BLOCKLIST_CACHE_KEY, response);
|
||||
this._cacheService.set(BLOCKLIST_CACHE_KEY, response, BLOCKLIST_CACHE_TTL_SEC);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -69,13 +69,11 @@ export class WowUpAddonService {
|
||||
_addonService.addonInstalled$
|
||||
.pipe(filter((update) => update.installState === AddonInstallState.Complete))
|
||||
.subscribe((update) => {
|
||||
console.debug("addonInstalled");
|
||||
const installation = this._warcraftInstallationService.getWowInstallation(update.addon.installationId);
|
||||
this.updateForInstallation(installation).catch((e) => console.error(e));
|
||||
});
|
||||
|
||||
_addonService.addonRemoved$.subscribe((addon) => {
|
||||
console.debug("addonRemoved", addon);
|
||||
this.updateForAllClientTypes().catch((e) => console.error(e));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import * as _ from "lodash";
|
||||
import { ColumnState } from "../../models/wowup/column-state";
|
||||
import { remote } from "electron";
|
||||
import { UpdateCheckResult } from "electron-updater";
|
||||
import * as _ from "lodash";
|
||||
import { join } from "path";
|
||||
import { BehaviorSubject, Subject } from "rxjs";
|
||||
import { Subject } from "rxjs";
|
||||
|
||||
import { Injectable } from "@angular/core";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
|
||||
import {
|
||||
ADDON_MIGRATION_VERSION_KEY,
|
||||
ADDON_PROVIDERS_KEY,
|
||||
ALLIANCE_LIGHT_THEME,
|
||||
ALLIANCE_THEME,
|
||||
APP_UPDATE_CHECK_END,
|
||||
APP_UPDATE_CHECK_FOR_UPDATE,
|
||||
APP_UPDATE_CHECK_START,
|
||||
@@ -14,37 +19,34 @@ import {
|
||||
APP_UPDATE_INSTALL,
|
||||
APP_UPDATE_START_DOWNLOAD,
|
||||
COLLAPSE_TO_TRAY_PREFERENCE_KEY,
|
||||
CURRENT_THEME_KEY,
|
||||
DEFAULT_AUTO_UPDATE_PREFERENCE_KEY_SUFFIX,
|
||||
DEFAULT_CHANNEL_PREFERENCE_KEY_SUFFIX,
|
||||
DEFAULT_LIGHT_THEME,
|
||||
DEFAULT_THEME,
|
||||
ENABLE_SYSTEM_NOTIFICATIONS_PREFERENCE_KEY,
|
||||
GET_ADDONS_HIDDEN_COLUMNS_KEY,
|
||||
GET_ADDONS_SORT_ORDER,
|
||||
HORDE_LIGHT_THEME,
|
||||
HORDE_THEME,
|
||||
IPC_GET_APP_VERSION,
|
||||
LAST_SELECTED_WOW_CLIENT_TYPE_PREFERENCE_KEY,
|
||||
MY_ADDONS_HIDDEN_COLUMNS_KEY,
|
||||
MY_ADDONS_SORT_ORDER,
|
||||
SELECTED_LANGUAGE_PREFERENCE_KEY,
|
||||
START_MINIMIZED_PREFERENCE_KEY,
|
||||
START_WITH_SYSTEM_PREFERENCE_KEY,
|
||||
USE_HARDWARE_ACCELERATION_PREFERENCE_KEY,
|
||||
WOWUP_RELEASE_CHANNEL_PREFERENCE_KEY,
|
||||
SELECTED_LANGUAGE_PREFERENCE_KEY,
|
||||
MY_ADDONS_HIDDEN_COLUMNS_KEY,
|
||||
MY_ADDONS_SORT_ORDER,
|
||||
GET_ADDONS_HIDDEN_COLUMNS_KEY,
|
||||
GET_ADDONS_SORT_ORDER,
|
||||
CURRENT_THEME_KEY,
|
||||
DEFAULT_THEME,
|
||||
ADDON_PROVIDERS_KEY,
|
||||
HORDE_THEME,
|
||||
HORDE_LIGHT_THEME,
|
||||
ALLIANCE_THEME,
|
||||
ALLIANCE_LIGHT_THEME,
|
||||
DEFAULT_LIGHT_THEME,
|
||||
ADDON_MIGRATION_VERSION_KEY,
|
||||
IPC_GET_APP_VERSION,
|
||||
USE_SYMLINK_MODE_PREFERENCE_KEY,
|
||||
WOWUP_RELEASE_CHANNEL_PREFERENCE_KEY,
|
||||
} from "../../../common/constants";
|
||||
import { WowClientType } from "../../../common/warcraft/wow-client-type";
|
||||
import { AddonChannelType } from "../../../common/wowup/models";
|
||||
import { AddonProviderState } from "../../models/wowup/addon-provider-state";
|
||||
import { ColumnState } from "../../models/wowup/column-state";
|
||||
import { PreferenceChange } from "../../models/wowup/preference-change";
|
||||
import { SortOrder } from "../../models/wowup/sort-order";
|
||||
import { WowUpReleaseChannelType } from "../../models/wowup/wowup-release-channel-type";
|
||||
import { AddonProviderState } from "../../models/wowup/addon-provider-state";
|
||||
import { getEnumList, getEnumName } from "../../utils/enum.utils";
|
||||
import { ElectronService } from "../electron/electron.service";
|
||||
import { FileService } from "../files/file.service";
|
||||
@@ -81,7 +83,7 @@ export class WowUpService {
|
||||
private _translateService: TranslateService
|
||||
) {
|
||||
this.setDefaultPreferences()
|
||||
.then(() => console.debug("Set default preferences"))
|
||||
// .then(() => console.debug("Set default preferences"))
|
||||
.catch((e) => console.error("Failed to set default preferences", e));
|
||||
|
||||
this.createDownloadDirectory()
|
||||
@@ -341,7 +343,8 @@ export class WowUpService {
|
||||
const updateCheckResult: UpdateCheckResult = await this._electronService.invoke(APP_UPDATE_CHECK_FOR_UPDATE);
|
||||
|
||||
// only notify things when the version changes
|
||||
if (!(await this.isSameVersion(updateCheckResult))) {
|
||||
const isSameVersion = await this.isSameVersion(updateCheckResult);
|
||||
if (!isSameVersion) {
|
||||
this._availableVersion = updateCheckResult.updateInfo.version;
|
||||
this._wowupUpdateCheckSrc.next(updateCheckResult);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user