Skip to content

Commit

Permalink
Merge pull request #45 from lbratkovskaya/gurnick013/game_sprintfix
Browse files Browse the repository at this point in the history
Sprint Fix
  • Loading branch information
lbratkovskaya authored Apr 14, 2021
2 parents fb42abd + aeec70f commit 9864b9b
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 60 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Build
build/

# IntellijIdea files
.idea/

# Dependency directories
node_modules/

Expand Down
Binary file removed src/assets/SprintAudio/sprint_false.mp3
Binary file not shown.
Binary file removed src/assets/SprintAudio/sprint_true.mp3
Binary file not shown.
16 changes: 12 additions & 4 deletions src/components/GameSprint/GameSprint.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { useFullScreenHandle } from 'react-full-screen';
import { FullScreenBtn, FullScreenWrapper } from '../commonComponents';
import { Countdown, FullScreenBtn, FullScreenWrapper } from '../commonComponents';
import Header from '../Header';
import SprintGamePlay from './SprintGamePlay';
import StartGameSprint from './StartGameSprint';
Expand All @@ -12,6 +12,7 @@ import useStyles from './style';
const GameSprint: React.FC = () => {
const classes = useStyles();
const sprintInfo = useSelector((state: IAppState) => state.sprint);
const { isCountDown } = useSelector((state: IAppState) => state.games);
const [fullSize, setFullSize] = useState(false);
const [style, setStyle] = useState({});
const handleFullScreenMode = useFullScreenHandle();
Expand All @@ -27,15 +28,22 @@ const GameSprint: React.FC = () => {
bg.src = SPRINT.background;
}, []);

const renderComponent = () => {
if (!isCountDown) {
return !sprintInfo.isStartGame ? <StartGameSprint /> : <SprintGamePlay />;
}
return <Countdown />;
};

const fullScreenClass = fullSize ? ` ${classes.wrapperFull}` : ` ${classes.wrapperNotFull}`;

