Merge branch 'develop' into pr/318

This commit is contained in:
jliddev
2020-11-04 11:08:57 -06:00
32 changed files with 360 additions and 74 deletions

View File

@@ -3,7 +3,9 @@ import * as log from "electron-log";
import { autoUpdater } from "electron-updater";
import {
APP_UPDATE_AVAILABLE,
APP_UPDATE_CHECK_END,
APP_UPDATE_CHECK_FOR_UPDATE,
APP_UPDATE_CHECK_START,
APP_UPDATE_DOWNLOADED,
APP_UPDATE_ERROR,
APP_UPDATE_INSTALL,
@@ -11,6 +13,21 @@ import {
APP_UPDATE_START_DOWNLOAD,
} from "./src/common/constants";
export const checkForUpdates = async function checkForUpdates(
win: BrowserWindow
) {
let result = null;
try {
win.webContents.send(APP_UPDATE_CHECK_START);
result = await autoUpdater.checkForUpdates();
} finally {
win.webContents.send(APP_UPDATE_CHECK_END);
}
return result;
};
// Example: https://github.com/electron-userland/electron-builder/blob/docs/encapsulated%20manual%20update%20via%20menu.js
export function initializeAppUpdater(win: BrowserWindow) {
autoUpdater.logger = log;
@@ -39,9 +56,10 @@ export function initializeAppUpdater(win: BrowserWindow) {
});
}
export function initializeAppUpdateIpcHandlers() {
export function initializeAppUpdateIpcHandlers(win: BrowserWindow) {
ipcMain.handle(APP_UPDATE_START_DOWNLOAD, async () => {
log.info(APP_UPDATE_START_DOWNLOAD);
win.webContents.send(APP_UPDATE_START_DOWNLOAD);
return await autoUpdater.downloadUpdate();
});
@@ -52,6 +70,6 @@ export function initializeAppUpdateIpcHandlers() {
ipcMain.handle(APP_UPDATE_CHECK_FOR_UPDATE, async () => {
log.info(APP_UPDATE_CHECK_FOR_UPDATE);
return await autoUpdater.checkForUpdates();
return await checkForUpdates(win);
});
}

View File

@@ -35,7 +35,7 @@ let win: BrowserWindow = null;
// APP MENU SETUP
const appMenuTemplate: Array<
MenuItemConstructorOptions | MenuItem
MenuItemConstructorOptions | MenuItem
> = getAppMenu();
const appMenu = Menu.buildFromTemplate(appMenuTemplate);
@@ -66,6 +66,10 @@ const argv = require("minimist")(process.argv.slice(1), {
boolean: ["serve", "hidden"],
});
function canStartHidden() {
return argv.hidden || app.getLoginItemSettings().wasOpenedAsHidden;
}
function windowStateManager(
windowName: string,
{ width, height }: { width: number; height: number }
@@ -90,9 +94,9 @@ function windowStateManager(
windowState.x >= display.bounds.x &&
windowState.y >= display.bounds.y &&
windowState.x + windowState.width <=
display.bounds.x + display.bounds.width &&
display.bounds.x + display.bounds.width &&
windowState.y + windowState.height <=
display.bounds.y + display.bounds.height
display.bounds.y + display.bounds.height
);
});
@@ -173,7 +177,7 @@ function createWindow(): BrowserWindow {
win = new BrowserWindow(windowOptions);
initializeIpcHanders(win);
initializeAppUpdater(win);
initializeAppUpdateIpcHandlers();
initializeAppUpdateIpcHandlers(win);
// Keep track of window state
mainWindowManager.monitorState(win);
@@ -181,7 +185,10 @@ function createWindow(): BrowserWindow {
win.webContents.userAgent = USER_AGENT;
win.once("ready-to-show", () => {
if (!argv.hidden) win.show();
if (canStartHidden()) {
return;
}
win.show();
});
win.once("show", () => {

View File

@@ -114,6 +114,8 @@
"@angular/animations": "~10.1.4",
"@angular/cdk": "10.2.5",
"@angular/material": "10.2.5",
"@fortawesome/fontawesome-svg-core": "1.2.32",
"@fortawesome/free-solid-svg-icons": "5.15.1",
"@types/lodash": "4.14.162",
"adm-zip": "0.4.16",
"async": "3.2.0",

View File

@@ -1,8 +1,6 @@
import { AfterViewInit, ChangeDetectionStrategy, Component } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { TranslateService } from "@ngx-translate/core";
import { from } from "rxjs";
import { switchMap } from "rxjs/operators";
import { CREATE_TRAY_MENU_CHANNEL } from "../common/constants";
import { SystemTrayConfig } from "../common/wowup/system-tray-config";
import { TelemetryDialogComponent } from "./components/telemetry-dialog/telemetry-dialog.component";
@@ -10,8 +8,9 @@ import { ElectronService } from "./services";
import { AddonService } from "./services/addons/addon.service";
import { AnalyticsService } from "./services/analytics/analytics.service";
import { FileService } from "./services/files/file.service";
import { WarcraftService } from "./services/warcraft/warcraft.service";
import { WowUpService } from "./services/wowup/wowup.service";
import { IconService } from "./services/icons/icon.service";
import { faAngleDoubleDown } from "@fortawesome/free-solid-svg-icons";
const AUTO_UPDATE_PERIOD_MS = 60 * 60 * 1000; // 1 hour
@@ -29,13 +28,15 @@ export class AppComponent implements AfterViewInit {
private _electronService: ElectronService,
private _fileService: FileService,
private translate: TranslateService,
private warcraft: WarcraftService,
private _wowUpService: WowUpService,
private _dialog: MatDialog,
private _addonService: AddonService
private _addonService: AddonService,
private _iconService: IconService
) {
this.translate.setDefaultLang("en");
this.translate.use(this._wowUpService.currentLanguage);
this._iconService.addSvg(faAngleDoubleDown);
}
ngAfterViewInit(): void {
@@ -90,6 +91,7 @@ export class AppComponent implements AfterViewInit {
console.debug("Creating tray", result);
const config: SystemTrayConfig = {
quitLabel: result["APP.SYSTEM_TRAY.QUIT_ACTION"],
checkUpdateLabel: result["APP.SYSTEM_TRAY.CHECK_UPDATE"],
showLabel: result["APP.SYSTEM_TRAY.SHOW_ACTION"],
};

View File

@@ -32,6 +32,18 @@
<div class="row align-items-center">
<p class="mr-3">{{ sessionService.pageContextText$ | async }}</p>
<p>v{{ wowUpService.applicationVersion }}</p>
<div *ngIf="isWowUpdateDownloading" class="downloading-button ml-3 animate">
<mat-icon svgIcon="fas:angle-double-down"></mat-icon>
</div>
<div
*ngIf="!isWowUpUpdateAvailable && !isWowUpdateDownloading"
class="check-update-button ml-3"
[ngClass]="{'animate': isCheckingForUpdates}"
(click)="onClickCheckForUpdates()"
[matTooltip]="'APP.SYSTEM_TRAY.CHECK_UPDATE' | translate"
>
<mat-icon>cached</mat-icon>
</div>
<button
*ngIf="isWowUpUpdateAvailable"
class="update-button ml-3"

View File

@@ -51,13 +51,14 @@ footer {
height: 25px;
padding: 0 0.5em;
overflow: hidden;
background-color: green;
color: green;
border-radius: 4px;
border: none;
color: $white-1;
background-color: $dark-4;
// color: $white-1;
&:hover {
background-color: darkgreen;
background-color: $dark-3;
cursor: pointer;
}
@@ -68,4 +69,41 @@ footer {
pointer-events: none;
}
}
.downloading-button {
height: 25px;
&.animate {
animation: fadeInDown 1s infinite linear;
}
}
.check-update-button {
height: 25px;
&:hover {
cursor: pointer;
}
&.animate {
animation: rotate 1.5s infinite linear reverse;
}
}
}
@keyframes rotate {
to {
transform: rotate(360deg);
}
}
@keyframes fadeInDown {
0% {
opacity: 1;
transform: translateY(-5px);
}
100% {
opacity: 0;
transform: translateY(5px);
}
}

View File

@@ -1,6 +1,9 @@
import { ChangeDetectorRef, Component, NgZone, OnInit } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { MatSnackBar } from "@angular/material/snack-bar";
import { TranslateService } from "@ngx-translate/core";
import { UpdateCheckResult } from "electron-updater";
import { from } from "rxjs";
import { SessionService } from "../../services/session/session.service";
import { WowUpService } from "../../services/wowup/wowup.service";
import { ConfirmDialogComponent } from "../confirm-dialog/confirm-dialog.component";
@@ -14,6 +17,8 @@ export class FooterComponent implements OnInit {
public isUpdatingWowUp = false;
public isWowUpUpdateAvailable = false;
public isWowUpUpdateDownloaded = false;
public isCheckingForUpdates = false;
public isWowUpdateDownloading = false;
constructor(
private _dialog: MatDialog,
@@ -21,7 +26,8 @@ export class FooterComponent implements OnInit {
private _zone: NgZone,
private _cdRef: ChangeDetectorRef,
public wowUpService: WowUpService,
public sessionService: SessionService
public sessionService: SessionService,
private _snackBar: MatSnackBar
) {}
ngOnInit(): void {
@@ -39,6 +45,18 @@ export class FooterComponent implements OnInit {
});
});
this.wowUpService.wowupUpdateCheckInProgress$.subscribe((inProgress) => {
console.debug("wowUpUpdateCheckInProgress", inProgress);
this.isCheckingForUpdates = inProgress;
this._cdRef.detectChanges();
});
this.wowUpService.wowupUpdateDownloadInProgress$.subscribe((inProgress) => {
console.debug("wowupUpdateDownloadInProgress", inProgress);
this.isWowUpdateDownloading = inProgress;
this._cdRef.detectChanges();
});
// Force the angular zone to pump for every progress update since its outside the zone
this.sessionService.statusText$.subscribe((text) => {
this._zone.run(() => {});
@@ -49,6 +67,31 @@ export class FooterComponent implements OnInit {
});
}
public async onClickCheckForUpdates(): Promise<void> {
if (this.isCheckingForUpdates) {
return;
}
let result: UpdateCheckResult = null;
try {
result = await this.wowUpService.checkForAppUpdate();
if (result === null || this.wowUpService.isSameVersion(result)) {
this.showSnackbar("APP.WOWUP_UPDATE.NOT_AVAILABLE");
}
} catch (e) {
console.error(e);
this.showSnackbar("APP.WOWUP_UPDATE.UPDATE_ERROR", ["error-text"]);
}
}
private showSnackbar(localeKey: string, classes: string[] = []) {
this._snackBar.open(this._translateService.instant(localeKey), null, {
duration: 2000,
panelClass: ["center-text", ...classes],
});
}
public getUpdateIconTooltip() {
if (this.isWowUpUpdateDownloaded) {
return "APP.WOWUP_UPDATE_DOWNLOADED_TOOLTIP";

View File

@@ -1,66 +1,47 @@
<div class="addon-column row align-items-center">
<div class="thumbnail-container">
<div
*ngIf="listItem.hasThumbnail === true"
class="addon-logo-container"
[style.backgroundImage]="'url(' + listItem.addon.thumbnailUrl + ')'"
></div>
<div *ngIf="listItem.hasThumbnail === true" class="addon-logo-container"
[style.backgroundImage]="'url(' + listItem.addon.thumbnailUrl + ')'"></div>
<div *ngIf="listItem.hasThumbnail === false" class="addon-logo-container">
<div class="addon-logo-letter">
{{ listItem.thumbnailLetter }}
</div>
</div>
<div
*ngIf="listItem.isBetaChannel || listItem.isAlphaChannel"
class="channel"
[ngClass]="{
<div *ngIf="listItem.isBetaChannel || listItem.isAlphaChannel" class="channel" [ngClass]="{
beta: listItem.isBetaChannel,
alpha: listItem.isAlphaChannel
}"
>
}">
{{ listItem.isAlphaChannel ? "Alpha" : "Beta" }}
</div>
</div>
<div>
<a class="addon-title mat-subheading-2" (click)="viewDetails()" [ngClass]="{ ignored: listItem.isIgnored }">{{
listItem.addon.name
}}</a>
<a class="addon-title mat-subheading-2" (click)="viewDetails()"
[ngClass]="{ ignored: 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 row align-items-center" [ngClass]="{ ignored: listItem.isIgnored }">
<mat-icon
*ngIf="this.listItem.isAutoUpdate === true"
class="auto-update-icon mr-1"
[inline]="true"
[matTooltip]="'PAGES.MY_ADDONS.TABLE.AUTO_UPDATE_ICON_TOOLTIP' | translate"
>
<mat-icon *ngIf="this.listItem.isAutoUpdate === true" class="auto-update-icon mr-1" [inline]="true"
[matTooltip]="'PAGES.MY_ADDONS.TABLE.AUTO_UPDATE_ICON_TOOLTIP' | translate">
update
</mat-icon>
{{ listItem.addon.installedVersion }}
<div class="update-available row"
*ngIf="showUpdateToVersion && listItem.addon.latestVersion !== listItem.addon.installedVersion">
<mat-icon [inline]="true">play_arrow</mat-icon>
<div>{{ listItem.addon.latestVersion }}</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -66,6 +66,10 @@
.addon-version {
color: $white-2;
.update-available {
color: $artifact;
}
}
.auto-update-icon {

View File

@@ -8,6 +8,7 @@ import { AddonViewModel } from "../../business-objects/my-addon-list-item";
})
export class MyAddonsAddonCellComponent implements OnInit {
@Input("addon") listItem: AddonViewModel;
@Input() showUpdateToVersion = false;
@Output() onViewDetails: EventEmitter<AddonViewModel> = new EventEmitter();

View File

@@ -20,6 +20,7 @@ import { MatTabsModule } from "@angular/material/tabs";
import { MatTooltipModule } from "@angular/material/tooltip";
import { MatSidenavModule } from "@angular/material/sidenav";
import { MatListModule } from "@angular/material/list";
import { MatBadgeModule } from "@angular/material/badge";
@NgModule({
exports: [
@@ -44,6 +45,7 @@ import { MatListModule } from "@angular/material/list";
MatSnackBarModule,
MatSidenavModule,
MatListModule,
MatBadgeModule,
],
imports: [
MatSliderModule,
@@ -67,6 +69,7 @@ import { MatListModule } from "@angular/material/list";
MatSnackBarModule,
MatSidenavModule,
MatListModule,
MatBadgeModule,
],
})
export class MatModule {}

View File

@@ -131,6 +131,7 @@
<app-my-addons-addon-cell
[addon]="element"
(onViewDetails)="openDetailDialog($event)"
[showUpdateToVersion]="!isLatestUpdateColumnVisible()"
>
</app-my-addons-addon-cell>
</td>
@@ -179,7 +180,7 @@
<th mat-header-cell mat-sort-header *matHeaderCellDef>
{{ "PAGES.MY_ADDONS.TABLE.LATEST_VERSION_COLUMN_HEADER" | translate }}
</th>
<td mat-cell *matCellDef="let element" class="cell-padding">
<td mat-cell *matCellDef="let element" class="cell-padding" [ngClass]="{'addon-update-available' : element.addon.latestVersion !== element.addon.installedVersion}">
{{ element.addon.latestVersion }}
</td>
</ng-container>
@@ -307,7 +308,13 @@
</div>
<div>
<div class="addon-name">{{ listItem.addon.name }}</div>
<div class="addon-version">{{ listItem.addon.latestVersion }}</div>
<div class="addon-version">{{ listItem.addon.installedVersion }}</div>
<div
class="addon-update-available"
*ngIf="listItem.addon.latestVersion !== listItem.addon.installedVersion"
>
{{ listItem.addon.latestVersion }}
</div>
</div>
</div>
<mat-divider></mat-divider>

View File

@@ -86,6 +86,10 @@
white-space: pre-wrap;
}
.addon-update-available {
color: $artifact;
}
.game-version-cell {
min-width: 110px;
}

View File

@@ -180,6 +180,10 @@ export class MyAddonsComponent implements OnInit, OnDestroy {
this.subscriptions.forEach((sub) => sub.unsubscribe());
}
public isLatestUpdateColumnVisible(): boolean {
return this.columns.find(column => column.name === 'addon.latestVersion').visible
}
public onSortChange(): void {
if (this.table) {
this.table.nativeElement.scrollIntoView({ behavior: "smooth" });

View File

@@ -1,8 +1,9 @@
import { Injectable } from "@angular/core";
import * as childProcess from "child_process";
import { APP_UPDATE_CHECK_END, APP_UPDATE_CHECK_START } from "common/constants";
// If you import a module but never use any of the imported values other than as TypeScript types,
// the resulting javascript file will look as if you never imported the module at all.
import { ipcRenderer, remote, shell, webFrame } from "electron";
import { ipcRenderer, remote, Settings, shell, webFrame } from "electron";
import * as fs from "fs";
import { BehaviorSubject } from "rxjs";
import { v4 as uuidv4 } from "uuid";
@@ -17,6 +18,7 @@ import { ValueResponse } from "../../../common/models/value-response";
export class ElectronService {
private readonly _windowMaximizedSrc = new BehaviorSubject(false);
private readonly _windowMinimizedSrc = new BehaviorSubject(false);
private readonly _ipcEventReceivedSrc = new BehaviorSubject('');
ipcRenderer: typeof ipcRenderer;
webFrame: typeof webFrame;
@@ -27,6 +29,7 @@ export class ElectronService {
public readonly windowMaximized$ = this._windowMaximizedSrc.asObservable();
public readonly windowMinimized$ = this._windowMinimizedSrc.asObservable();
public readonly ipcEventReceived$ = this._ipcEventReceivedSrc.asObservable();
public readonly isWin = process.platform === "win32";
public readonly isMac = process.platform === "darwin";
public readonly isLinux = process.platform === "linux";
@@ -39,6 +42,13 @@ export class ElectronService {
return this.remote.app.getLocale().split("-")[0];
}
get loginItemSettings() {
return this.remote.app.getLoginItemSettings();
}
set loginItemSettings(settings: Settings) {
this.remote.app.setLoginItemSettings(settings);
}
constructor() {
// Conditional imports
if (!this.isElectron) {
@@ -55,6 +65,14 @@ export class ElectronService {
this.childProcess = window.require("child_process");
this.fs = window.require("fs");
this.ipcRenderer.on(APP_UPDATE_CHECK_START, () => {
this._ipcEventReceivedSrc.next(APP_UPDATE_CHECK_START);
});
this.ipcRenderer.on(APP_UPDATE_CHECK_END, () => {
this._ipcEventReceivedSrc.next(APP_UPDATE_CHECK_END);
});
const currentWindow = this.remote?.getCurrentWindow();
currentWindow?.on("minimize", () => {

View File

@@ -0,0 +1,24 @@
import { Injectable } from "@angular/core";
import { MatIconRegistry } from "@angular/material/icon";
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
import { DomSanitizer } from "@angular/platform-browser";
@Injectable({
providedIn: "root",
})
export class IconService {
constructor(
private _matIconRegistry: MatIconRegistry,
private _sanitizer: DomSanitizer
) {}
async addSvg(icon: IconDefinition) {
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${icon.icon[0]} ${icon.icon[1]}"><path d="${icon.icon[4]}" /></svg>`;
this._matIconRegistry.addSvgIconLiteralInNamespace(
icon.prefix,
icon.iconName,
this._sanitizer.bypassSecurityTrustHtml(svg)
);
}
}

View File

@@ -5,7 +5,10 @@ import { existsSync } from "fs";
import { join } from "path";
import { Subject } from "rxjs";
import {
APP_UPDATE_CHECK_END,
APP_UPDATE_CHECK_FOR_UPDATE,
APP_UPDATE_CHECK_START,
APP_UPDATE_DOWNLOADED,
APP_UPDATE_INSTALL,
APP_UPDATE_START_DOWNLOAD,
COLLAPSE_TO_TRAY_PREFERENCE_KEY,
@@ -25,23 +28,21 @@ import { AddonChannelType } from "../../models/wowup/addon-channel-type";
import { PreferenceChange } from "../../models/wowup/preference-change";
import { WowUpReleaseChannelType } from "../../models/wowup/wowup-release-channel-type";
import { getEnumList, getEnumName } from "../../utils/enum.utils";
import { CachingService } from "../caching/caching-service";
import { DownloadSevice } from "../download/download.service";
import { ElectronService } from "../electron/electron.service";
import { FileService } from "../files/file.service";
import { PreferenceStorageService } from "../storage/preference-storage.service";
import { WowUpApiService } from "../wowup-api/wowup-api.service";
const LATEST_VERSION_CACHE_KEY = "latest-version-response";
var autoLaunch = require("auto-launch");
const autoLaunch = require("auto-launch");
@Injectable({
providedIn: "root",
})
export class WowUpService {
private readonly _preferenceChangeSrc = new Subject<PreferenceChange>();
private readonly _wowupUpdateDownloadInProgressSrc = new Subject<boolean>();
private readonly _wowupUpdateDownloadedSrc = new Subject<any>();
private readonly _wowupUpdateCheckSrc = new Subject<UpdateCheckResult>();
private readonly _wowupUpdateCheckInProgressSrc = new Subject<boolean>();
public readonly updaterName = "WowUpUpdater.exe";
@@ -67,15 +68,14 @@ export class WowUpService {
public readonly isBetaBuild: boolean;
public readonly preferenceChange$ = this._preferenceChangeSrc.asObservable();
public readonly wowupUpdateDownloaded$ = this._wowupUpdateDownloadedSrc.asObservable();
public readonly wowupUpdateDownloadInProgress$ = this._wowupUpdateDownloadInProgressSrc.asObservable();
public readonly wowupUpdateCheck$ = this._wowupUpdateCheckSrc.asObservable();
public readonly wowupUpdateCheckInProgress$ = this._wowupUpdateCheckInProgressSrc.asObservable();
constructor(
private _preferenceStorageService: PreferenceStorageService,
private _downloadService: DownloadSevice,
private _electronService: ElectronService,
private _fileService: FileService,
private _cacheService: CachingService,
private _wowUpApiService: WowUpApiService
) {
this.setDefaultPreferences();
@@ -84,6 +84,31 @@ export class WowUpService {
this.applicationVersion.toLowerCase().indexOf("beta") != -1;
this.createDownloadDirectory().then(() => this.cleanupDownloads());
this._electronService.ipcEventReceived$.subscribe((evt) => {
switch (evt) {
case APP_UPDATE_CHECK_START:
console.log(APP_UPDATE_CHECK_START);
this._wowupUpdateCheckInProgressSrc.next(true);
break;
case APP_UPDATE_CHECK_END:
console.log(APP_UPDATE_CHECK_END);
this._wowupUpdateCheckInProgressSrc.next(false);
break;
case APP_UPDATE_START_DOWNLOAD:
console.log(APP_UPDATE_START_DOWNLOAD);
this._wowupUpdateDownloadInProgressSrc.next(true);
break;
case APP_UPDATE_DOWNLOADED:
console.log(APP_UPDATE_DOWNLOADED);
this._wowupUpdateDownloadInProgressSrc.next(false);
break;
}
});
this.setAutoStartup();
console.log('loginItemSettings', this._electronService.loginItemSettings);
}
public get updaterExists() {
@@ -245,16 +270,21 @@ export class WowUpService {
);
// only notify things when the version changes
if (
updateCheckResult.updateInfo.version !==
this._electronService.getVersionNumber()
) {
if (!this.isSameVersion(updateCheckResult)) {
this._wowupUpdateCheckSrc.next(updateCheckResult);
}
return updateCheckResult;
}
public isSameVersion(updateCheckResult: UpdateCheckResult) {
return (
updateCheckResult &&
updateCheckResult.updateInfo?.version ===
this._electronService.getVersionNumber()
);
}
public async downloadUpdate() {
const downloadResult = await this._electronService.invoke(
APP_UPDATE_START_DOWNLOAD
@@ -347,10 +377,14 @@ export class WowUpService {
isHidden: this.startMinimized,
});
if (this.startWithSystem) autoLauncher.enable();
else autoLauncher.disable();
if (this.startWithSystem) {
autoLauncher.enable();
}
else {
autoLauncher.disable();
}
} else {
this._electronService.remote.app.setLoginItemSettings({
this._electronService.loginItemSettings = {
openAtLogin: this.startWithSystem,
openAsHidden: this._electronService.isMac ? this.startMinimized : false,
args: this._electronService.isWin
@@ -358,7 +392,7 @@ export class WowUpService {
? ["--hidden"]
: []
: [],
});
};
}
}

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Automatisch {count} {count, plural, =1{Addon} other{Addons}} aktualisiert.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Automatische Aktualisierung",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Beenden",
"SHOW_ACTION": "Öffnen"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "WowUp Update installieren",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Willst du WowUp neu Starten um das Update zu installieren?",
"WOWUP_UPDATE_INSTALL_TITLE": "WowUp Update bereit",
@@ -222,6 +227,11 @@
"LOG_FILES_LABEL": "Log-Dateien",
"TITLE": "Debuggen"
},
"TABS": {
"APPLICATION": "Application",
"CLIENTS": "Clients",
"DEBUG": "Debug"
},
"WOW": {
"AUTO_UPDATE_DESCRIPTION": "Neu installierte Addons werden standardmäßig auf Auto-Update gesetzt",
"AUTO_UPDATE_LABEL": "Automatisch aktualisieren",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Automatically updated {count} {count, plural, =1{addon} other{addons}}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Auto Updates",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Quit",
"SHOW_ACTION": "Show"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Install WowUp update",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Do you want to restart WowUp and install the update?",
"WOWUP_UPDATE_INSTALL_TITLE": "WowUp Update Ready",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Automatically updated {count} {count, plural, =1{addon} other{addons}}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Auto Updates",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Quit",
"SHOW_ACTION": "Show"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Install WowUp update",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Do you want restart WowUp to install the update?",
"WOWUP_UPDATE_INSTALL_TITLE": "WowUp Update Ready",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Automatically updated {count} {count, plural, =1{addon} other{addons}}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Auto Updates",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Quit",
"SHOW_ACTION": "Show"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Install WowUp update",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Do you want restart WowUp to install the update?",
"WOWUP_UPDATE_INSTALL_TITLE": "WowUp Update Ready",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Automaticamente {count, plural, =1{aggiornato} other{aggiornati}} {count} {count, plural, =1{addon} other{addons}}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Aggiornamenti automatici",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Chiudi",
"SHOW_ACTION": "Mostra"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Installa l'aggiornamento di WowUp",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Vuoi riavviare WowUp per installare l'aggiornamento?",
"WOWUP_UPDATE_INSTALL_TITLE": "Aggiornamento di Wowup pronto",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Automatically updated {count} {count, plural, =1{addon} other{addons}}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Auto Updates",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Quit",
"SHOW_ACTION": "Show"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Install WowUp update",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Do you want restart WowUp to install the update?",
"WOWUP_UPDATE_INSTALL_TITLE": "WowUp Update Ready",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "{count} {count, plural, =1{utvidelse} other{utvidelse} ble automatisk oppdatert}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Automatiske Oppdateringer",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Quit",
"SHOW_ACTION": "Show"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Installer oppdatering til WowUp",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Vil du restarte WowUp for å installere oppdateringen?",
"WOWUP_UPDATE_INSTALL_TITLE": "WowUp-oppdatering er klar",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Automatically updated {count} {count, plural, =1{addon} other{addons}}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Auto Updates",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Quit",
"SHOW_ACTION": "Show"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Install WowUp update",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Do you want restart WowUp to install the update?",
"WOWUP_UPDATE_INSTALL_TITLE": "WowUp Update Ready",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Автоматически {count, plural, one{обновлена} other{обновлено}} {count} {count, plural, one{модификация} few{модификации} other{модификаций}}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Автоматические обновления",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Выход",
"SHOW_ACTION": "Показать"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Установить обновление WowUp",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Вы хотите перезапустить WowUp чтобы установить обновление?",
"WOWUP_UPDATE_INSTALL_TITLE": "Для WowUp готово обновление",

View File

@@ -3,9 +3,14 @@
"AUTO_UPDATE_NOTIFICATION_BODY": "Automatically updated {count} {count, plural, =1{addon} other{addons}}.",
"AUTO_UPDATE_NOTIFICATION_TITLE": "Auto Updates",
"SYSTEM_TRAY": {
"CHECK_UPDATE": "Check for Updates...",
"QUIT_ACTION": "Quit",
"SHOW_ACTION": "Show"
},
"WOWUP_UPDATE": {
"NOT_AVAILABLE": "Latest version of WowUp is already installed",
"UPDATE_ERROR": "Failed to get WowUp update"
},
"WOWUP_UPDATE_DOWNLOADED_TOOLTIP": "Install WowUp update",
"WOWUP_UPDATE_INSTALL_MESSAGE": "Do you want restart WowUp to install the update?",
"WOWUP_UPDATE_INSTALL_TITLE": "WowUp Update Ready",

View File

@@ -43,3 +43,5 @@ export const APP_UPDATE_AVAILABLE = "app-update-available";
export const APP_UPDATE_START_DOWNLOAD = "app-update-start-download";
export const APP_UPDATE_INSTALL = "app-update-install";
export const APP_UPDATE_CHECK_FOR_UPDATE = "app-update-check-for-update";
export const APP_UPDATE_CHECK_START = "app-update-check-start";
export const APP_UPDATE_CHECK_END = "app-update-check-end";

View File

@@ -1,4 +1,5 @@
export interface SystemTrayConfig {
showLabel: string;
quitLabel: string;
checkUpdateLabel: string;
}

View File

@@ -298,6 +298,10 @@ img {
.addon-version {
color: $white-2;
}
.addon-update-available {
color: $artifact;
}
}
}
@@ -401,6 +405,10 @@ img {
}
}
.error-text {
color: red;
}
.no-tabs {
&.mat-tab-group {
.mat-tab-header {
@@ -408,3 +416,12 @@ img {
}
}
}
snack-bar-container {
&.center-text {
span {
margin: auto;
text-align: center;
}
}
}

View File

@@ -18,3 +18,5 @@ $white-4: #bbbbbb;
$rare-color: #0070dd;
$epic-color: #a335ee;
$artifact: #dbcc78;

View File

@@ -33,6 +33,13 @@ export function createTray(
}
},
},
// Removing this for now per discussion with zak
// {
// label: config.showLabel || "Check for Updates...",
// click: () => {
// checkForUpdates(window);
// },
// },
{
label: config.quitLabel || "Quit",
role: "quit",