| 1 |
import { Component } from '@wordpress/element'; |
| 2 |
import { withSelect, withDispatch } from '@wordpress/data'; |
| 3 |
import { compose } from '@wordpress/compose'; |
| 4 |
import { __ } from '@wordpress/i18n'; |
| 5 |
|
| 6 |
import Question from './question'; |
| 7 |
|
| 8 |
class Questions extends Component { |
| 9 |
constructor( props ) { |
| 10 |
super( ...arguments ); |
| 11 |
|
| 12 |
this.needToTop = false; |
| 13 |
this.state = { |
| 14 |
isReviewing: null, |
| 15 |
currentPage: 0, |
| 16 |
self: this, |
| 17 |
}; |
| 18 |
} |
| 19 |
|
| 20 |
static getDerivedStateFromProps( props, state ) { |
| 21 |
const checkProps = [ 'isReviewing', 'currentPage' ]; |
| 22 |
const changedProps = {}; |
| 23 |
|
| 24 |
for ( let i = 0; i < checkProps.length; i++ ) { |
| 25 |
if ( props[ checkProps[ i ] ] !== state[ checkProps[ i ] ] ) { |
| 26 |
changedProps[ checkProps[ i ] ] = props[ checkProps[ i ] ]; |
| 27 |
} |
| 28 |
} |
| 29 |
|
| 30 |
if ( Object.values( changedProps ).length ) { |
| 31 |
if ( props.questionsPerPage === 1 ) { |
| 32 |
state.self.needToTop = true; |
| 33 |
} |
| 34 |
return changedProps; |
| 35 |
} |
| 36 |
|
| 37 |
return null; |
| 38 |
} |
| 39 |
|
| 40 |
// componentWillReceiveProps(nextProps){ |
| 41 |
// const checkProps = ['isReviewing', 'currentPage']; |
| 42 |
// |
| 43 |
// for(let i = 0; i < checkProps.length; i++){ |
| 44 |
// if(this.props[checkProps[i]] !== nextProps[checkProps[i]]){ |
| 45 |
// this.needToTop = true; |
| 46 |
// return; |
| 47 |
// } |
| 48 |
// } |
| 49 |
// |
| 50 |
// } |
| 51 |
|
| 52 |
// componentWillUpdate() { |
| 53 |
// this.needToTop = this.state.needToTop; |
| 54 |
// this.setState({needToTop: false}); |
| 55 |
// } |
| 56 |
|
| 57 |
componentDidUpdate() { |
| 58 |
if ( this.needToTop ) { |
| 59 |
jQuery( '#popup-content' ) |
| 60 |
.animate( { scrollTop: 0 } ) |
| 61 |
.find( '.content-item-scrollable:last' ) |
| 62 |
.animate( { scrollTop: 0 } ); |
| 63 |
this.needToTop = false; |
| 64 |
} |
| 65 |
} |
| 66 |
|
| 67 |
startQuiz = ( event ) => { |
| 68 |
event.preventDefault(); |
| 69 |
|
| 70 |
const { |
| 71 |
startQuiz, |
| 72 |
} = this.props; |
| 73 |
|
| 74 |
startQuiz(); |
| 75 |
}; |
| 76 |
|
| 77 |
isInVisibleRange = ( id, index ) => { |
| 78 |
const { |
| 79 |
currentPage, |
| 80 |
questionsPerPage, |
| 81 |
} = this.props; |
| 82 |
return currentPage === Math.ceil( index / questionsPerPage ); |
| 83 |
}; |
| 84 |
|
| 85 |
nav = ( event ) => { |
| 86 |
const { sendKey } = this.props; |
| 87 |
|
| 88 |
switch ( event.keyCode ) { |
| 89 |
case 37: |
| 90 |
return sendKey( 'left' ); |
| 91 |
case 38: |
| 92 |
return; |
| 93 |
case 39: |
| 94 |
return sendKey( 'right' ); |
| 95 |
case 40: |
| 96 |
return; |
| 97 |
default: |
| 98 |
if ( event.keyCode >= 49 && event.keyCode <= 57 ) { |
| 99 |
sendKey( event.keyCode - 48 ); |
| 100 |
} |
| 101 |
} |
| 102 |
} |
| 103 |
|
| 104 |
render() { |
| 105 |
const { |
| 106 |
status, |
| 107 |
currentQuestion, |
| 108 |
questions, |
| 109 |
questionsRendered, |
| 110 |
isReviewing, |
| 111 |
questionsPerPage, |
| 112 |
} = this.props; |
| 113 |
let isShow = true; |
| 114 |
|
| 115 |
if ( status === 'completed' && ! isReviewing ) { |
| 116 |
isShow = false; |
| 117 |
} |
| 118 |
|
| 119 |
return ( |
| 120 |
<> |
| 121 |
<div tabIndex={ 100 } onKeyUp={ this.nav }> |
| 122 |
<div className="quiz-questions" style={ { display: isShow ? '' : 'none' } }> |
| 123 |
{ questions.map( ( question, index ) => { |
| 124 |
const isCurrent = questionsPerPage ? false : currentQuestion === question.id; |
| 125 |
const isRendered = questionsRendered && questionsRendered.indexOf( question.id ) !== -1; |
| 126 |
const isVisible = this.isInVisibleRange( question.id, index + 1 ); |
| 127 |
return ( |
| 128 |
( isRendered || ! isRendered ) || isVisible |
| 129 |
? <Question |
| 130 |
key={ `loop-question-${ question.id }` } |
| 131 |
isCurrent={ isCurrent } |
| 132 |
isShow={ isVisible } |
| 133 |
isShowIndex={ questionsPerPage ? index + 1 : false } |
| 134 |
questionsPerPage={ questionsPerPage } |
| 135 |
question={ question } |
| 136 |
/> : '' |
| 137 |
); |
| 138 |
} ) } |
| 139 |
</div> |
| 140 |
</div> |
| 141 |
</> |
| 142 |
); |
| 143 |
} |
| 144 |
} |
| 145 |
|
| 146 |
export default compose( |
| 147 |
withSelect( ( select, a, b ) => { |
| 148 |
const { |
| 149 |
getData, |
| 150 |
getQuestions, |
| 151 |
} = select( 'learnpress/quiz' ); |
| 152 |
|
| 153 |
return { |
| 154 |
status: getData( 'status' ), |
| 155 |
currentQuestion: getData( 'currentQuestion' ), |
| 156 |
questions: getQuestions(), |
| 157 |
questionsRendered: getData( 'questionsRendered' ), |
| 158 |
isReviewing: getData( 'mode' ) === 'reviewing', |
| 159 |
numPages: getData( 'numPages' ), |
| 160 |
currentPage: getData( 'currentPage' ), |
| 161 |
questionsPerPage: getData( 'questionsPerPage' ) || 1, |
| 162 |
}; |
| 163 |
} ), |
| 164 |
withDispatch( ( dispatch ) => { |
| 165 |
const { |
| 166 |
startQuiz, |
| 167 |
sendKey, |
| 168 |
} = dispatch( 'learnpress/quiz' ); |
| 169 |
|
| 170 |
return { |
| 171 |
startQuiz, |
| 172 |
sendKey, |
| 173 |
}; |
| 174 |
} ) |
| 175 |
)( Questions ); |
| 176 |
|