const startComponent = (
<>
<div>
<div className={`${classes.sprintWrapper}${fullScreenClass}`} style={style}>
{!sprintInfo.isStartGame ? <StartGameSprint /> : <SprintGamePlay />}
{renderComponent()}
</div>
<FullScreenBtn changeScreen={handleFullSize} />
</>
</div>
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ const SprintGameEnd: React.FC = () => {
const checkCorrectArray = springInfo.wordsData.filter((el: ISprintWords) => !el.isCorrect);
setTimeout(() => {
if (checkCorrectArray.length) {
onAudioPlay(SPRINT.audioFalse);
onAudioPlay(SPRINT.audioFail);
} else {
onAudioPlay(SPRINT.audioTrue);
onAudioPlay(SPRINT.audioWin);
}
}, timeout);
}, []);
Expand Down
92 changes: 55 additions & 37 deletions src/components/GameSprint/SprintGamePlay/SprintGamePlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SprintGameEnd from './SprintGameEnd';
import Timer from '../../commonComponents/Timer';
import { GameExitBtn } from '../../commonComponents';
import { clickStartGame, onAnswer } from '../../../store/actions/sprintAction';
import { modalTimeout, SPRINT } from '../../../constants';
import { modalTimeout, SPRINT, VOLUME_DIVIDER } from '../../../constants';
import { TIME_OUT_DELAY } from '../constants';
import { IAppState, ISprintWords } from '../../../store/types';
import useStyles from '../style';
Expand All @@ -17,8 +17,11 @@ const SprintGamePlay: React.FC = () => {
const answer = (wordsArray: ISprintWords[], word: string, isAnswer: boolean) =>
dispatch(onAnswer(wordsArray, word, isAnswer));
const startGame = (isStart: boolean) => dispatch(clickStartGame(isStart));

const sprintInfo = useSelector((state: IAppState) => state?.sprint);
const { changeTimer } = useSelector((state: IAppState) => state.sprint);
const soundsVolume = useSelector((state: IAppState) => state.settings.soundsVolume);

const [randomWord, setRandomWord] = useState('');
const [classAnswer, setClassAnswer] = useState(classes.answerDefault);
const [currentWord, setCurrentWord] = useState('');
Expand All @@ -29,13 +32,20 @@ const SprintGamePlay: React.FC = () => {
const [isDisabled, setIsDisabled] = useState(false);

const timeDaleyWord = (): void => {
setCurrentWord(sprintInfo?.wordsData?.[selectWord]?.word.word);
setTranslateWord(sprintInfo?.wordsData?.[selectWord]?.word.wordTranslate);
const currentWordDependingOnLang = sprintInfo.isEng
? sprintInfo?.wordsData?.[selectWord]?.word.word
: sprintInfo?.wordsData?.[selectWord]?.word.wordTranslate;
const currentTranslateDependingOnLang = sprintInfo.isEng
? sprintInfo?.wordsData?.[selectWord]?.word.wordTranslate
: sprintInfo?.wordsData?.[selectWord]?.word.word;
setCurrentWord(currentWordDependingOnLang);
setTranslateWord(currentTranslateDependingOnLang);
setClassAnswer(classes.answerDefault);
const randomIndex: number = Math.floor(Math.random() * sprintInfo.wordsData.length);
const getRandomTranslate: string = sprintInfo?.wordsData?.[randomIndex]?.word.wordTranslate;
const getCurrentWordTranslate: string = sprintInfo?.wordsData?.[selectWord]?.word.wordTranslate;
const getRandomArray: Array<string> = [getRandomTranslate, getCurrentWordTranslate];
const getRandomTranslate: string = sprintInfo.isEng
? sprintInfo?.wordsData?.[randomIndex]?.word.wordTranslate
: sprintInfo?.wordsData?.[randomIndex]?.word.word;
const getRandomArray: Array<string> = [getRandomTranslate, currentTranslateDependingOnLang];
const getRandomWord = getRandomArray[Math.floor(Math.random() * getRandomArray.length)];
setRandomWord(getRandomWord);
setIsDisabled(false);
Expand All @@ -50,25 +60,34 @@ const SprintGamePlay: React.FC = () => {
}, [selectWord]);

useEffect(() => {
// eslint-disable-next-line no-undef
let timeout: NodeJS.Timeout;
if (timer === 0) {
setIsEndGame(true);
} else {
timeout = setTimeout(() => {
setTimer(timer - 1);
}, modalTimeout);
}
return () => {
if (timeout) clearTimeout(timeout);
};
}, [timer]);

useEffect(() => {
const timeout = setTimeout(() => setTimer(timer - 1), modalTimeout);
return () => {
startGame(false);
clearTimeout(timeout);
};
}, []);

const onAudioPlay = (url: string): void => {
const audio = new Audio(url);
audio.volume = soundsVolume / VOLUME_DIVIDER;
audio.play();
};

const onCheckAnswer = (word: string): void => {
if (!randomWord || !translateWord) return;
const isCorrectAnswer: boolean =
(word === 'false' && translateWord !== randomWord) ||
(word === 'true' && translateWord === randomWord);
Expand Down Expand Up @@ -117,7 +136,7 @@ const SprintGamePlay: React.FC = () => {
return () => {
window.removeEventListener('keydown', handleKeyboardAnswer);
};
}, [isDisabled]);
}, [timer, isDisabled]);

