Feature(react): Add lightbox to step challenge images

This commit is contained in:
Berkeley Martinez
2016-06-17 17:24:34 -07:00
parent d76aa36c5b
commit d1b78eba9b
5 changed files with 56 additions and 6 deletions

View File

@ -4,11 +4,14 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import PureComponent from 'react-pure-render/component'; import PureComponent from 'react-pure-render/component';
import ReactTransitionReplace from 'react-css-transition-replace'; import ReactTransitionReplace from 'react-css-transition-replace';
import LightBox from 'react-images';
import { import {
goToStep, goToStep,
completeAction, completeAction,
submitChallenge submitChallenge,
openLightBoxImage,
closeLightBoxImage
} from '../../redux/actions'; } from '../../redux/actions';
import { challengeSelector } from '../../redux/selectors'; import { challengeSelector } from '../../redux/selectors';
import { Button, Col, Image, Row } from 'react-bootstrap'; import { Button, Col, Image, Row } from 'react-bootstrap';
@ -19,16 +22,19 @@ const mapStateToProps = createSelector(
state => state.challengesApp.currentIndex, state => state.challengesApp.currentIndex,
state => state.challengesApp.previousIndex, state => state.challengesApp.previousIndex,
state => state.challengesApp.isActionCompleted, state => state.challengesApp.isActionCompleted,
state => state.challengesApp.isLightBoxOpen,
( (
{ {
challenge: { description = [] } challenge: { description = [] }
}, },
currentIndex, currentIndex,
previousIndex, previousIndex,
isActionCompleted isActionCompleted,
isLightBoxOpen
) => ({ ) => ({
currentIndex, currentIndex,
isActionCompleted, isActionCompleted,
isLightBoxOpen,
step: description[currentIndex], step: description[currentIndex],
steps: description, steps: description,
numOfSteps: description.length, numOfSteps: description.length,
@ -39,7 +45,9 @@ const mapStateToProps = createSelector(
const dispatchActions = { const dispatchActions = {
goToStep, goToStep,
completeAction, completeAction,
submitChallenge submitChallenge,
openLightBoxImage,
closeLightBoxImage
}; };
export class StepChallenge extends PureComponent { export class StepChallenge extends PureComponent {
@ -47,6 +55,7 @@ export class StepChallenge extends PureComponent {
super(...args); super(...args);
this.handleNextClick = this.handleNextClick.bind(this); this.handleNextClick = this.handleNextClick.bind(this);
this.handleBackClick = this.handleBackClick.bind(this); this.handleBackClick = this.handleBackClick.bind(this);
this.handleLightBoxOpen = this.handleLightBoxOpen.bind(this);
} }
static displayName = 'StepChallenge'; static displayName = 'StepChallenge';
static propTypes = { static propTypes = {
@ -58,7 +67,10 @@ export class StepChallenge extends PureComponent {
numOfSteps: PropTypes.number, numOfSteps: PropTypes.number,
goToStep: PropTypes.func, goToStep: PropTypes.func,
completeAction: PropTypes.func, completeAction: PropTypes.func,
submitChallenge: PropTypes.func submitChallenge: PropTypes.func,
isLightBoxOpen: PropTypes.bool,
openlightBoxImage: PropTypes.func,
closeLightBoxImage: PropTypes.func
}; };
handleNextClick() { handleNextClick() {
@ -75,6 +87,13 @@ export class StepChallenge extends PureComponent {
goToStep(currentIndex - 1); goToStep(currentIndex - 1);
} }
handleLightBoxOpen(e) {
if (!(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.props.openLightBoxImage();
}
}
renderActionButton(action, completeAction) { renderActionButton(action, completeAction) {
const isApiAction = action === '#'; const isApiAction = action === '#';
const buttonCopy = isApiAction ? const buttonCopy = isApiAction ?
@ -158,7 +177,11 @@ export class StepChallenge extends PureComponent {
className='' className=''
key={ imgUrl } key={ imgUrl }
> >
<a href={ imgUrl }> <a
href={ imgUrl }
onClick={ this.handleLightBoxOpen }
target='_blank'
>
<Image <Image
alt={ imgAlt } alt={ imgAlt }
responsive={ true } responsive={ true }
@ -222,7 +245,13 @@ export class StepChallenge extends PureComponent {
} }
render() { render() {
const { steps, isGoingForward } = this.props; const {
step,
steps,
isLightBoxOpen,
isGoingForward,
closeLightBoxImage
} = this.props;
const transitionName = 'challenge-step-' + const transitionName = 'challenge-step-' +
(isGoingForward ? 'forward' : 'backward'); (isGoingForward ? 'forward' : 'backward');
return ( return (
@ -240,6 +269,13 @@ export class StepChallenge extends PureComponent {
<div className='hidden'> <div className='hidden'>
{ this.renderImages(steps) } { this.renderImages(steps) }
</div> </div>
<LightBox
backdropClosesModal={ true }
images={ [ { src: step[0] } ] }
isOpen={ isLightBoxOpen }
onClose={ closeLightBoxImage }
showImageCount={ false }
/>
<div className='spacer' /> <div className='spacer' />
</Col> </Col>
); );

View File

@ -7,6 +7,8 @@ import types from './types';
// step // step
export const goToStep = createAction(types.goToStep); export const goToStep = createAction(types.goToStep);
export const completeAction = createAction(types.completeAction); export const completeAction = createAction(types.completeAction);
export const openLightBoxImage = createAction(types.openLightBoxImage);
export const closeLightBoxImage = createAction(types.closeLightBoxImage);
// challenges // challenges
export const fetchChallenge = createAction( export const fetchChallenge = createAction(

View File

@ -18,6 +18,7 @@ const initialUiState = {
previousIndex: -1, previousIndex: -1,
// step action // step action
isActionCompleted: false, isActionCompleted: false,
isLightBoxOpen: false,
// project is ready to submit // project is ready to submit
isSubmitting: false, isSubmitting: false,
output: `/** output: `/**
@ -121,6 +122,14 @@ const mainReducer = handleActions(
...state, ...state,
isActionCompleted: true isActionCompleted: true
}), }),
[types.openLightBoxImage]: state => ({
...state,
isLightBoxOpen: true
}),
[types.closeLightBoxImage]: state => ({
...state,
isLightBoxOpen: false
}),
// classic/modern // classic/modern
[types.initOutput]: (state, { payload: output }) => ({ [types.initOutput]: (state, { payload: output }) => ({

View File

@ -4,6 +4,8 @@ export default createTypes([
// step // step
'goToStep', 'goToStep',
'completeAction', 'completeAction',
'openLightBoxImage',
'closeLightBoxImage',
// challenges // challenges
'fetchChallenge', 'fetchChallenge',

View File

@ -87,6 +87,7 @@
"react-css-transition-replace": "^1.2.0-beta", "react-css-transition-replace": "^1.2.0-beta",
"react-dom": "^15.0.2", "react-dom": "^15.0.2",
"react-fontawesome": "^0.3.3", "react-fontawesome": "^0.3.3",
"react-images": "^0.4.6",
"react-motion": "~0.4.2", "react-motion": "~0.4.2",
"react-no-ssr": "^1.0.1", "react-no-ssr": "^1.0.1",
"react-pure-render": "^1.0.2", "react-pure-render": "^1.0.2",