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