feat: redesign auto-update component (#910)
This commit is contained in:
committed by
László Monda
parent
12d361eb2e
commit
9a0b0f9df1
@@ -5,7 +5,7 @@ import * as settings from 'electron-settings';
|
|||||||
import * as isDev from 'electron-is-dev';
|
import * as isDev from 'electron-is-dev';
|
||||||
import * as storage from 'electron-settings';
|
import * as storage from 'electron-settings';
|
||||||
|
|
||||||
import { IpcEvents, LogService } from 'uhk-common';
|
import { AutoUpdateSettings, IpcEvents, LogService } from 'uhk-common';
|
||||||
import { MainServiceBase } from './main-service-base';
|
import { MainServiceBase } from './main-service-base';
|
||||||
|
|
||||||
export class AppUpdateService extends MainServiceBase {
|
export class AppUpdateService extends MainServiceBase {
|
||||||
@@ -76,14 +76,17 @@ export class AppUpdateService extends MainServiceBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.autoUpdater.checkForUpdate, () => {
|
ipcMain.on(IpcEvents.autoUpdater.checkForUpdate, (event: Electron.Event, args: any[]) => {
|
||||||
this.logService.debug('[AppUpdateService] checkForUpdate request from renderer process');
|
const allowPrerelease: boolean = args[0];
|
||||||
|
// tslint:disable-next-line:max-line-length
|
||||||
|
const logMsg = `[AppUpdateService] checkForUpdate request from renderer process. Allow prerelease: ${allowPrerelease}`;
|
||||||
|
this.logService.debug(logMsg);
|
||||||
this.sendAutoUpdateNotification = true;
|
this.sendAutoUpdateNotification = true;
|
||||||
this.checkForUpdate();
|
this.checkForUpdate(allowPrerelease);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkForUpdate() {
|
private checkForUpdate(allowPrerelease = false): void {
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
const msg = '[AppUpdateService] Application update is not working in dev mode.';
|
const msg = '[AppUpdateService] Application update is not working in dev mode.';
|
||||||
this.logService.info(msg);
|
this.logService.info(msg);
|
||||||
@@ -106,7 +109,7 @@ export class AppUpdateService extends MainServiceBase {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
autoUpdater.allowPrerelease = this.allowPreRelease();
|
autoUpdater.allowPrerelease = allowPrerelease;
|
||||||
autoUpdater.checkForUpdates()
|
autoUpdater.checkForUpdates()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.logService.debug('[AppUpdateService] checkForUpdate success');
|
this.logService.debug('[AppUpdateService] checkForUpdate success');
|
||||||
@@ -127,12 +130,6 @@ export class AppUpdateService extends MainServiceBase {
|
|||||||
return firstRunVersion !== this.app.getVersion();
|
return firstRunVersion !== this.app.getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
private allowPreRelease() {
|
|
||||||
const autoUpdateSettings = this.getAutoUpdateSettings();
|
|
||||||
|
|
||||||
return autoUpdateSettings && autoUpdateSettings.usePreReleaseUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkForUpdateAtStartup() {
|
private checkForUpdateAtStartup() {
|
||||||
const autoUpdateSettings = this.getAutoUpdateSettings();
|
const autoUpdateSettings = this.getAutoUpdateSettings();
|
||||||
const checkForUpdate = autoUpdateSettings && autoUpdateSettings.checkForUpdateOnStartUp;
|
const checkForUpdate = autoUpdateSettings && autoUpdateSettings.checkForUpdateOnStartUp;
|
||||||
@@ -142,10 +139,10 @@ export class AppUpdateService extends MainServiceBase {
|
|||||||
return checkForUpdate;
|
return checkForUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getAutoUpdateSettings() {
|
private getAutoUpdateSettings(): AutoUpdateSettings {
|
||||||
const value = storage.get('auto-update-settings');
|
const value = storage.get('auto-update-settings');
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return {checkForUpdateOnStartUp: false, usePreReleaseUpdate: false};
|
return {checkForUpdateOnStartUp: false};
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.parse(<string>value);
|
return JSON.parse(<string>value);
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
export interface AutoUpdateSettings {
|
export interface AutoUpdateSettings {
|
||||||
checkForUpdateOnStartUp: boolean;
|
checkForUpdateOnStartUp: boolean;
|
||||||
usePreReleaseUpdate: boolean;
|
usePreReleaseUpdate?: boolean;
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export * from './auto-update-settings';
|
||||||
export * from './command-line-args';
|
export * from './command-line-args';
|
||||||
export * from './notification';
|
export * from './notification';
|
||||||
export * from './ipc-response';
|
export * from './ipc-response';
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
<app-update-available *ngIf="showUpdateAvailable$ | async"
|
<app-update-available *ngIf="showUpdateAvailable"
|
||||||
|
[@updateAvailable]
|
||||||
|
[updateInfo]="updateInfo$ | async"
|
||||||
(updateApp)="updateApp()"
|
(updateApp)="updateApp()"
|
||||||
(doNotUpdateApp)="doNotUpdateApp()">
|
(doNotUpdateApp)="doNotUpdateApp()">
|
||||||
</app-update-available>
|
</app-update-available>
|
||||||
|
|
||||||
<side-menu *ngIf="deviceConfigurationLoaded$ | async"></side-menu>
|
<side-menu *ngIf="deviceConfigurationLoaded$ | async"
|
||||||
<div id="main-content" class="main-content">
|
[class.update-panel-visible]="showUpdateAvailable"></side-menu>
|
||||||
|
<div id="main-content"
|
||||||
|
class="main-content"
|
||||||
|
[class.update-panel-visible]="showUpdateAvailable">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</div>
|
</div>
|
||||||
<notifier-container></notifier-container>
|
<notifier-container></notifier-container>
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import {
|
|||||||
deviceConfigurationLoaded,
|
deviceConfigurationLoaded,
|
||||||
runningInElectron,
|
runningInElectron,
|
||||||
saveToKeyboardState,
|
saveToKeyboardState,
|
||||||
keypressCapturing
|
keypressCapturing,
|
||||||
|
getUpdateInfo
|
||||||
} from './store';
|
} from './store';
|
||||||
import { ProgressButtonState } from './store/reducers/progress-button-state';
|
import { ProgressButtonState } from './store/reducers/progress-button-state';
|
||||||
|
import { UpdateInfo } from './models/update-info';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'main-app',
|
selector: 'main-app',
|
||||||
@@ -32,11 +34,22 @@ import { ProgressButtonState } from './store/reducers/progress-button-state';
|
|||||||
style({transform: 'translateY(0)'}),
|
style({transform: 'translateY(0)'}),
|
||||||
animate('400ms ease-in-out', style({transform: 'translateY(100%)'}))
|
animate('400ms ease-in-out', style({transform: 'translateY(100%)'}))
|
||||||
])
|
])
|
||||||
|
]),
|
||||||
|
trigger('updateAvailable', [
|
||||||
|
transition(':enter', [
|
||||||
|
style({transform: 'translateY(-45px)'}),
|
||||||
|
animate('500ms ease-out', style({transform: 'translateY(0)'}))
|
||||||
|
]),
|
||||||
|
transition(':leave', [
|
||||||
|
style({transform: 'translateY(0)'}),
|
||||||
|
animate('500ms ease-out', style({transform: 'translateY(-45px)'}))
|
||||||
])
|
])
|
||||||
|
])
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class MainAppComponent implements OnDestroy {
|
export class MainAppComponent implements OnDestroy {
|
||||||
showUpdateAvailable$: Observable<boolean>;
|
showUpdateAvailable: boolean;
|
||||||
|
updateInfo$: Observable<UpdateInfo>;
|
||||||
deviceConfigurationLoaded$: Observable<boolean>;
|
deviceConfigurationLoaded$: Observable<boolean>;
|
||||||
runningInElectron$: Observable<boolean>;
|
runningInElectron$: Observable<boolean>;
|
||||||
saveToKeyboardState: ProgressButtonState;
|
saveToKeyboardState: ProgressButtonState;
|
||||||
@@ -44,9 +57,12 @@ export class MainAppComponent implements OnDestroy {
|
|||||||
private keypressCapturing: boolean;
|
private keypressCapturing: boolean;
|
||||||
private saveToKeyboardStateSubscription: Subscription;
|
private saveToKeyboardStateSubscription: Subscription;
|
||||||
private keypressCapturingSubscription: Subscription;
|
private keypressCapturingSubscription: Subscription;
|
||||||
|
private showUpdateAvailableSubscription: Subscription;
|
||||||
|
|
||||||
constructor(private store: Store<AppState>) {
|
constructor(private store: Store<AppState>) {
|
||||||
this.showUpdateAvailable$ = store.select(getShowAppUpdateAvailable);
|
this.showUpdateAvailableSubscription = store.select(getShowAppUpdateAvailable)
|
||||||
|
.subscribe(data => this.showUpdateAvailable = data);
|
||||||
|
this.updateInfo$ = store.select(getUpdateInfo);
|
||||||
this.deviceConfigurationLoaded$ = store.select(deviceConfigurationLoaded);
|
this.deviceConfigurationLoaded$ = store.select(deviceConfigurationLoaded);
|
||||||
this.runningInElectron$ = store.select(runningInElectron);
|
this.runningInElectron$ = store.select(runningInElectron);
|
||||||
this.saveToKeyboardStateSubscription = store.select(saveToKeyboardState)
|
this.saveToKeyboardStateSubscription = store.select(saveToKeyboardState)
|
||||||
@@ -58,6 +74,7 @@ export class MainAppComponent implements OnDestroy {
|
|||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.saveToKeyboardStateSubscription.unsubscribe();
|
this.saveToKeyboardStateSubscription.unsubscribe();
|
||||||
this.keypressCapturingSubscription.unsubscribe();
|
this.keypressCapturingSubscription.unsubscribe();
|
||||||
|
this.showUpdateAvailableSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('document:keydown', ['$event'])
|
@HostListener('document:keydown', ['$event'])
|
||||||
|
|||||||
@@ -4,10 +4,8 @@
|
|||||||
<span class="macro__name pane-title__name">Settings</span>
|
<span class="macro__name pane-title__name">Settings</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<auto-update-settings [version]="version"
|
<auto-update-settings [settings]="autoUpdateSettings$ | async"
|
||||||
[settings]="autoUpdateSettings$ | async"
|
|
||||||
[checkingForUpdate]="checkingForUpdate$ | async"
|
[checkingForUpdate]="checkingForUpdate$ | async"
|
||||||
(toggleCheckForUpdateOnStartUp)="toogleCheckForUpdateOnStartUp($event)"
|
(toggleCheckForUpdateOnStartUp)="toogleCheckForUpdateOnStartUp($event)"
|
||||||
(toggleUsePreReleaseUpdate)="toogleUsePreReleaseUpdate($event)"
|
(checkForUpdate)="checkForUpdate($event)">
|
||||||
(checkForUpdate)="checkForUpdate()">
|
|
||||||
</auto-update-settings>
|
</auto-update-settings>
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { AutoUpdateSettings } from 'uhk-common';
|
||||||
|
|
||||||
import { AppState, getAutoUpdateSettings, getCheckingForUpdate } from '../../../store';
|
import { AppState, getAutoUpdateSettings, getCheckingForUpdate } from '../../../store';
|
||||||
import {
|
import {
|
||||||
CheckForUpdateNowAction,
|
CheckForUpdateNowAction,
|
||||||
ToggleCheckForUpdateOnStartupAction,
|
ToggleCheckForUpdateOnStartupAction
|
||||||
TogglePreReleaseFlagAction
|
|
||||||
} from '../../../store/actions/auto-update-settings';
|
} from '../../../store/actions/auto-update-settings';
|
||||||
import { AutoUpdateSettings } from '../../../models/auto-update-settings';
|
|
||||||
import { getVersions } from '../../../util';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'settings',
|
selector: 'settings',
|
||||||
@@ -20,7 +18,6 @@ import { getVersions } from '../../../util';
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class SettingsComponent {
|
export class SettingsComponent {
|
||||||
version: string = getVersions().version;
|
|
||||||
autoUpdateSettings$: Observable<AutoUpdateSettings>;
|
autoUpdateSettings$: Observable<AutoUpdateSettings>;
|
||||||
checkingForUpdate$: Observable<boolean>;
|
checkingForUpdate$: Observable<boolean>;
|
||||||
|
|
||||||
@@ -33,11 +30,7 @@ export class SettingsComponent {
|
|||||||
this.store.dispatch(new ToggleCheckForUpdateOnStartupAction(value));
|
this.store.dispatch(new ToggleCheckForUpdateOnStartupAction(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
toogleUsePreReleaseUpdate(value: boolean) {
|
checkForUpdate(allowPrerelease: boolean): void {
|
||||||
this.store.dispatch(new TogglePreReleaseFlagAction(value));
|
this.store.dispatch(new CheckForUpdateNowAction(allowPrerelease));
|
||||||
}
|
|
||||||
|
|
||||||
checkForUpdate() {
|
|
||||||
this.store.dispatch(new CheckForUpdateNowAction());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,21 +9,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="checkbox">
|
<button class="btn btn-link" (click)="emitCheckForUpdate($event)">
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
[checked]="settings.usePreReleaseUpdate"
|
|
||||||
(change)="emitUsePreReleaseUpdate($event.target.checked)"> Allow alpha / pre release
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-sm-2 control-label">Version:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<p>{{version}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="btn btn-link" (click)="emitCheckForUpdate()">
|
|
||||||
Check for update
|
Check for update
|
||||||
<span *ngIf="checkingForUpdate"
|
<span *ngIf="checkingForUpdate"
|
||||||
class="fa fa-spinner fa-spin"></span>
|
class="fa fa-spinner fa-spin"></span>
|
||||||
|
|||||||
@@ -9,13 +9,11 @@ import { State } from '../../store/reducers/auto-update-settings';
|
|||||||
})
|
})
|
||||||
export class AutoUpdateSettings {
|
export class AutoUpdateSettings {
|
||||||
|
|
||||||
@Input() version: string;
|
|
||||||
@Input() settings: State | undefined;
|
@Input() settings: State | undefined;
|
||||||
@Input() checkingForUpdate: boolean;
|
@Input() checkingForUpdate: boolean;
|
||||||
|
|
||||||
@Output() toggleCheckForUpdateOnStartUp = new EventEmitter<boolean>();
|
@Output() toggleCheckForUpdateOnStartUp = new EventEmitter<boolean>();
|
||||||
@Output() toggleUsePreReleaseUpdate = new EventEmitter<boolean>();
|
@Output() checkForUpdate = new EventEmitter<boolean>();
|
||||||
@Output() checkForUpdate = new EventEmitter();
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
@@ -24,11 +22,7 @@ export class AutoUpdateSettings {
|
|||||||
this.toggleCheckForUpdateOnStartUp.emit(value);
|
this.toggleCheckForUpdateOnStartUp.emit(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitUsePreReleaseUpdate(value: boolean) {
|
emitCheckForUpdate($event: MouseEvent) {
|
||||||
this.toggleUsePreReleaseUpdate.emit(value);
|
this.checkForUpdate.emit($event.shiftKey);
|
||||||
}
|
|
||||||
|
|
||||||
emitCheckForUpdate() {
|
|
||||||
this.checkForUpdate.emit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,12 +136,12 @@
|
|||||||
(click)="toggleHide($event, 'agent')"></i>
|
(click)="toggleHide($event, 'agent')"></i>
|
||||||
</div>
|
</div>
|
||||||
<ul [@toggler]="animation['agent']">
|
<ul [@toggler]="animation['agent']">
|
||||||
<!--li class="sidebar__level-2--item">
|
<li class="sidebar__level-2--item">
|
||||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||||
<a [routerLink]="['/settings']"
|
<a [routerLink]="['/settings']"
|
||||||
[class.disabled]="state.updatingFirmware">Settings</a>
|
[class.disabled]="state.updatingFirmware">Settings</a>
|
||||||
</div>
|
</div>
|
||||||
</li-->
|
</li>
|
||||||
<li class="sidebar__level-2--item">
|
<li class="sidebar__level-2--item">
|
||||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||||
<a [routerLink]="['/help']"
|
<a [routerLink]="['/help']"
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
|
@import '../../../styles/common';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
border-right: 1px solid #ccc;
|
border-right: 1px solid #ccc;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
top: 0;
|
||||||
width: 250px;
|
width: 250px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
@include updatePanelVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -34,6 +39,7 @@ ul {
|
|||||||
&__level-0 {
|
&__level-0 {
|
||||||
padding: 0.5rem 1rem 0;
|
padding: 0.5rem 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__level-1 {
|
&__level-1 {
|
||||||
padding: 0.5rem 1rem 0.5rem 2rem;
|
padding: 0.5rem 1rem 0.5rem 2rem;
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-4
@@ -1,5 +1,15 @@
|
|||||||
<div class="app-update-available-wrapper">
|
<div class="app-update-available-wrapper" role="alert">
|
||||||
New version available.
|
Agent {{ updateInfo.version }} has been <span *ngIf="updateInfo.isPrerelease">pre-</span>released.
|
||||||
<button type="button" (click)="updateApp.emit()" class="btn btn-primary">Update</button>
|
|
||||||
<button type="button" (click)="doNotUpdateApp.emit()" class="btn btn-default">Close</button>
|
<button type="button"
|
||||||
|
class="btn btn-link underline"
|
||||||
|
(click)="updateApp.emit()" >Update now!</button>
|
||||||
|
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-link pull-right"
|
||||||
|
data-dismiss="alert"
|
||||||
|
aria-label="Close"
|
||||||
|
(click)="doNotUpdateApp.emit()">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+17
-3
@@ -1,5 +1,19 @@
|
|||||||
.app-update-available-wrapper {
|
.app-update-available-wrapper {
|
||||||
display: flex;
|
margin: 0;
|
||||||
justify-content: center;
|
padding-top: 5px;
|
||||||
margin: 0.5rem;
|
padding-bottom: 5px;
|
||||||
|
|
||||||
|
background-color: #428bca;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 0;
|
||||||
|
border-width: 0;
|
||||||
|
|
||||||
|
.btn-link {
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
&.underline {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { ChangeDetectionStrategy, Component, EventEmitter, Output } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
|
||||||
|
import { UpdateInfo } from '../../models/update-info';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-update-available',
|
selector: 'app-update-available',
|
||||||
@@ -7,6 +9,8 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Output } from '@angul
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class UpdateAvailableComponent {
|
export class UpdateAvailableComponent {
|
||||||
|
@Input() updateInfo: UpdateInfo;
|
||||||
|
|
||||||
@Output() updateApp = new EventEmitter<null>();
|
@Output() updateApp = new EventEmitter<null>();
|
||||||
@Output() doNotUpdateApp = new EventEmitter<null>();
|
@Output() doNotUpdateApp = new EventEmitter<null>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export interface UpdateInfo {
|
||||||
|
version: string;
|
||||||
|
isPrerelease: boolean;
|
||||||
|
}
|
||||||
@@ -32,8 +32,8 @@ export class AppUpdateRendererService {
|
|||||||
this.ipcRenderer.send(IpcEvents.autoUpdater.updateAndRestart);
|
this.ipcRenderer.send(IpcEvents.autoUpdater.updateAndRestart);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForUpdate() {
|
checkForUpdate(allowPrerelease: boolean): void {
|
||||||
this.ipcRenderer.send(IpcEvents.autoUpdater.checkForUpdate);
|
this.ipcRenderer.send(IpcEvents.autoUpdater.checkForUpdate, allowPrerelease);
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerEvents() {
|
private registerEvents() {
|
||||||
@@ -57,7 +57,7 @@ export class AppUpdateRendererService {
|
|||||||
|
|
||||||
this.ipcRenderer.on(IpcEvents.autoUpdater.autoUpdateDownloaded, (event: string, arg: any) => {
|
this.ipcRenderer.on(IpcEvents.autoUpdater.autoUpdateDownloaded, (event: string, arg: any) => {
|
||||||
this.writeUpdateState(IpcEvents.autoUpdater.autoUpdateDownloaded, arg);
|
this.writeUpdateState(IpcEvents.autoUpdater.autoUpdateDownloaded, arg);
|
||||||
this.dispachStoreAction(new UpdateDownloadedAction());
|
this.dispachStoreAction(new UpdateDownloadedAction(arg));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.ipcRenderer.on(IpcEvents.autoUpdater.checkForUpdateNotAvailable, (event: string, arg: any) => {
|
this.ipcRenderer.on(IpcEvents.autoUpdater.checkForUpdateNotAvailable, (event: string, arg: any) => {
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { UserConfiguration } from 'uhk-common';
|
import { AutoUpdateSettings, UserConfiguration } from 'uhk-common';
|
||||||
|
|
||||||
import { AutoUpdateSettings } from '../models/auto-update-settings';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DataStorageRepositoryService {
|
export class DataStorageRepositoryService {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Action } from '@ngrx/store';
|
import { Action } from '@ngrx/store';
|
||||||
import { type } from 'uhk-common';
|
import { type } from 'uhk-common';
|
||||||
|
import { UpdateInfo } from '../../models/update-info';
|
||||||
|
|
||||||
const PREFIX = '[app-update] ';
|
const PREFIX = '[app-update] ';
|
||||||
|
|
||||||
@@ -27,6 +28,9 @@ export class DoNotUpdateAppAction implements Action {
|
|||||||
|
|
||||||
export class UpdateDownloadedAction implements Action {
|
export class UpdateDownloadedAction implements Action {
|
||||||
type = ActionTypes.UPDATE_DOWNLOADED;
|
type = ActionTypes.UPDATE_DOWNLOADED;
|
||||||
|
|
||||||
|
constructor(public payload: UpdateInfo) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdatingAction implements Action {
|
export class UpdatingAction implements Action {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Action } from '@ngrx/store';
|
import { Action } from '@ngrx/store';
|
||||||
|
|
||||||
import { type } from 'uhk-common';
|
import { AutoUpdateSettings, type } from 'uhk-common';
|
||||||
import { AutoUpdateSettings } from '../../models/auto-update-settings';
|
|
||||||
|
|
||||||
const PREFIX = '[app-update-config] ';
|
const PREFIX = '[app-update-config] ';
|
||||||
|
|
||||||
@@ -26,6 +25,9 @@ export class ToggleCheckForUpdateOnStartupAction implements Action {
|
|||||||
|
|
||||||
export class CheckForUpdateNowAction implements Action {
|
export class CheckForUpdateNowAction implements Action {
|
||||||
type = ActionTypes.CHECK_FOR_UPDATE_NOW;
|
type = ActionTypes.CHECK_FOR_UPDATE_NOW;
|
||||||
|
|
||||||
|
constructor(public payload?: boolean) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CheckForUpdateSuccessAction implements Action {
|
export class CheckForUpdateSuccessAction implements Action {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { first, map, tap } from 'rxjs/operators';
|
|||||||
import { LogService, NotificationType } from 'uhk-common';
|
import { LogService, NotificationType } from 'uhk-common';
|
||||||
|
|
||||||
import { ActionTypes, UpdateErrorAction } from '../actions/app-update.action';
|
import { ActionTypes, UpdateErrorAction } from '../actions/app-update.action';
|
||||||
import { ActionTypes as AutoUpdateActionTypes } from '../actions/auto-update-settings';
|
import { ActionTypes as AutoUpdateActionTypes, CheckForUpdateNowAction } from '../actions/auto-update-settings';
|
||||||
import { ShowNotificationAction } from '../actions/app';
|
import { ShowNotificationAction } from '../actions/app';
|
||||||
import { AppUpdateRendererService } from '../../services/app-update-renderer.service';
|
import { AppUpdateRendererService } from '../../services/app-update-renderer.service';
|
||||||
|
|
||||||
@@ -23,12 +23,13 @@ export class AppUpdateEffect {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@Effect({ dispatch: false }) checkForUpdate$: Observable<Action> = this.actions$
|
@Effect({ dispatch: false }) checkForUpdate$ = this.actions$
|
||||||
.ofType(AutoUpdateActionTypes.CHECK_FOR_UPDATE_NOW)
|
.ofType<CheckForUpdateNowAction>(AutoUpdateActionTypes.CHECK_FOR_UPDATE_NOW)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(() => {
|
map(action => action.payload),
|
||||||
|
tap((allowPrerelease: boolean) => {
|
||||||
this.logService.debug('[AppUpdateEffect] call checkForUpdate');
|
this.logService.debug('[AppUpdateEffect] call checkForUpdate');
|
||||||
this.appUpdateRendererService.checkForUpdate();
|
this.appUpdateRendererService.checkForUpdate(allowPrerelease);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Observable } from 'rxjs/Observable';
|
|||||||
import { Action, Store } from '@ngrx/store';
|
import { Action, Store } from '@ngrx/store';
|
||||||
import { map, startWith, switchMap, withLatestFrom } from 'rxjs/operators';
|
import { map, startWith, switchMap, withLatestFrom } from 'rxjs/operators';
|
||||||
|
|
||||||
import { NotificationType } from 'uhk-common';
|
import { AutoUpdateSettings, NotificationType } from 'uhk-common';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActionTypes,
|
ActionTypes,
|
||||||
@@ -16,7 +16,6 @@ import {
|
|||||||
import { DataStorageRepositoryService } from '../../services/datastorage-repository.service';
|
import { DataStorageRepositoryService } from '../../services/datastorage-repository.service';
|
||||||
import { AppState, getAutoUpdateSettings } from '../index';
|
import { AppState, getAutoUpdateSettings } from '../index';
|
||||||
import { initialState } from '../reducers/auto-update-settings';
|
import { initialState } from '../reducers/auto-update-settings';
|
||||||
import { AutoUpdateSettings } from '../../models/auto-update-settings';
|
|
||||||
import { ShowNotificationAction } from '../actions/app';
|
import { ShowNotificationAction } from '../actions/app';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ export const firmwareUpgradeAllowed = createSelector(runningOnNotSupportedWindow
|
|||||||
|
|
||||||
export const appUpdateState = (state: AppState) => state.appUpdate;
|
export const appUpdateState = (state: AppState) => state.appUpdate;
|
||||||
export const getShowAppUpdateAvailable = createSelector(appUpdateState, fromAppUpdate.getShowAppUpdateAvailable);
|
export const getShowAppUpdateAvailable = createSelector(appUpdateState, fromAppUpdate.getShowAppUpdateAvailable);
|
||||||
|
export const getUpdateInfo = createSelector(appUpdateState, fromAppUpdate.getUpdateInfo);
|
||||||
|
|
||||||
export const appUpdateSettingsState = (state: AppState) => state.autoUpdateSettings;
|
export const appUpdateSettingsState = (state: AppState) => state.autoUpdateSettings;
|
||||||
export const getAutoUpdateSettings = createSelector(appUpdateSettingsState, autoUpdateSettings.getUpdateSettings);
|
export const getAutoUpdateSettings = createSelector(appUpdateSettingsState, autoUpdateSettings.getUpdateSettings);
|
||||||
|
|||||||
@@ -1,39 +1,48 @@
|
|||||||
import { Actions, ActionTypes } from '../actions/app-update.action';
|
import { Actions, ActionTypes, UpdateDownloadedAction } from '../actions/app-update.action';
|
||||||
|
import { UpdateInfo } from '../../models/update-info';
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
updateAvailable: boolean;
|
updateAvailable: boolean;
|
||||||
updateDownloaded: boolean;
|
updateDownloaded: boolean;
|
||||||
doNotUpdateApp: boolean;
|
doNotUpdateApp: boolean;
|
||||||
|
updateInfo: UpdateInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialState: State = {
|
export const initialState: State = {
|
||||||
updateAvailable: false,
|
updateAvailable: false,
|
||||||
updateDownloaded: false,
|
updateDownloaded: false,
|
||||||
doNotUpdateApp: false
|
doNotUpdateApp: false,
|
||||||
|
updateInfo: {
|
||||||
|
isPrerelease: false,
|
||||||
|
version: ''
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function reducer(state = initialState, action: Actions) {
|
export function reducer(state = initialState, action: Actions) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ActionTypes.UPDATE_AVAILABLE: {
|
case ActionTypes.UPDATE_AVAILABLE:
|
||||||
const newState = Object.assign({}, state);
|
return {
|
||||||
newState.updateAvailable = true;
|
...state,
|
||||||
return newState;
|
updateAvailable: true
|
||||||
}
|
};
|
||||||
|
|
||||||
case ActionTypes.UPDATE_DOWNLOADED: {
|
case ActionTypes.UPDATE_DOWNLOADED:
|
||||||
const newState = Object.assign({}, state);
|
return {
|
||||||
newState.updateDownloaded = true;
|
...state,
|
||||||
return newState;
|
updateDownloaded: true,
|
||||||
}
|
updateInfo: (action as UpdateDownloadedAction).payload
|
||||||
|
};
|
||||||
|
|
||||||
|
case ActionTypes.DO_NOT_UPDATE_APP:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
doNotUpdateApp: true
|
||||||
|
};
|
||||||
|
|
||||||
case ActionTypes.DO_NOT_UPDATE_APP: {
|
|
||||||
const newState = Object.assign({}, state);
|
|
||||||
newState.doNotUpdateApp = true;
|
|
||||||
return newState;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getShowAppUpdateAvailable = (state: State) => state.updateDownloaded && !state.doNotUpdateApp;
|
export const getShowAppUpdateAvailable = (state: State) => state.updateDownloaded && !state.doNotUpdateApp;
|
||||||
|
export const getUpdateInfo = (state: State) => state.updateInfo;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { Action } from '@ngrx/store';
|
import { Action } from '@ngrx/store';
|
||||||
|
import { AutoUpdateSettings } from 'uhk-common';
|
||||||
|
|
||||||
import { ActionTypes } from '../actions/auto-update-settings';
|
import { ActionTypes } from '../actions/auto-update-settings';
|
||||||
import { ActionTypes as UpdateActions } from '../actions/app-update.action';
|
import { ActionTypes as UpdateActions } from '../actions/app-update.action';
|
||||||
import { AutoUpdateSettings } from '../../models/auto-update-settings';
|
|
||||||
|
|
||||||
export interface State extends AutoUpdateSettings {
|
export interface State extends AutoUpdateSettings {
|
||||||
checkingForUpdate: boolean;
|
checkingForUpdate: boolean;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import * as storage from 'electron-settings';
|
import * as storage from 'electron-settings';
|
||||||
|
|
||||||
import { UserConfiguration } from 'uhk-common';
|
import { AutoUpdateSettings, UserConfiguration } from 'uhk-common';
|
||||||
import { DataStorageRepositoryService } from '../../app/services/datastorage-repository.service';
|
import { DataStorageRepositoryService } from '../../app/services/datastorage-repository.service';
|
||||||
import { AutoUpdateSettings } from '../../app/models/auto-update-settings';
|
|
||||||
|
|
||||||
export class ElectronDataStorageRepositoryService implements DataStorageRepositoryService {
|
export class ElectronDataStorageRepositoryService implements DataStorageRepositoryService {
|
||||||
static getValue(key: string): any {
|
static getValue(key: string): any {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ $zindex-navbar-fixed: 1030;
|
|||||||
@import '~spacing-bootstrap-3/spacing';
|
@import '~spacing-bootstrap-3/spacing';
|
||||||
|
|
||||||
@import './styles/variables';
|
@import './styles/variables';
|
||||||
|
@import './styles/common';
|
||||||
@import '~angular-notifier/styles';
|
@import '~angular-notifier/styles';
|
||||||
@import '~font-awesome/scss/font-awesome';
|
@import '~font-awesome/scss/font-awesome';
|
||||||
@import './styles/tooltip';
|
@import './styles/tooltip';
|
||||||
@@ -44,6 +45,9 @@ html, body {
|
|||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
@include updatePanelVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-page-content {
|
.main-page-content {
|
||||||
@@ -52,6 +56,15 @@ html, body {
|
|||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app-update-available {
|
||||||
|
position: fixed;
|
||||||
|
display: block;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 200;
|
||||||
|
}
|
||||||
|
|
||||||
.nav-pills > li > a {
|
.nav-pills > li > a {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,3 +12,6 @@ $tooltip-border-color: $dark-grey;
|
|||||||
$tooltip-background-color: #fff;
|
$tooltip-background-color: #fff;
|
||||||
$tooltip-inner-color: #000;
|
$tooltip-inner-color: #000;
|
||||||
$tooltip-arrow-border-width: $tooltip-arrow-width + $tooltip-border-width;
|
$tooltip-arrow-border-width: $tooltip-arrow-width + $tooltip-border-width;
|
||||||
|
|
||||||
|
$update-notification-height: 35px;
|
||||||
|
$main-content-top-margin-on-update: 35px + 10px;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import './variables';
|
||||||
|
|
||||||
%btn-link {
|
%btn-link {
|
||||||
padding: 7px 0;
|
padding: 7px 0;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -8,3 +10,15 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin updatePanelVisible() {
|
||||||
|
transition-timing-function: ease-out;
|
||||||
|
transition: 0.5s;
|
||||||
|
margin-top: 0;
|
||||||
|
|
||||||
|
&.update-panel-visible {
|
||||||
|
transition-timing-function: ease-in;
|
||||||
|
transition: 0.5s;
|
||||||
|
margin-top: $main-content-top-margin-on-update;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user