Render Hikes questions

This commit is contained in:
Berkeley Martinez
2016-02-04 15:03:05 -08:00
parent ac32912cd5
commit f150b31c24
8 changed files with 48 additions and 32 deletions

View File

@ -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

View File

@ -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 }),

View File

@ -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

View File

@ -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 = {

View File

@ -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,

View File

@ -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}` }>

View File

@ -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' />

View 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] || {})
);