From 8635a2c70cc24a4c52558162ac058de95750271f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 11 Jun 2017 12:28:22 +0200 Subject: Update client modules --- client/src/app/app.module.ts | 67 ++++++++++++++++++---- client/src/app/app.resolver.ts | 18 ++++++ client/src/app/app.service.ts | 20 +++++-- client/src/app/environment.ts | 54 +++++++++++------ .../videos/video-watch/video-watch.component.ts | 2 +- client/src/custom-typings.d.ts | 2 +- client/src/index.html | 6 +- client/src/main.browser.aot.ts | 24 +++++--- client/src/main.browser.ts | 27 +++++++-- 9 files changed, 170 insertions(+), 50 deletions(-) create mode 100644 client/src/app/app.resolver.ts (limited to 'client/src') diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index 7d1760fcd..8a072eaac 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts @@ -1,6 +1,10 @@ import { ApplicationRef, NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; -import { removeNgStyles, createNewHosts } from '@angularclass/hmr'; +import { + removeNgStyles, + createNewHosts, + createInputTransfer +} from '@angularclass/hmr'; import { MetaModule, MetaLoader, MetaStaticLoader, PageTitlePositioning } from '@nglibs/meta'; // TODO: remove, we need this to avoid error in ng2-smart-table @@ -10,7 +14,7 @@ import 'bootstrap-loader'; import { ENV_PROVIDERS } from './environment'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; -import { AppState } from './app.service'; +import { AppState, InternalStateType } from './app.service'; import { AccountModule } from './account'; import { CoreModule } from './core'; @@ -31,6 +35,12 @@ export function metaFactory(): MetaLoader { }); } +type StoreType = { + state: InternalStateType, + restoreInputValues: () => void, + disposeOldHosts: () => void +}; + // Application wide providers const APP_PROVIDERS = [ AppState @@ -67,25 +77,58 @@ const APP_PROVIDERS = [ ] }) export class AppModule { - constructor(public appRef: ApplicationRef, public appState: AppState) {} - hmrOnInit(store) { - if (!store || !store.state) return; - console.log('HMR store', store); + constructor( + public appRef: ApplicationRef, + public appState: AppState + ) {} + + public hmrOnInit(store: StoreType) { + if (!store || !store.state) { + return; + } + console.log('HMR store', JSON.stringify(store, null, 2)); + /** + * Set state + */ this.appState._state = store.state; + /** + * Set input values + */ + if ('restoreInputValues' in store) { + let restoreInputValues = store.restoreInputValues; + setTimeout(restoreInputValues); + } + this.appRef.tick(); delete store.state; + delete store.restoreInputValues; } - hmrOnDestroy(store) { - const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement); - // recreate elements + + public hmrOnDestroy(store: StoreType) { + const cmpLocation = this.appRef.components.map((cmp) => cmp.location.nativeElement); + /** + * Save state + */ const state = this.appState._state; store.state = state; + /** + * Recreate root elements + */ store.disposeOldHosts = createNewHosts(cmpLocation); - // remove styles + /** + * Save input values + */ + store.restoreInputValues = createInputTransfer(); + /** + * Remove styles + */ removeNgStyles(); } - hmrAfterDestroy(store) { - // display new elements + + public hmrAfterDestroy(store: StoreType) { + /** + * Display new elements + */ store.disposeOldHosts(); delete store.disposeOldHosts; } diff --git a/client/src/app/app.resolver.ts b/client/src/app/app.resolver.ts new file mode 100644 index 000000000..45774b8d1 --- /dev/null +++ b/client/src/app/app.resolver.ts @@ -0,0 +1,18 @@ +import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; + +@Injectable() +export class DataResolver implements Resolve { + public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + return Observable.of({ res: 'I am data'}); + } +} + +/** + * An array of services to resolve routes with data. + */ +export const APP_RESOLVER_PROVIDERS = [ + DataResolver +]; diff --git a/client/src/app/app.service.ts b/client/src/app/app.service.ts index 9b582e472..a7eb880a4 100644 --- a/client/src/app/app.service.ts +++ b/client/src/app/app.service.ts @@ -9,28 +9,38 @@ export class AppState { public _state: InternalStateType = { }; - // already return a clone of the current state + /** + * Already return a clone of the current state. + */ public get state() { return this._state = this._clone(this._state); } - // never allow mutation + /** + * Never allow mutation + */ public set state(value) { throw new Error('do not mutate the `.state` directly'); } public get(prop?: any) { - // use our state getter for the clone + /** + * Use our state getter for the clone. + */ const state = this.state; return state.hasOwnProperty(prop) ? state[prop] : state; } public set(prop: string, value: any) { - // internally mutate our state + /** + * Internally mutate our state. + */ return this._state[prop] = value; } private _clone(object: InternalStateType) { - // simple object clone + /** + * Simple object clone. + */ return JSON.parse(JSON.stringify( object )); } } diff --git a/client/src/app/environment.ts b/client/src/app/environment.ts index 929e09490..799102d82 100644 --- a/client/src/app/environment.ts +++ b/client/src/app/environment.ts @@ -1,21 +1,35 @@ - -// Angular 2 -// rc2 workaround -import { enableDebugTools, disableDebugTools } from '@angular/platform-browser'; -import { enableProdMode, ApplicationRef } from '@angular/core'; -// Environment Providers +/** + * Angular 2 + */ +import { + enableDebugTools, + disableDebugTools +} from '@angular/platform-browser'; +import { + ApplicationRef, + enableProdMode +} from '@angular/core'; +/** + * Environment Providers + */ let PROVIDERS: any[] = [ - // common env directives + /** + * Common env directives + */ ]; -// Angular debug tools in the dev console -// https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md -let _decorateModuleRef = function identity(value: T): T { return value; }; +/** + * Angular debug tools in the dev console + * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md + */ +let _decorateModuleRef = (value: T): T => { return value; }; if ('production' === ENV) { enableProdMode(); - // Production + /** + * Production + */ _decorateModuleRef = (modRef: any) => { disableDebugTools(); @@ -24,7 +38,9 @@ if ('production' === ENV) { PROVIDERS = [ ...PROVIDERS, - // custom providers in production + /** + * Custom providers in production. + */ ]; } else { @@ -33,17 +49,21 @@ if ('production' === ENV) { const appRef = modRef.injector.get(ApplicationRef); const cmpRef = appRef.components[0]; - let _ng = (window).ng; + let _ng = ( window).ng; enableDebugTools(cmpRef); - (window).ng.probe = _ng.probe; - (window).ng.coreTokens = _ng.coreTokens; + ( window).ng.probe = _ng.probe; + ( window).ng.coreTokens = _ng.coreTokens; return modRef; }; - // Development + /** + * Development + */ PROVIDERS = [ ...PROVIDERS, - // custom providers in development + /** + * Custom providers in development. + */ ]; } diff --git a/client/src/app/videos/video-watch/video-watch.component.ts b/client/src/app/videos/video-watch/video-watch.component.ts index d4b60b001..32c847785 100644 --- a/client/src/app/videos/video-watch/video-watch.component.ts +++ b/client/src/app/videos/video-watch/video-watch.component.ts @@ -31,7 +31,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { error: boolean = false; loading: boolean = false; numPeers: number; - player: VideoJSPlayer; + player: videojs.Player; playerElement: Element; uploadSpeed: number; userRating: RateType = null; diff --git a/client/src/custom-typings.d.ts b/client/src/custom-typings.d.ts index 7cb57b62b..621a416b4 100644 --- a/client/src/custom-typings.d.ts +++ b/client/src/custom-typings.d.ts @@ -83,7 +83,7 @@ type AsyncRoutes = { [component: string]: Es6PromiseLoader | Function | FactoryEs6PromiseLoader | - FactoryPromise + FactoryPromise ; }; type IdleCallbacks = Es6PromiseLoader | diff --git a/client/src/index.html b/client/src/index.html index 07658bbb7..e18b83dc8 100644 --- a/client/src/index.html +++ b/client/src/index.html @@ -11,13 +11,15 @@ - - + + + + <%= htmlWebpackPlugin.files.webpackManifest %> diff --git a/client/src/main.browser.aot.ts b/client/src/main.browser.aot.ts index 29ecf7349..718cb3a80 100644 --- a/client/src/main.browser.aot.ts +++ b/client/src/main.browser.aot.ts @@ -1,13 +1,14 @@ import { platformBrowser } from '@angular/platform-browser'; import { decorateModuleRef } from './app/environment'; -/* + +/** * App Module - * our top level module that holds all of our components + * our top level module that holds all of our components. */ import { AppModuleNgFactory } from '../compiled/src/app/app.module.ngfactory'; -/* - * Bootstrap our Angular app with a top level NgModule +/** + * Bootstrap our Angular app with a top level NgModule. */ export function main(): Promise { return platformBrowser() @@ -16,8 +17,17 @@ export function main(): Promise { .catch((err) => console.error(err)); } -export function bootstrapDomReady() { - document.addEventListener('DOMContentLoaded', main); +switch (document.readyState) { + case 'loading': + document.addEventListener('DOMContentLoaded', _domReadyHandler, false); + break; + case 'interactive': + case 'complete': + default: + main(); } -bootstrapDomReady(); +function _domReadyHandler() { + document.removeEventListener('DOMContentLoaded', _domReadyHandler, false); + main(); +} diff --git a/client/src/main.browser.ts b/client/src/main.browser.ts index 70bf48537..f627ba7df 100644 --- a/client/src/main.browser.ts +++ b/client/src/main.browser.ts @@ -1,20 +1,37 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { decorateModuleRef } from './app/environment'; -import { bootloader } from '@angularclass/hmr'; -/* + +/** * App Module * our top level module that holds all of our components */ import { AppModule } from './app'; -/* +/** * Bootstrap our Angular app with a top level NgModule */ export function main(): Promise { return platformBrowserDynamic() .bootstrapModule(AppModule) .then(decorateModuleRef) - .catch(err => console.error(err)); + .catch((err) => console.error(err)); } -bootloader(main); +/** + * Needed for hmr + * in prod this is replace for document ready + */ +switch (document.readyState) { + case 'loading': + document.addEventListener('DOMContentLoaded', _domReadyHandler, false); + break; + case 'interactive': + case 'complete': + default: + main(); +} + +function _domReadyHandler() { + document.removeEventListener('DOMContentLoaded', _domReadyHandler, false); + main(); +} -- cgit v1.2.3