const btnComponent = (selectName: string) => {
return (
Expand All @@ -128,34 +147,33 @@ const SprintGamePlay: React.FC = () => {
};

return (
<>
<div>
<div className={classes.sprintHeader}>
<Timer gameTime={timer} handleOnComplite={handleEndGame} size={60} />
<GameExitBtn clickBtn={handleExitGame} />
</div>
{!isEndGame ? (
<>
<Card className={classAnswer}>
<CardContent>
<Typography color="textSecondary" gutterBottom className={classes.sprintSpan}>
{currentWord}
</Typography>
<Typography color="textSecondary" className={classes.sprintSpan}>
{randomWord}
</Typography>
</CardContent>
</Card>
<div className={classes.sprintChooseWrapper}>
{btnComponent('true')}
{btnComponent('false')}
</div>
</>
) : (
<SprintGameEnd />
)}
</div>
</>
<div>
{!isEndGame ? (
<>
<div className={classes.sprintHeader}>
<Timer gameTime={changeTimer} handleOnComplite={handleEndGame} size={60} />
<GameExitBtn clickBtn={handleExitGame} />
</div>

<Card className={classAnswer}>
<CardContent>
<Typography color="textSecondary" gutterBottom className={classes.sprintSpan}>
{currentWord}
</Typography>
<Typography color="textSecondary" className={classes.sprintSpan}>
{randomWord}
</Typography>
</CardContent>
</Card>
<div className={classes.sprintChooseWrapper}>
{btnComponent('true')}
{btnComponent('false')}
</div>
</>
) : (
<SprintGameEnd />
)}
</div>
);
};

Expand Down
3 changes: 3 additions & 0 deletions src/components/GameSprint/StartGameSprint/StartGameSprint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '../../../store/actions/sprintAction';
import { fetchDictionary } from '../../../store/actions/dictionaryActions';
import { fetchWords } from '../../../store/actions/wordBookActions';
import { changeCountDown } from '../../../store/actions/gamesActions';
import { MAX_LENGTH_GAME_ARR, SELECT_ROUNDS } from '../constants';
import { GAMES, WORDBOOK_GROUPS } from '../../../constants';
import { IAppState, IWord } from '../../../store/types';
Expand All @@ -34,6 +35,7 @@ const StartGameSprint: React.FC = () => {
const onReduceArrayWords = (wordsArray: IWord[]) => dispatch(reduceArrayWords(wordsArray));
const switchLanguage = (isEng: boolean) => dispatch(switchLang(isEng));
const getDictionaryWords = () => dispatch(fetchDictionary(userData));
const countDownStart = (isCount: boolean) => dispatch(changeCountDown(isCount));

const location = useLocation();
const isCameFromWordbook = location.state?.fromWordbook;
Expand Down Expand Up @@ -75,6 +77,7 @@ const StartGameSprint: React.FC = () => {
setRound(randomPage);
onReduceArrayWords(wordBook?.words);
}
countDownStart(true);
onClickStartGame(true);
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/GameSprint/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export const SELECT_ROUNDS: any = {
amount: 30,
};

export const TIME_OUT_DELAY: number = 500;
export const TIME_OUT_DELAY: number = 800;
export const MAX_LENGTH_GAME_ARR: number = 20;
6 changes: 2 additions & 4 deletions src/components/GameSprint/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,12 @@ const useStyles = makeStyles(() =>
margin: '3rem auto',
background: 'scroll',
'&::-webkit-scrollbar': {
width: '24px',
width: '8px',
height: '8px',
backgroundColor: '#143861',
},
'&::-webkit-scrollbar-thumb': {
backgroundColor: '#843465',
backgroundColor: '#000',
borderRadius: '9em',
boxShadow: 'inset 1px 1px 10px #f3faf7',
},
},
tableSpanCorrectly: {
Expand Down
26 changes: 16 additions & 10 deletions src/components/WordCard/WordCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import backendUrl, {
WORDBOOK_GROUPS,
WORDCARD_APPEAR_GAP,
} from '../../constants';
import { IAppState, IUserWord, IWord } from '../../store/types';
import { IAppState, IUserWord } from '../../store/types';
import { IWordCardButton, IWordCardProps } from './types';
import useStyles, { defaultImageSize, transitionStyles } from './styles';

Expand All @@ -36,16 +36,21 @@ const WordCard: React.FC<IWordCardProps> = ({
const userDifficultWords = useSelector((state: IAppState) =>
state.userDictionary.difficultWords.map((el) => el.word)
);
const isInDifficultWords = userDifficultWords.includes(word.word);
const userDeletedWords = useSelector((state: IAppState) =>
state.userDictionary.deletedWords.map((el) => el.word)
);
const isInDeletedWords = userDeletedWords.includes(word.word);

const userWords =
useSelector((state: IAppState) =>
state.userDictionary.learningWords?.reduce((acc, el) => {
Object.assign(acc, { [el.word]: el });
return acc;
}, {} as { [key: string]: IUserWord })
) || {};
const userWord = userWords[word.word] || word;

const { showTranslate, showButtons } = useSelector((state: IAppState) => state.wordBook);
const [isImageReady, setImageIsReady] = useState(false);
const audio = useMemo(() => new Audio(), []);
Expand All @@ -60,9 +65,6 @@ const WordCard: React.FC<IWordCardProps> = ({
const colorOfDifficult = theme.palette.secondary.main;
const dispatch = useDispatch();

const { deletedWords } = useSelector((state: IAppState) => state.userDictionary);
const isInDeletedWords = deletedWords.map((el: IWord) => el.word).includes(word.word);

const textStyle = {
word: playingAudioIndex === 0 ? highlightStyle : {},
meaning: playingAudioIndex === 1 ? highlightStyle : {},
Expand Down Expand Up @@ -138,10 +140,10 @@ const WordCard: React.FC<IWordCardProps> = ({

const handleAddToDifficult = (): void => {
if (isDifficult) {
dispatch(setUserWordEasy(word, userData));
dispatch(setUserWordEasy(userWord, userData));
setIsDifficult(false);
} else {
dispatch(setUserWordHard(word, userData));
dispatch(setUserWordHard(userWord, userData));
setIsDifficult(true);
}
if (removeOnDifficultyChange) {
Expand All @@ -153,8 +155,8 @@ const WordCard: React.FC<IWordCardProps> = ({
if (isDeleted) {
return;
}
dispatch(setUserWordDeleted(word, userData, !isDeleted));
dispatch(deleteWordFromGamesStore(word));
dispatch(setUserWordDeleted(userWord, userData, !isDeleted));
dispatch(deleteWordFromGamesStore(userWord));
setIsMounted(false);
setTimeout(() => {
setIsDeleted(true);
Expand All @@ -171,7 +173,7 @@ const WordCard: React.FC<IWordCardProps> = ({

const handleKeepInDictionary = (): void => {
handleRestoreClose();
dispatch(setUserWordDeleted(word, userData, !isDeleted));
dispatch(setUserWordDeleted(userWord, userData, !isDeleted));
setIsMounted(false);
setTimeout(() => {
setIsDeleted(true);
Expand All @@ -180,7 +182,7 @@ const WordCard: React.FC<IWordCardProps> = ({

const handleRemoveFromDictionary = (): void => {
handleRestoreClose();
dispatch(deleteUserWord(word, userData));
dispatch(deleteUserWord(userWord, userData));
setIsMounted(false);
setTimeout(() => {
setIsDeleted(true);
Expand Down Expand Up @@ -218,6 +220,10 @@ const WordCard: React.FC<IWordCardProps> = ({
};
}, []);

useEffect(() => {
setIsDifficult(isInDifficultWords);
}, [isInDifficultWords]);

useEffect(() => {
setIsDeleted(isInDeletedWords);
}, [isInDeletedWords]);
Expand Down
6 changes: 4 additions & 2 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,10 @@ export const SPRINT = {
background: '../../../assets/sprint-bg.jpg',
sadImg: '../../../assets/sad.svg',
winkImg: '../../../assets/wink.svg',
audioTrue: '../../../assets/SprintAudio/sprint_true.mp3',
audioFalse: '../../../assets/SprintAudio/sprint_false.mp3',
audioTrue: '../../../assets/audio/savannah-true.mp3',
audioFalse: '../../../assets/audio/savannah-false.mp3',
audioWin: '../../../assets/audio/win-sound.mp3',
audioFail: '../../../assets/audio/fail-sound.mp3',
};

export const modalTimeout = 1000;
Expand Down
1 change: 1 addition & 0 deletions src/store/actions/dictionaryActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export const setUserWordEasy = (word: IWord, userData: IUserData) => async (disp
} else {
await setUserWordData(word, userData, 'easy', false, 0, 0)(dispatch);
}
fetchDictionary(userData)(dispatch);
};

export const setUserWordHard = (word: IWord, userData: IUserData) => async (dispatch: Dispatch) => {
Expand Down

0 comments on commit 9864b9b

Please sign in to comment.