Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sprint Fix #45

Merged
merged 3 commits into from
Apr 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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