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