8a072eaac2507beb27a7d68ff71a27cc256a6f66
[oweals/peertube.git] / client / src / app / app.module.ts
1 import { ApplicationRef, NgModule } from '@angular/core';
2 import { BrowserModule } from '@angular/platform-browser';
3 import {
4   removeNgStyles,
5   createNewHosts,
6   createInputTransfer
7 } from '@angularclass/hmr';
8
9 import { MetaModule, MetaLoader, MetaStaticLoader, PageTitlePositioning } from '@nglibs/meta';
10 // TODO: remove, we need this to avoid error in ng2-smart-table
11 import 'rxjs/add/operator/toPromise';
12 import 'bootstrap-loader';
13
14 import { ENV_PROVIDERS } from './environment';
15 import { AppRoutingModule } from './app-routing.module';
16 import { AppComponent } from './app.component';
17 import { AppState, InternalStateType } from './app.service';
18
19 import { AccountModule } from './account';
20 import { CoreModule } from './core';
21 import { LoginModule } from './login';
22 import { SignupModule } from './signup';
23 import { SharedModule } from './shared';
24 import { VideosModule } from './videos';
25
26 export function metaFactory(): MetaLoader {
27   return new MetaStaticLoader({
28     pageTitlePositioning: PageTitlePositioning.PrependPageTitle,
29     pageTitleSeparator: ' - ',
30     applicationName: 'PeerTube',
31     defaults: {
32       title: 'PeerTube',
33       description: 'PeerTube, a decentralized video streaming platform using P2P (BitTorrent) directly in the web browser'
34     }
35   });
36 }
37
38 type StoreType = {
39   state: InternalStateType,
40   restoreInputValues: () => void,
41   disposeOldHosts: () => void
42 };
43
44 // Application wide providers
45 const APP_PROVIDERS = [
46   AppState
47 ];
48
49 @NgModule({
50   bootstrap: [ AppComponent ],
51   declarations: [
52     AppComponent
53   ],
54   imports: [
55     BrowserModule,
56
57     CoreModule,
58     SharedModule,
59
60     AppRoutingModule,
61
62     AccountModule,
63     CoreModule,
64     LoginModule,
65     SignupModule,
66     SharedModule,
67     VideosModule,
68
69     MetaModule.forRoot({
70       provide: MetaLoader,
71       useFactory: (metaFactory)
72     })
73   ],
74   providers: [ // expose our Services and Providers into Angular's dependency injection
75     ENV_PROVIDERS,
76     APP_PROVIDERS
77   ]
78 })
79 export class AppModule {
80   constructor(
81     public appRef: ApplicationRef,
82     public appState: AppState
83   ) {}
84
85   public hmrOnInit(store: StoreType) {
86     if (!store || !store.state) {
87       return;
88     }
89     console.log('HMR store', JSON.stringify(store, null, 2));
90     /**
91      * Set state
92      */
93     this.appState._state = store.state;
94     /**
95      * Set input values
96      */
97     if ('restoreInputValues' in store) {
98       let restoreInputValues = store.restoreInputValues;
99       setTimeout(restoreInputValues);
100     }
101
102     this.appRef.tick();
103     delete store.state;
104     delete store.restoreInputValues;
105   }
106
107   public hmrOnDestroy(store: StoreType) {
108     const cmpLocation = this.appRef.components.map((cmp) => cmp.location.nativeElement);
109     /**
110      * Save state
111      */
112     const state = this.appState._state;
113     store.state = state;
114     /**
115      * Recreate root elements
116      */
117     store.disposeOldHosts = createNewHosts(cmpLocation);
118     /**
119      * Save input values
120      */
121     store.restoreInputValues  = createInputTransfer();
122     /**
123      * Remove styles
124      */
125     removeNgStyles();
126   }
127
128   public hmrAfterDestroy(store: StoreType) {
129     /**
130      * Display new elements
131      */
132     store.disposeOldHosts();
133     delete store.disposeOldHosts;
134   }
135 }