2015-06-18 04:04:28 +00:00
|
|
|
import React, { PropTypes } from 'react';
|
2016-06-01 22:52:08 +00:00
|
|
|
import { Button, Row } from 'react-bootstrap';
|
2016-01-07 22:51:41 +00:00
|
|
|
import { ToastMessage, ToastContainer } from 'react-toastr';
|
2016-01-27 19:34:44 +00:00
|
|
|
import { connect } from 'react-redux';
|
|
|
|
import { createSelector } from 'reselect';
|
|
|
|
|
2016-06-03 20:43:42 +00:00
|
|
|
import MapDrawer from './components/Map-Drawer.jsx';
|
2016-03-06 05:06:04 +00:00
|
|
|
import {
|
|
|
|
fetchUser,
|
2016-05-12 04:14:08 +00:00
|
|
|
initWindowHeight,
|
2016-06-03 20:43:42 +00:00
|
|
|
updateNavHeight,
|
2016-06-04 06:34:28 +00:00
|
|
|
toggleMapDrawer,
|
|
|
|
toggleMainChat
|
2016-03-06 05:06:04 +00:00
|
|
|
} from './redux/actions';
|
2015-06-18 04:04:28 +00:00
|
|
|
|
2016-06-01 22:52:08 +00:00
|
|
|
import { submitChallenge } from './routes/challenges/redux/actions';
|
|
|
|
|
2016-01-06 17:33:55 +00:00
|
|
|
import Nav from './components/Nav';
|
2016-06-01 22:52:08 +00:00
|
|
|
import { randomCompliment } from './utils/get-words';
|
2016-06-20 18:35:19 +00:00
|
|
|
import { userSelector } from './redux/selectors';
|
2015-06-18 04:04:28 +00:00
|
|
|
|
2016-01-07 22:51:41 +00:00
|
|
|
const toastMessageFactory = React.createFactory(ToastMessage.animation);
|
|
|
|
|
2016-01-27 19:34:44 +00:00
|
|
|
const mapStateToProps = createSelector(
|
2016-06-20 18:35:19 +00:00
|
|
|
userSelector,
|
|
|
|
state => state.app.shouldShowSignIn,
|
2016-06-01 22:52:08 +00:00
|
|
|
state => state.app.toast,
|
2016-06-03 20:43:42 +00:00
|
|
|
state => state.app.isMapDrawerOpen,
|
|
|
|
state => state.app.isMapAlreadyLoaded,
|
2016-06-01 22:52:08 +00:00
|
|
|
state => state.challengesApp.toast,
|
|
|
|
(
|
2016-06-20 18:35:19 +00:00
|
|
|
{ user: { username, points, picture } },
|
|
|
|
shouldShowSignIn,
|
2016-06-01 22:52:08 +00:00
|
|
|
toast,
|
2016-06-03 20:43:42 +00:00
|
|
|
isMapDrawerOpen,
|
|
|
|
isMapAlreadyLoaded,
|
2016-06-01 22:52:08 +00:00
|
|
|
showChallengeComplete
|
|
|
|
) => ({
|
2016-01-27 19:34:44 +00:00
|
|
|
username,
|
|
|
|
points,
|
|
|
|
picture,
|
2016-06-01 22:52:08 +00:00
|
|
|
toast,
|
2016-06-21 04:01:14 +00:00
|
|
|
shouldShowSignIn,
|
2016-06-03 20:43:42 +00:00
|
|
|
isMapDrawerOpen,
|
|
|
|
isMapAlreadyLoaded,
|
2016-06-21 04:01:14 +00:00
|
|
|
showChallengeComplete,
|
|
|
|
isSignedIn: !!username
|
2016-01-27 19:34:44 +00:00
|
|
|
})
|
|
|
|
);
|
|
|
|
|
2016-06-01 22:52:08 +00:00
|
|
|
const bindableActions = {
|
|
|
|
initWindowHeight,
|
|
|
|
updateNavHeight,
|
|
|
|
fetchUser,
|
2016-06-03 20:43:42 +00:00
|
|
|
submitChallenge,
|
2016-06-04 06:34:28 +00:00
|
|
|
toggleMapDrawer,
|
|
|
|
toggleMainChat
|
2016-06-01 22:52:08 +00:00
|
|
|
};
|
|
|
|
|
2016-01-27 19:34:44 +00:00
|
|
|
// export plain class for testing
|
|
|
|
export class FreeCodeCamp extends React.Component {
|
|
|
|
static displayName = 'FreeCodeCamp';
|
2016-06-28 03:11:52 +00:00
|
|
|
static contextTypes = {
|
|
|
|
router: PropTypes.object
|
|
|
|
};
|
2016-01-27 19:34:44 +00:00
|
|
|
static propTypes = {
|
|
|
|
children: PropTypes.node,
|
|
|
|
username: PropTypes.string,
|
2016-06-20 18:35:19 +00:00
|
|
|
isSignedIn: PropTypes.bool,
|
2016-01-27 19:34:44 +00:00
|
|
|
points: PropTypes.number,
|
|
|
|
picture: PropTypes.string,
|
2016-03-06 05:06:04 +00:00
|
|
|
toast: PropTypes.object,
|
|
|
|
updateNavHeight: PropTypes.func,
|
2016-06-01 22:52:08 +00:00
|
|
|
initWindowHeight: PropTypes.func,
|
|
|
|
showChallengeComplete: PropTypes.number,
|
2016-06-03 20:43:42 +00:00
|
|
|
submitChallenge: PropTypes.func,
|
|
|
|
isMapDrawerOpen: PropTypes.bool,
|
|
|
|
isMapAlreadyLoaded: PropTypes.bool,
|
2016-06-04 06:34:28 +00:00
|
|
|
toggleMapDrawer: PropTypes.func,
|
2016-06-20 18:35:19 +00:00
|
|
|
toggleMainChat: PropTypes.func,
|
|
|
|
fetchUser: PropTypes.func,
|
2016-06-28 03:11:52 +00:00
|
|
|
shouldShowSignIn: PropTypes.bool,
|
|
|
|
params: PropTypes.object
|
2016-01-27 19:34:44 +00:00
|
|
|
};
|
2015-07-29 17:16:48 +00:00
|
|
|
|
2016-06-01 22:52:08 +00:00
|
|
|
componentWillReceiveProps({
|
|
|
|
toast: nextToast = {},
|
|
|
|
showChallengeComplete: nextCC = 0
|
|
|
|
}) {
|
|
|
|
const {
|
|
|
|
toast = {},
|
|
|
|
showChallengeComplete
|
|
|
|
} = this.props;
|
2016-01-27 19:34:44 +00:00
|
|
|
if (toast.id !== nextToast.id) {
|
|
|
|
this.refs.toaster[nextToast.type || 'success'](
|
|
|
|
nextToast.message,
|
|
|
|
nextToast.title,
|
|
|
|
{
|
|
|
|
closeButton: true,
|
|
|
|
timeOut: 10000
|
|
|
|
}
|
2015-07-25 00:52:07 +00:00
|
|
|
);
|
|
|
|
}
|
2016-06-01 22:52:08 +00:00
|
|
|
|
|
|
|
if (nextCC !== showChallengeComplete) {
|
|
|
|
this.refs.toaster.success(
|
|
|
|
this.renderChallengeComplete(),
|
|
|
|
randomCompliment(),
|
|
|
|
{
|
|
|
|
closeButton: true,
|
|
|
|
timeOut: 0,
|
|
|
|
extendedTimeOut: 0
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2016-01-27 19:34:44 +00:00
|
|
|
}
|
|
|
|
|
2016-03-06 05:06:04 +00:00
|
|
|
componentDidMount() {
|
2016-05-12 04:14:08 +00:00
|
|
|
this.props.initWindowHeight();
|
2016-06-20 18:35:19 +00:00
|
|
|
if (!this.props.isSignedIn) {
|
|
|
|
this.props.fetchUser();
|
|
|
|
}
|
2016-03-06 05:06:04 +00:00
|
|
|
}
|
|
|
|
|
2016-06-01 22:52:08 +00:00
|
|
|
renderChallengeComplete() {
|
|
|
|
const { submitChallenge } = this.props;
|
|
|
|
return (
|
|
|
|
<Button
|
|
|
|
block={ true }
|
|
|
|
bsSize='small'
|
|
|
|
bsStyle='primary'
|
|
|
|
className='animated fadeIn'
|
|
|
|
onClick={ submitChallenge }
|
2016-06-15 01:47:43 +00:00
|
|
|
>
|
2016-06-01 22:52:08 +00:00
|
|
|
Submit and go to my next challenge
|
|
|
|
</Button>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-01-27 19:34:44 +00:00
|
|
|
render() {
|
2016-06-28 03:11:52 +00:00
|
|
|
const { router } = this.context;
|
2016-06-03 20:43:42 +00:00
|
|
|
const {
|
|
|
|
username,
|
|
|
|
points,
|
|
|
|
picture,
|
|
|
|
updateNavHeight,
|
|
|
|
isMapDrawerOpen,
|
|
|
|
isMapAlreadyLoaded,
|
2016-06-04 06:34:28 +00:00
|
|
|
toggleMapDrawer,
|
2016-06-20 18:35:19 +00:00
|
|
|
toggleMainChat,
|
2016-06-28 03:11:52 +00:00
|
|
|
shouldShowSignIn,
|
|
|
|
params: { lang }
|
2016-06-03 20:43:42 +00:00
|
|
|
} = this.props;
|
|
|
|
const navProps = {
|
2016-06-28 03:11:52 +00:00
|
|
|
isOnMap: router.isActive(`/${lang}/map`),
|
2016-06-03 20:43:42 +00:00
|
|
|
username,
|
|
|
|
points,
|
|
|
|
picture,
|
|
|
|
updateNavHeight,
|
2016-06-04 06:34:28 +00:00
|
|
|
toggleMapDrawer,
|
2016-06-20 18:35:19 +00:00
|
|
|
toggleMainChat,
|
|
|
|
shouldShowSignIn
|
2016-06-03 20:43:42 +00:00
|
|
|
};
|
2016-01-27 19:34:44 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<Nav { ...navProps }/>
|
|
|
|
<Row>
|
|
|
|
{ this.props.children }
|
|
|
|
</Row>
|
2016-06-03 20:43:42 +00:00
|
|
|
<MapDrawer
|
|
|
|
isAlreadyLoaded={ isMapAlreadyLoaded }
|
|
|
|
isOpen={ isMapDrawerOpen }
|
|
|
|
toggleMapDrawer={ toggleMapDrawer }
|
|
|
|
/>
|
2016-01-27 19:34:44 +00:00
|
|
|
<ToastContainer
|
|
|
|
className='toast-bottom-right'
|
|
|
|
ref='toaster'
|
2016-06-15 01:47:43 +00:00
|
|
|
toastMessageFactory={ toastMessageFactory }
|
|
|
|
/>
|
2016-01-27 19:34:44 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-20 18:35:19 +00:00
|
|
|
export default connect(
|
|
|
|
mapStateToProps,
|
|
|
|
bindableActions
|
|
|
|
)(FreeCodeCamp);
|