Created
February 25, 2017 16:49
-
-
Save originalmoose/65ab88ad4930f731c6cd701d14eaeae3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from "react"; | |
import { observer } from "mobx-react"; | |
import inject from "../store/Inject"; | |
import { addTask } from "../module/task"; | |
import { add, exists, fetch } from "../module/cache" | |
import { Match, Redirect } from "react-router"; | |
import { default as load } from "../module/load"; | |
import { ApplicationStore } from "../store/ApplicationStore"; | |
import { UserStoreKey, UserStoreStructure } from "../store/UserStore"; | |
function isNode() { | |
return typeof global === 'object' && typeof process === 'object' | |
&& Object.prototype.toString.call(process) === '[object process]'; | |
} | |
interface NestedProps { | |
module: () => Promise<any>; | |
render: (props) => (module) => any; | |
/** | |
* This is injected by mobx-react Provider | |
*/ | |
store?: ApplicationStore; | |
} | |
interface NestedState { | |
module: React.ReactType; | |
} | |
/** | |
* This class is for internal use by LazyRoute. | |
*/ | |
@observer | |
class Nested extends React.Component<NestedProps, NestedState>{ | |
state: NestedState = { | |
module: null | |
}; | |
_isMounted: boolean; | |
componentWillMount() { | |
this._isMounted = true; | |
if (exists(module, this.props.module)) { | |
const {info, loadedModule} = fetch(module, this.props.module); | |
this.setState({ module: loadedModule }); | |
} else { | |
console.log("async route load"); | |
var task = load<React.ReactType>(module, this.props.module)(this.props.module()).then(({ info, module: loadedModule }) => { | |
add(module, this.props.module, { info, loadedModule }); | |
if (!isNode()) { | |
if (this._isMounted) { | |
this.setState({ module: loadedModule }); | |
} | |
} | |
}); | |
addTask(task); | |
} | |
} | |
componentWillUnmount() { | |
this._isMounted = false; | |
} | |
render() { | |
let { | |
render, | |
module, | |
} = this.props; | |
return render(this.props)(this.state.module); | |
} | |
} | |
interface LazyRouteProps { | |
pattern: string; | |
module: () => Promise<any>; | |
/* | |
Defaults True - redirects to login when user is not logged in | |
When False - redirects to home page when user is logged in (only used on the login page and pages that should only be viewed by non logged in users) | |
*/ | |
onlyAuthorizedUsers?: boolean; | |
exactly?: boolean; | |
render?: (props) => (module) => any; | |
} | |
interface LazyRouteStores { | |
stores: UserStoreStructure; | |
} | |
@observer | |
class LazyRoute extends React.Component<LazyRouteProps & LazyRouteStores, {}> { | |
static defaultProps: any = { | |
render: props => Component => Component && Component.default ? <Component.default {...props} /> : null, | |
onlyAuthorizedUsers: true, | |
}; | |
render() { | |
const {children, onlyAuthorizedUsers, stores: {user}} = this.props; | |
return ( | |
<Match | |
pattern={this.props.pattern} | |
exactly={this.props.exactly} | |
render={props => { | |
var nested = <Nested {...props} module={this.props.module} render={this.props.render} />; | |
return onlyAuthorizedUsers ? | |
(user.isLoggedIn ? | |
nested : | |
<Redirect to={{ pathname: '/login', state: { from: props.location } }} />) : | |
(!user.isLoggedIn ? | |
nested : | |
<Redirect to="/" />) | |
} | |
} | |
/> | |
); | |
} | |
} | |
export default inject<LazyRouteProps, LazyRouteStores>(UserStoreKey)(LazyRoute); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment