overflow_app/src/ts/@overflow/app/index.tsx
2017-07-24 19:58:45 +09:00

197 lines
4.8 KiB
TypeScript

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Provider, Store } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import createSagaMiddleware, { SagaMiddleware } from 'redux-saga';
import { History } from 'history';
import { AppContainer } from 'react-hot-loader';
import * as injectTapEventPlugin from 'react-tap-event-plugin';
import Platform from '@overflow/commons/platform';
import AppContext from '@overflow/commons/context';
import * as AppContextLifecycleActions from '@overflow/commons/context/redux/action/lifecycle';
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
import ReducerManager from '@overflow/commons/redux/ReducerManager';
import { store, sagaMiddleware, history } from './redux/store';
import appConfig, { Config } from './config';
import sagas from './redux/saga';
// import routes from './router';
import App from './views/App';
injectTapEventPlugin();
const isProduction:boolean = process.env.NODE_ENV === 'production' ? true : false;
class Application {
private config: Config;
private container: HTMLElement;
private context: AppContext;
private rpcClient: WebSocketRPC;
private store: Store<any>;
private sagaMiddleware: SagaMiddleware<any>;
private history: History;
private reducerManager: ReducerManager;
public constructor() {
this.config = appConfig;
this.sagaMiddleware = sagaMiddleware;
this.store = store;
this.history = history;
this.reducerManager = new ReducerManager();
}
public static Run(): void {
let application = new Application();
application.start();
}
private async start(): Promise<void> {
try {
this.container = await Platform.getAppContainer(this.config.container.placeholderID);
this.displayLoading();
this.context = await this.initContext();
// this.rpcClient = await this.initRpcClient();
await this.initSagaEffect();
this.store.dispatch(AppContextLifecycleActions.initialized());
this.displayApp();
} catch (e) {
console.error(e);
this.displayError(e);
}
}
private initContext(): Promise<AppContext> {
const appContext = new Promise<AppContext>(resolve => {
const context = AppContext.getContext();
resolve(context);
});
return appContext;
}
private initRpcClient(): Promise<WebSocketRPC> {
const rpcClient = new Promise<WebSocketRPC>((resolve, reject) => {
let client = new WebSocketRPC(this.config.rpc.url);
client.initialize()
.then(() => {
resolve(client);
})
.catch((err: any) => {
reject(err);
});
});
return rpcClient;
}
private initRedux(): Promise<void> {
const init = new Promise<void>(resolve => {
// state tree
// reducer
// middleware
// saga
});
return init;
}
private initSagaEffect(): Promise<void> {
const rpcClient = new Promise<void>(resolve => {
this.sagaMiddleware.run(sagas);
resolve();
});
return rpcClient;
}
private displayLoading(): void {
ReactDOM.render(
<div style={{
width: '100vw',
height: '100vh',
backgroundColor: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}>
<h1>Loading...</h1>
</div>,
this.container,
);
}
private displayError(e: Error): void {
ReactDOM.render(
<div style={{
width: '100vw',
height: '100vh',
backgroundColor: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}>
<h1>{e.message}</h1>
</div>,
this.container,
);
}
private displayApp(): void {
isProduction ? this.displayProductionApp() : this.displayDebugApp();
}
private displayProductionApp(): void {
ReactDOM.render(
<Provider store={this.store}>
<ConnectedRouter history={this.history}>
<App />
</ConnectedRouter>
</Provider>,
this.container,
);
}
private displayDebugApp(): void {
if (module.hot) {
module.hot.accept('./views/App', async () => {
const NextApp = (await import('./views/App')).default;
ReactDOM.render(
<AppContainer>
<Provider store={this.store}>
<ConnectedRouter history={this.history}>
<NextApp />
</ConnectedRouter>
</Provider>
</AppContainer>
,
this.container,
);
});
}
ReactDOM.render(
<AppContainer>
<Provider store={this.store}>
<ConnectedRouter history={this.history}>
<App />
</ConnectedRouter>
</Provider>
</AppContainer>
,
this.container,
);
}
}
Application.Run();