aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/app.module.ts
blob: e71641e0dbd3fe774979bd880bea006ae64947df (plain) (blame)
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
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'

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
  ],
  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
  }
}