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 // updateTitle(title: String) => Action
export const updateTitle = createAction(types.updateTitle); export const updateTitle = createAction(types.updateTitle);
let id = 0;
// makeToast({ type?: String, message: String, title: String }) => Action // makeToast({ type?: String, message: String, title: String }) => Action
export const makeToast = createAction( export const makeToast = createAction(
types.makeToast, types.makeToast,
toast => toast.type ? toast : (toast.type = 'info', toast) toast => {
id += 1;
return {
...toast,
id,
type: toast.type || 'info'
};
}
); );
// fetchUser() => Action // fetchUser() => Action

View File

@ -10,10 +10,7 @@ export default handleActions(
[types.makeToast]: (state, { payload: toast }) => ({ [types.makeToast]: (state, { payload: toast }) => ({
...state, ...state,
toast: { toast
...toast,
id: state.toast && state.toast.id ? state.toast.id : 1
}
}), }),
[types.setUser]: (state, { payload: user }) => ({ ...state, ...user }), [types.setUser]: (state, { payload: user }) => ({ ...state, ...user }),

View File

@ -6,18 +6,15 @@ import { createSelector } from 'reselect';
import Lecture from './Lecture.jsx'; import Lecture from './Lecture.jsx';
import Questions from './Questions.jsx'; import Questions from './Questions.jsx';
import { resetHike } from '../redux/actions'; import { resetHike } from '../redux/actions';
import { getCurrentHike } from '../redux/selectors';
const mapStateToProps = createSelector( const mapStateToProps = createSelector(
state => state.hikesApp.hikes.entities, getCurrentHike,
state => state.hikesApp.currentHike, state => state.hikesApp.shouldShowQuestions,
state => state.hikesApp, (currentHike, shouldShowQuestions) => ({
(hikes, currentHikeDashedName, { shouldShowQuestions }) => {
const currentHike = hikes[currentHikeDashedName];
return {
title: currentHike ? currentHike.title : '', title: currentHike ? currentHike.title : '',
shouldShowQuestions shouldShowQuestions
}; })
}
); );
// export plain component for testing // export plain component for testing

View File

@ -2,7 +2,7 @@ import React, { PropTypes } from 'react';
import { compose } from 'redux'; import { compose } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Row } from 'react-bootstrap'; import { Row } from 'react-bootstrap';
import shouldComponentUpdate from 'react-pure-render/function'; import PureComponent from 'react-pure-render/component';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
// import debug from 'debug'; // import debug from 'debug';
@ -15,13 +15,14 @@ import contain from '../../../utils/professor-x';
// const log = debug('fcc:hikes'); // const log = debug('fcc:hikes');
const mapStateToProps = createSelector( const mapStateToProps = createSelector(
state => state.hikesApp.hikes, state => state.hikesApp.hikes.entities,
hikes => { state => state.hikesApp.hikes.results,
if (!hikes || !hikes.entities || !hikes.results) { (hikesMap, hikesByDashedName)=> {
if (!hikesMap || !hikesByDashedName) {
return { hikes: [] }; return { hikes: [] };
} }
return { 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 displayName = 'Hikes';
static propTypes = { static propTypes = {

View File

@ -6,19 +6,18 @@ import { createSelector } from 'reselect';
import debug from 'debug'; import debug from 'debug';
import { toggleQuestionView } from '../redux/actions'; import { toggleQuestionView } from '../redux/actions';
import { getCurrentHike } from '../redux/selectors';
const log = debug('fcc:hikes'); const log = debug('fcc:hikes');
const mapStateToProps = createSelector( const mapStateToProps = createSelector(
state => state.hikesApp.hikes.entities, getCurrentHike,
state => state.hikesApp.currentHike, (currentHike) => {
(hikes, currentHikeDashedName) => {
const currentHike = hikes[currentHikeDashedName];
const { const {
dashedName, dashedName,
description, description,
challengeSeed: [id] = [0] challengeSeed: [id] = [0]
} = currentHike || {}; } = currentHike;
return { return {
id, id,
dashedName, dashedName,

View File

@ -10,8 +10,10 @@ import {
releaseQuestion, releaseQuestion,
grabQuestion grabQuestion
} from '../redux/actions'; } from '../redux/actions';
import { getCurrentHike } from '../redux/selectors';
const answerThreshold = 100; const answerThreshold = 100;
const springProperties = { stiffness: 120, damping: 10 };
const actionsToBind = { const actionsToBind = {
answerQuestion, answerQuestion,
moveQuestion, moveQuestion,
@ -20,11 +22,10 @@ const actionsToBind = {
}; };
const mapStateToProps = createSelector( const mapStateToProps = createSelector(
state => state.hikesApp.hikes.entities, getCurrentHike,
state => state.hikesApp.hikes.results,
state => state.hikesApp, state => state.hikesApp,
state => state.app.isSignedIn, state => state.app.isSignedIn,
(hikesMap, hikesByDashname, ui, isSignedIn) => { (currentHike, ui, isSignedIn) => {
const { const {
currentQuestion = 1, currentQuestion = 1,
mouse = [ 0, 0 ], mouse = [ 0, 0 ],
@ -34,7 +35,12 @@ const mapStateToProps = createSelector(
shouldShakeQuestion = false shouldShakeQuestion = false
} = ui; } = ui;
const {
tests = []
} = currentHike;
return { return {
tests,
currentQuestion, currentQuestion,
isCorrect, isCorrect,
mouse, mouse,
@ -138,7 +144,7 @@ class Question extends React.Component {
render() { render() {
const { const {
tests = [], tests = [],
mouse: [x], mouse: [xPosition],
currentQuestion, currentQuestion,
shouldShakeQuestion shouldShakeQuestion
} = this.props; } = this.props;
@ -158,7 +164,7 @@ class Question extends React.Component {
xs={ 8 } xs={ 8 }
xsOffset={ 2 }> xsOffset={ 2 }>
<Row> <Row>
<Motion style={{ x: spring(x, { stiffness: 120, damping: 10 }) }}> <Motion style={{ x: spring(xPosition, springProperties) }}>
{ questionElement } { questionElement }
</Motion> </Motion>
<div className='spacer' /> <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] || {})
);