Feature(react): Add lightbox to step challenge images
This commit is contained in:
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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(
|
||||||
|
@ -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 }) => ({
|
||||||
|
@ -4,6 +4,8 @@ export default createTypes([
|
|||||||
// step
|
// step
|
||||||
'goToStep',
|
'goToStep',
|
||||||
'completeAction',
|
'completeAction',
|
||||||
|
'openLightBoxImage',
|
||||||
|
'closeLightBoxImage',
|
||||||
|
|
||||||
// challenges
|
// challenges
|
||||||
'fetchChallenge',
|
'fetchChallenge',
|
||||||
|
@ -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",
|
||||||
|
Reference in New Issue
Block a user