From 202c273432f4d0e6e2ab6d91b63fc99a968d68a8 Mon Sep 17 00:00:00 2001 From: Alfred Melch Date: Sun, 15 Dec 2019 01:28:28 +0100 Subject: [PATCH] Add disableing controls --- src/components/PlayerControl.js | 4 +- src/components/SegmentControl.js | 18 +++++++- src/store/reducer.js | 25 ++++++----- src/store/selectors.js | 74 ++++++++++++++++++++++++++++---- 4 files changed, 98 insertions(+), 23 deletions(-) diff --git a/src/components/PlayerControl.js b/src/components/PlayerControl.js index f3d1013..d8d4dd3 100644 --- a/src/components/PlayerControl.js +++ b/src/components/PlayerControl.js @@ -2,7 +2,7 @@ import React from 'react' import { useSelector, useDispatch } from 'react-redux' import { - hasNextSegment, + selectHasNextSegment, selectRunning, selectInterval } from '../store/selectors' @@ -14,7 +14,7 @@ import { IconButton } from '../styles/IconButton' export const PlayerControl = () => { const dispatch = useDispatch() const running = useSelector(selectRunning) - const hasNext = useSelector(hasNextSegment) + const hasNext = useSelector(selectHasNextSegment) const interval = useSelector(selectInterval) useInterval( diff --git a/src/components/SegmentControl.js b/src/components/SegmentControl.js index 80d957f..2607976 100644 --- a/src/components/SegmentControl.js +++ b/src/components/SegmentControl.js @@ -1,5 +1,5 @@ import React from 'react' -import { useDispatch } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { FiSkipBack, FiSkipForward, @@ -9,6 +9,13 @@ import { import { IconButton } from '../styles/IconButton' +import { + selectHasNextSentence, + selectHasPrevSentence, + selectHasPrevWord, + selectHasNextWord +} from '../store/selectors' + import { incrementSentence, incrementWord, @@ -18,28 +25,37 @@ import { export const SegmentControl = ({ children }) => { const dispatch = useDispatch() + const hasPrevSentence = useSelector(selectHasPrevSentence) + const hasNextSentence = useSelector(selectHasNextSentence) + const hasPrevWord = useSelector(selectHasPrevWord) + const hasNextWord = useSelector(selectHasNextWord) + return ( <> dispatch(decrementSentence())} Icon={FiRewind} + disabled={!hasPrevSentence} /> dispatch(decrementWord())} + disabled={!hasPrevWord} /> {children} dispatch(incrementWord())} + disabled={!hasNextWord} /> dispatch(incrementSentence())} + disabled={!hasNextSentence} /> ) diff --git a/src/store/reducer.js b/src/store/reducer.js index d703d58..5d40a8f 100644 --- a/src/store/reducer.js +++ b/src/store/reducer.js @@ -1,16 +1,19 @@ import { - selectNextWord, - selectNextSentence, - selectPrevWord, - selectPrevSentence + safeSelectNextWord, + safeSelectNextSentence, + safeSelectPrevWord, + safeSelectPrevSentence, + safeSelectNextSegment, + safeSelectPrevSegment } from './selectors' export const initialState = { originalText: 'Sample Text', curIdx: 0, - maxLength: 5, + maxLength: 8, isPlaying: false, wpm: 300, + offset: -15, running: false } @@ -21,12 +24,12 @@ const reducer = { curIdx: 0 }), SET_CURRENT_SEGMENT: (state, payload) => ({ ...state, curIdx: payload }), - INC_SEGMENT: state => ({ ...state, curIdx: state.curIdx + 1 }), - DEC_SEGMENT: state => ({ ...state, curIdx: state.curIdx - 1 }), - INC_WORD: state => ({ ...state, curIdx: selectNextWord(state) }), - DEC_WORD: state => ({ ...state, curIdx: selectPrevWord(state) }), - INC_SENTENCE: state => ({ ...state, curIdx: selectNextSentence(state) }), - DEC_SENTENCE: state => ({ ...state, curIdx: selectPrevSentence(state) }), + INC_SEGMENT: state => ({ ...state, curIdx: safeSelectNextSegment(state) }), + DEC_SEGMENT: state => ({ ...state, curIdx: safeSelectPrevSegment(state) }), + INC_WORD: state => ({ ...state, curIdx: safeSelectNextWord(state) }), + DEC_WORD: state => ({ ...state, curIdx: safeSelectPrevWord(state) }), + INC_SENTENCE: state => ({ ...state, curIdx: safeSelectNextSentence(state) }), + DEC_SENTENCE: state => ({ ...state, curIdx: safeSelectPrevSentence(state) }), SET_MAX_LENGTH: (state, payload) => ({ ...state, maxLength: payload, diff --git a/src/store/selectors.js b/src/store/selectors.js index fd36522..c196519 100644 --- a/src/store/selectors.js +++ b/src/store/selectors.js @@ -4,6 +4,9 @@ import { parseText } from '../lib/parseText' import { getNextBiggerNumber, getNextSmallerNumber } from '../lib/array-util.js' import { pivotize } from '../lib/pivotize' +// util +const notNull = val => val != null + // parsedText selectors export const selectMaxLength = state => state.maxLength @@ -19,6 +22,8 @@ export const selectSegments = createSelector( parsedText => parsedText.segments ) +// segments + export const selectCurrentSegmentIndex = state => state.curIdx export const selectCurrentSegment = createSelector( @@ -32,12 +37,32 @@ export const selectPivotizedSegment = createSelector( pivotize ) -export const hasNextSegment = createSelector( +export const selectNextSegment = state => state.curIdx + 1 +export const selectPrevSegment = state => state.curIdx - 1 + +export const selectHasNextSegment = createSelector( selectSegments, selectCurrentSegmentIndex, - (segments, idx) => { - return idx < segments.length - 1 - } + (segments, idx) => idx < segments.length - 1 +) + +export const selectHasPrevSegment = createSelector( + selectCurrentSegmentIndex, + idx => idx > 0 +) + +export const safeSelectNextSegment = createSelector( + selectHasNextSegment, + selectNextSegment, + selectCurrentSegmentIndex, + (has, segment, idx) => (has ? segment : idx) +) + +export const safeSelectPrevSegment = createSelector( + selectHasPrevSegment, + selectPrevSegment, + selectCurrentSegmentIndex, + (has, segment, idx) => (has ? segment : idx) ) // next/prev words @@ -56,11 +81,26 @@ export const selectNextWord = createSelector( export const selectPrevWord = createSelector( selectWords, selectCurrentSegmentIndex, - (words, curSegment) => getNextSmallerNumber(curSegment, words) + (words, curSegment) => { + console.log(words, curSegment, getNextSmallerNumber(curSegment, words)) + return getNextSmallerNumber(curSegment, words) + } ) -export const selectHasNextWord = createSelector(selectNextWord, Boolean) -export const selectHasPrevWord = createSelector(selectPrevWord, Boolean) +export const selectHasNextWord = createSelector(selectNextWord, notNull) +export const selectHasPrevWord = createSelector(selectPrevWord, notNull) +export const safeSelectNextWord = createSelector( + selectHasNextWord, + selectNextWord, + selectCurrentSegmentIndex, + (has, word, idx) => (has ? word : idx) +) +export const safeSelectPrevWord = createSelector( + selectHasPrevWord, + selectPrevWord, + selectCurrentSegmentIndex, + (has, word, idx) => (has ? word : idx) +) // next/prev sentences @@ -81,8 +121,24 @@ export const selectPrevSentence = createSelector( (sentences, curSegment) => getNextSmallerNumber(curSegment, sentences) ) -export const selectHasNextSentence = createSelector(selectNextSentence, Boolean) -export const selectHasPrevSentence = createSelector(selectPrevSentence, Boolean) +export const selectHasNextSentence = createSelector(selectNextSentence, notNull) +export const selectHasPrevSentence = createSelector(selectPrevSentence, notNull) + +export const safeSelectNextSentence = createSelector( + selectHasNextSentence, + selectNextSentence, + selectCurrentSegmentIndex, + (has, sentence, idx) => (has ? sentence : idx) +) + +export const safeSelectPrevSentence = createSelector( + selectHasPrevSentence, + selectPrevSentence, + selectCurrentSegmentIndex, + (has, sentence, idx) => (has ? sentence : idx) +) + +// options export const selectWpm = state => state.wpm export const selectInterval = createSelector(selectWpm, wpm => 60000 / wpm)