Render Hikes questions
This commit is contained in:
@ -4,10 +4,18 @@ import types from './types';
|
||||
// updateTitle(title: String) => Action
|
||||
export const updateTitle = createAction(types.updateTitle);
|
||||
|
||||
let id = 0;
|
||||
// makeToast({ type?: String, message: String, title: String }) => Action
|
||||
export const makeToast = createAction(
|
||||
types.makeToast,
|
||||
toast => toast.type ? toast : (toast.type = 'info', toast)
|
||||
toast => {
|
||||
id += 1;
|
||||
return {
|
||||
...toast,
|
||||
id,
|
||||
type: toast.type || 'info'
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// fetchUser() => Action
|
||||
|
@ -10,10 +10,7 @@ export default handleActions(
|
||||
|
||||
[types.makeToast]: (state, { payload: toast }) => ({
|
||||
...state,
|
||||
toast: {
|
||||
...toast,
|
||||
id: state.toast && state.toast.id ? state.toast.id : 1
|
||||
}
|
||||
toast
|
||||
}),
|
||||
|
||||
[types.setUser]: (state, { payload: user }) => ({ ...state, ...user }),
|
||||
|
@ -6,18 +6,15 @@ import { createSelector } from 'reselect';
|
||||
import Lecture from './Lecture.jsx';
|
||||
import Questions from './Questions.jsx';
|
||||
import { resetHike } from '../redux/actions';
|
||||
import { getCurrentHike } from '../redux/selectors';
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
state => state.hikesApp.hikes.entities,
|
||||
state => state.hikesApp.currentHike,
|
||||
state => state.hikesApp,
|
||||
(hikes, currentHikeDashedName, { shouldShowQuestions }) => {
|
||||
const currentHike = hikes[currentHikeDashedName];
|
||||
return {
|
||||
title: currentHike ? currentHike.title : '',
|
||||
shouldShowQuestions
|
||||
};
|
||||
}
|
||||
getCurrentHike,
|
||||
state => state.hikesApp.shouldShowQuestions,
|
||||
(currentHike, shouldShowQuestions) => ({
|
||||
title: currentHike ? currentHike.title : '',
|
||||
shouldShowQuestions
|
||||
})
|
||||
);
|
||||
|
||||
// export plain component for testing
|
||||
|
@ -2,7 +2,7 @@ import React, { PropTypes } from 'react';
|
||||
import { compose } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { Row } from 'react-bootstrap';
|
||||
import shouldComponentUpdate from 'react-pure-render/function';
|
||||
import PureComponent from 'react-pure-render/component';
|
||||
import { createSelector } from 'reselect';
|
||||
// import debug from 'debug';
|
||||
|
||||
@ -15,13 +15,14 @@ import contain from '../../../utils/professor-x';
|
||||
// const log = debug('fcc:hikes');
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
state => state.hikesApp.hikes,
|
||||
hikes => {
|
||||
if (!hikes || !hikes.entities || !hikes.results) {
|
||||
state => state.hikesApp.hikes.entities,
|
||||
state => state.hikesApp.hikes.results,
|
||||
(hikesMap, hikesByDashedName)=> {
|
||||
if (!hikesMap || !hikesByDashedName) {
|
||||
return { hikes: [] };
|
||||
}
|
||||
return {
|
||||
hikes: hikes.results.map(dashedName => hikes.entities[dashedName])
|
||||
hikes: hikesByDashedName.map(dashedName => hikesMap[dashedName])
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -36,7 +37,7 @@ const fetchOptions = {
|
||||
}
|
||||
};
|
||||
|
||||
export class Hikes extends React.Component {
|
||||
export class Hikes extends PureComponent {
|
||||
static displayName = 'Hikes';
|
||||
|
||||
static propTypes = {
|
||||
|
@ -6,19 +6,18 @@ import { createSelector } from 'reselect';
|
||||
import debug from 'debug';
|
||||
|
||||
import { toggleQuestionView } from '../redux/actions';
|
||||
import { getCurrentHike } from '../redux/selectors';
|
||||
|
||||
const log = debug('fcc:hikes');
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
state => state.hikesApp.hikes.entities,
|
||||
state => state.hikesApp.currentHike,
|
||||
(hikes, currentHikeDashedName) => {
|
||||
const currentHike = hikes[currentHikeDashedName];
|
||||
getCurrentHike,
|
||||
(currentHike) => {
|
||||
const {
|
||||
dashedName,
|
||||
description,
|
||||
challengeSeed: [id] = [0]
|
||||
} = currentHike || {};
|
||||
} = currentHike;
|
||||
return {
|
||||
id,
|
||||
dashedName,
|
||||
|
@ -14,7 +14,7 @@ export default React.createClass({
|
||||
hikes = [{}]
|
||||
} = this.props;
|
||||
|
||||
const vidElements = hikes.map(({ title, dashedName}) => {
|
||||
const vidElements = hikes.map(({ title, dashedName }) => {
|
||||
return (
|
||||
<ListGroupItem key={ dashedName }>
|
||||
<Link to={ `/videos/${dashedName}` }>
|
||||
|
@ -10,8 +10,10 @@ import {
|
||||
releaseQuestion,
|
||||
grabQuestion
|
||||
} from '../redux/actions';
|
||||
import { getCurrentHike } from '../redux/selectors';
|
||||
|
||||
const answerThreshold = 100;
|
||||
const springProperties = { stiffness: 120, damping: 10 };
|
||||
const actionsToBind = {
|
||||
answerQuestion,
|
||||
moveQuestion,
|
||||
@ -20,11 +22,10 @@ const actionsToBind = {
|
||||
};
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
state => state.hikesApp.hikes.entities,
|
||||
state => state.hikesApp.hikes.results,
|
||||
getCurrentHike,
|
||||
state => state.hikesApp,
|
||||
state => state.app.isSignedIn,
|
||||
(hikesMap, hikesByDashname, ui, isSignedIn) => {
|
||||
(currentHike, ui, isSignedIn) => {
|
||||
const {
|
||||
currentQuestion = 1,
|
||||
mouse = [ 0, 0 ],
|
||||
@ -34,7 +35,12 @@ const mapStateToProps = createSelector(
|
||||
shouldShakeQuestion = false
|
||||
} = ui;
|
||||
|
||||
const {
|
||||
tests = []
|
||||
} = currentHike;
|
||||
|
||||
return {
|
||||
tests,
|
||||
currentQuestion,
|
||||
isCorrect,
|
||||
mouse,
|
||||
@ -138,7 +144,7 @@ class Question extends React.Component {
|
||||
render() {
|
||||
const {
|
||||
tests = [],
|
||||
mouse: [x],
|
||||
mouse: [xPosition],
|
||||
currentQuestion,
|
||||
shouldShakeQuestion
|
||||
} = this.props;
|
||||
@ -158,7 +164,7 @@ class Question extends React.Component {
|
||||
xs={ 8 }
|
||||
xsOffset={ 2 }>
|
||||
<Row>
|
||||
<Motion style={{ x: spring(x, { stiffness: 120, damping: 10 }) }}>
|
||||
<Motion style={{ x: spring(xPosition, springProperties) }}>
|
||||
{ questionElement }
|
||||
</Motion>
|
||||
<div className='spacer' />
|
||||
|
8
common/app/routes/Hikes/redux/selectors.js
Normal file
8
common/app/routes/Hikes/redux/selectors.js
Normal file
@ -0,0 +1,8 @@
|
||||
// use this file for common selectors
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
export const getCurrentHike = createSelector(
|
||||
state => state.hikesApp.hikes.entities,
|
||||
state => state.hikesApp.currentHike,
|
||||
(hikesMap, currentHikeDashedName) => (hikesMap[currentHikeDashedName] || {})
|
||||
);
|
Reference in New Issue
Block a user