diff --git a/.stylelintrc.json b/.stylelintrc.json index 6dd36550..3e1a34b2 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -26,7 +26,7 @@ "unit-case": "lower", "unit-no-unknown": true, - "unit-whitelist": ["px", "%", "deg", "ms", "em", "rem", "vh", "vv"], + "unit-whitelist": ["px", "%", "deg", "ms", "em", "rem", "vh", "vv", "s"], "value-list-comma-space-after": "always-single-line", "value-list-comma-space-before": "never", diff --git a/packages/uhk-web/src/app/app.component.html b/packages/uhk-web/src/app/app.component.html index 965f6c80..16b5923f 100644 --- a/packages/uhk-web/src/app/app.component.html +++ b/packages/uhk-web/src/app/app.component.html @@ -3,7 +3,7 @@ (doNotUpdateApp)="doNotUpdateApp()"> - +
diff --git a/packages/uhk-web/src/app/app.component.ts b/packages/uhk-web/src/app/app.component.ts index 955c6c95..f23cd814 100644 --- a/packages/uhk-web/src/app/app.component.ts +++ b/packages/uhk-web/src/app/app.component.ts @@ -9,7 +9,7 @@ import { DoNotUpdateAppAction, UpdateAppAction } from './store/actions/app-updat import { AppState, getShowAppUpdateAvailable, - deviceConnected, + deviceConfigurationLoaded, runningInElectron, saveToKeyboardState } from './store'; @@ -37,13 +37,13 @@ import { SaveUserConfigInBinaryFileAction, SaveUserConfigInJsonFileAction } from }) export class MainAppComponent { showUpdateAvailable$: Observable; - deviceConnected$: Observable; + deviceConfigurationLoaded$: Observable; runningInElectron$: Observable; saveToKeyboardState$: Observable; constructor(private store: Store) { this.showUpdateAvailable$ = store.select(getShowAppUpdateAvailable); - this.deviceConnected$ = store.select(deviceConnected); + this.deviceConfigurationLoaded$ = store.select(deviceConfigurationLoaded); this.runningInElectron$ = store.select(runningInElectron); this.saveToKeyboardState$ = store.select(saveToKeyboardState); } diff --git a/packages/uhk-web/src/app/app.routes.ts b/packages/uhk-web/src/app/app.routes.ts index e44a1989..365d3263 100644 --- a/packages/uhk-web/src/app/app.routes.ts +++ b/packages/uhk-web/src/app/app.routes.ts @@ -13,6 +13,9 @@ import { UhkDeviceUninitializedGuard } from './services/uhk-device-uninitialized import { UhkDeviceInitializedGuard } from './services/uhk-device-initialized.guard'; import { MainPage } from './pages/main-page/main.page'; import { settingsRoutes } from './components/settings/settings.routes'; +import { LoadingDevicePageComponent } from './pages/loading-page/loading-device.page'; +import { UhkDeviceLoadingGuard } from './services/uhk-device-loading.guard'; +import { UhkDeviceLoadedGuard } from './services/uhk-device-loaded.guard'; const appRoutes: Routes = [ { @@ -25,10 +28,15 @@ const appRoutes: Routes = [ component: PrivilegeCheckerComponent, canActivate: [UhkDeviceInitializedGuard] }, + { + path: 'loading', + component: LoadingDevicePageComponent, + canActivate: [UhkDeviceLoadedGuard] + }, { path: '', component: MainPage, - canActivate: [UhkDeviceDisconnectedGuard], + canActivate: [UhkDeviceDisconnectedGuard, UhkDeviceLoadingGuard], children: [ ...deviceRoutes, ...keymapRoutes, diff --git a/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.html b/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.html index b1a01afc..d4a553d3 100644 --- a/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.html +++ b/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.html @@ -1,5 +1,7 @@ - +

{{ title }}

{{ subtitle }}

diff --git a/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.scss b/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.scss index bfcaeac4..56f930ab 100644 --- a/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.scss +++ b/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.scss @@ -17,3 +17,23 @@ margin-top: 10px; } } + +.spin-logo { + -webkit-animation: spin 2s ease-in-out infinite; + -moz-animation: spin 2s ease-in-out infinite; + animation: spin 2s ease-in-out infinite; +} + +@keyframes spin { + 0% { + transform: rotate(0); + } + + 50% { + transform: rotate(360deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.ts b/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.ts index 8e070458..f22885b2 100644 --- a/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.ts +++ b/packages/uhk-web/src/app/components/uhk-message/uhk-message.component.ts @@ -9,4 +9,5 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; export class UhkMessageComponent { @Input() title: string; @Input() subtitle: string; + @Input() rotateLogo = false; } diff --git a/packages/uhk-web/src/app/pages/loading-page/loading-device.page.ts b/packages/uhk-web/src/app/pages/loading-page/loading-device.page.ts new file mode 100644 index 00000000..604009c7 --- /dev/null +++ b/packages/uhk-web/src/app/pages/loading-page/loading-device.page.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'loading-device', + template: ` + + ` +}) +export class LoadingDevicePageComponent { + + constructor() { + } +} diff --git a/packages/uhk-web/src/app/services/uhk-device-loaded.guard.ts b/packages/uhk-web/src/app/services/uhk-device-loaded.guard.ts new file mode 100644 index 00000000..919524b7 --- /dev/null +++ b/packages/uhk-web/src/app/services/uhk-device-loaded.guard.ts @@ -0,0 +1,25 @@ +import { CanActivate, Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { Injectable } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/map'; + +import { AppState, deviceConfigurationLoaded } from '../store'; + +@Injectable() +export class UhkDeviceLoadedGuard implements CanActivate { + + constructor(private store: Store, private router: Router) { } + + canActivate(): Observable { + return this.store.select(deviceConfigurationLoaded) + .do(loaded => { + if (loaded) { + this.router.navigate(['/']); + } + }) + .map(loaded => !loaded); + } +} diff --git a/packages/uhk-web/src/app/services/uhk-device-loading.guard.ts b/packages/uhk-web/src/app/services/uhk-device-loading.guard.ts new file mode 100644 index 00000000..debf0e77 --- /dev/null +++ b/packages/uhk-web/src/app/services/uhk-device-loading.guard.ts @@ -0,0 +1,23 @@ +import { CanActivate, Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { Injectable } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/do'; + +import { AppState, deviceConfigurationLoaded } from '../store'; + +@Injectable() +export class UhkDeviceLoadingGuard implements CanActivate { + + constructor(private store: Store, private router: Router) { } + + canActivate(): Observable { + return this.store.select(deviceConfigurationLoaded) + .do(loaded => { + if (!loaded) { + this.router.navigate(['/loading']); + } + }); + } +} diff --git a/packages/uhk-web/src/app/shared.module.ts b/packages/uhk-web/src/app/shared.module.ts index 9e30c1b2..1c74e7ba 100644 --- a/packages/uhk-web/src/app/shared.module.ts +++ b/packages/uhk-web/src/app/shared.module.ts @@ -85,11 +85,13 @@ import { UhkDeviceConnectedGuard } from './services/uhk-device-connected.guard'; import { UhkDeviceDisconnectedGuard } from './services/uhk-device-disconnected.guard'; import { UhkDeviceUninitializedGuard } from './services/uhk-device-uninitialized.guard'; import { MainPage } from './pages/main-page/main.page'; -import { DeviceEffects } from './store/effects/device'; import { DeviceRendererService } from './services/device-renderer.service'; import { UhkDeviceInitializedGuard } from './services/uhk-device-initialized.guard'; import { ProgressButtonComponent } from './components/progress-button/progress-button.component'; import { MainAppComponent } from './app.component'; +import { LoadingDevicePageComponent } from './pages/loading-page/loading-device.page'; +import { UhkDeviceLoadingGuard } from './services/uhk-device-loading.guard'; +import { UhkDeviceLoadedGuard } from './services/uhk-device-loaded.guard'; @NgModule({ declarations: [ @@ -151,7 +153,8 @@ import { MainAppComponent } from './app.component'; MissingDeviceComponent, PrivilegeCheckerComponent, MainPage, - ProgressButtonComponent + ProgressButtonComponent, + LoadingDevicePageComponent ], imports: [ CommonModule, @@ -180,7 +183,9 @@ import { MainAppComponent } from './app.component'; UhkDeviceConnectedGuard, UhkDeviceDisconnectedGuard, UhkDeviceInitializedGuard, - UhkDeviceUninitializedGuard + UhkDeviceUninitializedGuard, + UhkDeviceLoadingGuard, + UhkDeviceLoadedGuard ], exports: [ UhkMessageComponent, diff --git a/packages/uhk-web/src/app/store/effects/user-config.ts b/packages/uhk-web/src/app/store/effects/user-config.ts index a5809de0..c8db015a 100644 --- a/packages/uhk-web/src/app/store/effects/user-config.ts +++ b/packages/uhk-web/src/app/store/effects/user-config.ts @@ -135,6 +135,7 @@ export class UserConfigEffects { try { const userConfig = UserConfigEffects.getUserConfigFromDeviceResponse(data.userConfiguration); const hardwareConfig = UserConfigEffects.getHardwareConfigFromDeviceResponse(data.hardwareConfiguration); + this.router.navigate(['/']); return [ new LoadUserConfigSuccessAction(userConfig), diff --git a/packages/uhk-web/src/app/store/index.ts b/packages/uhk-web/src/app/store/index.ts index 1fa72537..6499e373 100644 --- a/packages/uhk-web/src/app/store/index.ts +++ b/packages/uhk-web/src/app/store/index.ts @@ -47,6 +47,7 @@ export const getPrevUserConfiguration = createSelector(appState, fromApp.getPrev export const runningInElectron = createSelector(appState, fromApp.runningInElectron); export const getHardwareConfiguration = createSelector(appState, fromApp.getHardwareConfiguration); export const getKeyboardLayout = createSelector(appState, fromApp.getKeyboardLayout); +export const deviceConfigurationLoaded = createSelector(appState, fromApp.deviceConfigurationLoaded); export const appUpdateState = (state: AppState) => state.appUpdate; export const getShowAppUpdateAvailable = createSelector(appUpdateState, fromAppUpdate.getShowAppUpdateAvailable); diff --git a/packages/uhk-web/src/app/store/reducers/app.reducer.ts b/packages/uhk-web/src/app/store/reducers/app.reducer.ts index 41230187..4b827927 100644 --- a/packages/uhk-web/src/app/store/reducers/app.reducer.ts +++ b/packages/uhk-web/src/app/store/reducers/app.reducer.ts @@ -4,6 +4,7 @@ import { Action } from '@ngrx/store'; import { HardwareConfiguration, runInElectron, Notification, NotificationType, UserConfiguration } from 'uhk-common'; import { ActionTypes, ShowNotificationAction } from '../actions/app'; import { ActionTypes as UserConfigActionTypes } from '../actions/user-config'; +import { ActionTypes as DeviceActionTypes } from '../actions/device'; import { KeyboardLayout } from '../../keyboard/keyboard-layout.enum'; export interface State { @@ -57,7 +58,7 @@ export function reducer(state = initialState, action: Action & { payload: any }) // When deleted a keymap or macro the app automaticaly navigate to other keymap, or macro, so // so we have to count the navigations and when reach the 2nd then remove the dialog. case ROUTER_NAVIGATION: { - const newState = { ...state }; + const newState = {...state}; newState.navigationCountAfterNotification++; if (newState.navigationCountAfterNotification > 1) { @@ -98,6 +99,17 @@ export function reducer(state = initialState, action: Action & { payload: any }) hardwareConfig: action.payload }; + case DeviceActionTypes.CONNECTION_STATE_CHANGED: + + if (action.payload === true) { + return state; + } + + return { + ...state, + hardwareConfig: null + }; + default: return state; } @@ -115,3 +127,4 @@ export const getKeyboardLayout = (state: State): KeyboardLayout => { return KeyboardLayout.ANSI; }; +export const deviceConfigurationLoaded = (state: State) => !state.runningInElectron ? true : !!state.hardwareConfig;