2017-06-27 13:00:55 +00:00
|
|
|
import * as React from 'react';
|
|
|
|
import * as ReactDOM from 'react-dom';
|
2017-07-25 06:06:59 +00:00
|
|
|
import {
|
|
|
|
applyMiddleware,
|
|
|
|
compose,
|
|
|
|
createStore,
|
|
|
|
GenericStoreEnhancer,
|
|
|
|
Middleware,
|
|
|
|
Store,
|
|
|
|
} from 'redux';
|
|
|
|
|
|
|
|
import {
|
|
|
|
Provider,
|
|
|
|
} from 'react-redux';
|
|
|
|
|
|
|
|
import {
|
|
|
|
ConnectedRouter,
|
|
|
|
routerMiddleware,
|
|
|
|
} from 'react-router-redux';
|
|
|
|
|
|
|
|
import createSagaMiddleware, {
|
|
|
|
SagaMiddleware,
|
2017-07-25 10:28:27 +00:00
|
|
|
SagaIterator,
|
2017-07-25 06:06:59 +00:00
|
|
|
} from 'redux-saga';
|
|
|
|
|
2017-07-25 10:28:27 +00:00
|
|
|
import {
|
|
|
|
fork,
|
|
|
|
} from 'redux-saga/effects';
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-07-25 06:06:59 +00:00
|
|
|
import {
|
|
|
|
createHashHistory,
|
|
|
|
History,
|
|
|
|
} from 'history';
|
|
|
|
|
|
|
|
import {
|
|
|
|
AppContainer,
|
|
|
|
} from 'react-hot-loader';
|
|
|
|
|
2017-07-21 07:08:04 +00:00
|
|
|
|
|
|
|
import * as injectTapEventPlugin from 'react-tap-event-plugin';
|
2017-07-03 10:47:54 +00:00
|
|
|
|
2017-07-03 10:21:42 +00:00
|
|
|
import Platform from '@overflow/commons/platform';
|
2017-07-20 09:46:42 +00:00
|
|
|
import AppContext from '@overflow/commons/context';
|
|
|
|
import * as AppContextLifecycleActions from '@overflow/commons/context/redux/action/lifecycle';
|
|
|
|
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
|
2017-07-25 06:06:59 +00:00
|
|
|
import ReducerContext from '@overflow/commons/redux/ReducerContext';
|
2017-07-25 10:28:27 +00:00
|
|
|
import { SagaWatcher } from '@overflow/commons/redux-saga';
|
2017-07-24 10:58:45 +00:00
|
|
|
|
2017-07-25 06:06:59 +00:00
|
|
|
import appConfig, { Config, ReduxState } from './config';
|
2017-07-20 09:46:42 +00:00
|
|
|
|
2017-07-21 05:57:12 +00:00
|
|
|
import App from './views/App';
|
2017-06-28 07:50:19 +00:00
|
|
|
|
2017-06-27 13:00:55 +00:00
|
|
|
injectTapEventPlugin();
|
|
|
|
|
2017-07-25 06:06:59 +00:00
|
|
|
// const isProduction:boolean = process.env.NODE_ENV === 'production' ? true : false;
|
|
|
|
// const useReduxDevTools = window.devToolsExtension && !isProduction ? true : false;
|
2017-07-20 09:46:42 +00:00
|
|
|
|
2017-07-21 05:57:12 +00:00
|
|
|
class Application {
|
2017-07-25 06:06:59 +00:00
|
|
|
private static isProduction:boolean = process.env.NODE_ENV === 'production' ? true : false;
|
|
|
|
private static useReduxDevTools:boolean = window.devToolsExtension && !Application.isProduction ? true : false;
|
|
|
|
|
2017-07-20 09:46:42 +00:00
|
|
|
private config: Config;
|
|
|
|
private container: HTMLElement;
|
|
|
|
private context: AppContext;
|
|
|
|
private rpcClient: WebSocketRPC;
|
|
|
|
private store: Store<any>;
|
|
|
|
private sagaMiddleware: SagaMiddleware<any>;
|
|
|
|
private history: History;
|
2017-07-25 06:06:59 +00:00
|
|
|
|
2017-07-20 09:46:42 +00:00
|
|
|
|
|
|
|
public constructor() {
|
|
|
|
this.config = appConfig;
|
2017-07-25 06:06:59 +00:00
|
|
|
this.history = createHashHistory();
|
2017-07-20 09:46:42 +00:00
|
|
|
}
|
|
|
|
|
2017-07-23 14:40:48 +00:00
|
|
|
public static Run(): void {
|
2017-07-21 08:10:06 +00:00
|
|
|
let application = new Application();
|
2017-07-23 14:40:48 +00:00
|
|
|
application.start();
|
2017-07-21 08:10:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private async start(): Promise<void> {
|
2017-07-20 09:46:42 +00:00
|
|
|
try {
|
|
|
|
this.container = await Platform.getAppContainer(this.config.container.placeholderID);
|
|
|
|
this.displayLoading();
|
|
|
|
|
|
|
|
this.context = await this.initContext();
|
2017-07-25 10:28:27 +00:00
|
|
|
this.rpcClient = await this.initRpcClient();
|
|
|
|
this.context.put(this.rpcClient);
|
2017-07-25 06:06:59 +00:00
|
|
|
|
|
|
|
await this.initRedux();
|
2017-07-20 09:46:42 +00:00
|
|
|
|
|
|
|
this.store.dispatch(AppContextLifecycleActions.initialized());
|
|
|
|
|
|
|
|
this.displayApp();
|
|
|
|
} catch (e) {
|
2017-07-21 05:57:12 +00:00
|
|
|
console.error(e);
|
2017-07-20 09:46:42 +00:00
|
|
|
this.displayError(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-21 08:10:06 +00:00
|
|
|
private initContext(): Promise<AppContext> {
|
2017-07-20 09:46:42 +00:00
|
|
|
const appContext = new Promise<AppContext>(resolve => {
|
|
|
|
const context = AppContext.getContext();
|
|
|
|
resolve(context);
|
|
|
|
});
|
|
|
|
|
|
|
|
return appContext;
|
|
|
|
}
|
|
|
|
|
2017-07-21 08:10:06 +00:00
|
|
|
private initRpcClient(): Promise<WebSocketRPC> {
|
2017-07-20 09:46:42 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-07-23 14:40:48 +00:00
|
|
|
private initRedux(): Promise<void> {
|
2017-07-24 10:58:45 +00:00
|
|
|
const init = new Promise<void>(resolve => {
|
|
|
|
// state tree
|
|
|
|
// reducer
|
2017-07-25 06:06:59 +00:00
|
|
|
for (let reducerMap of this.config.redux.reducerMaps) {
|
|
|
|
ReducerContext.putReducers(reducerMap);
|
|
|
|
}
|
2017-07-24 10:58:45 +00:00
|
|
|
// middleware
|
2017-07-25 06:06:59 +00:00
|
|
|
let middlewares: Middleware[] = new Array();
|
|
|
|
this.sagaMiddleware = createSagaMiddleware();
|
|
|
|
middlewares.push(this.sagaMiddleware);
|
|
|
|
|
|
|
|
let routerReduxMiddleware = routerMiddleware(this.history);
|
|
|
|
middlewares.push(routerReduxMiddleware);
|
|
|
|
|
|
|
|
// store
|
|
|
|
let middleware: GenericStoreEnhancer = applyMiddleware(...middlewares);
|
|
|
|
this.store = createStore(
|
|
|
|
ReducerContext.reducer,
|
|
|
|
this.config.redux.state,
|
|
|
|
Application.useReduxDevTools ? compose(middleware, window.devToolsExtension()) : middleware,
|
|
|
|
);
|
2017-07-24 10:58:45 +00:00
|
|
|
// saga
|
2017-07-25 10:28:27 +00:00
|
|
|
this.sagaMiddleware.run(this.initReduxSagaWarchers, this.config.redux.sagaWarchers);
|
2017-07-23 14:40:48 +00:00
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
|
2017-07-25 06:06:59 +00:00
|
|
|
return init;
|
2017-07-23 14:40:48 +00:00
|
|
|
}
|
2017-07-20 09:46:42 +00:00
|
|
|
|
2017-07-25 10:28:27 +00:00
|
|
|
private * initReduxSagaWarchers(sagaWarchers: (SagaWatcher[])[]): SagaIterator {
|
|
|
|
for (let sagaWarcher of sagaWarchers) {
|
|
|
|
for (let warcher of sagaWarcher) {
|
|
|
|
yield fork(warcher);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-20 09:46:42 +00:00
|
|
|
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 {
|
2017-07-25 06:06:59 +00:00
|
|
|
Application.isProduction ? this.displayProductionApp() : this.displayDebugApp();
|
2017-07-23 14:40:48 +00:00
|
|
|
}
|
|
|
|
private displayProductionApp(): void {
|
2017-07-20 09:46:42 +00:00
|
|
|
ReactDOM.render(
|
2017-07-21 07:08:04 +00:00
|
|
|
<Provider store={this.store}>
|
|
|
|
<ConnectedRouter history={this.history}>
|
|
|
|
<App />
|
|
|
|
</ConnectedRouter>
|
|
|
|
</Provider>,
|
2017-07-20 09:46:42 +00:00
|
|
|
this.container,
|
|
|
|
);
|
|
|
|
}
|
2017-07-23 14:40:48 +00:00
|
|
|
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,
|
|
|
|
);
|
|
|
|
}
|
2017-07-20 09:46:42 +00:00
|
|
|
|
2017-06-21 11:24:44 +00:00
|
|
|
}
|
|
|
|
|
2017-07-21 08:10:06 +00:00
|
|
|
Application.Run();
|