|
|
|
@@ -3,47 +3,48 @@ import { alarmOutline, arrowBackCircleOutline } from 'ionicons/icons';
|
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
|
import { useParams } from 'react-router';
|
|
|
|
|
import { LoadingScreen } from '../../components/LoadingScreen';
|
|
|
|
|
import { MATCHING_FRENZY_LINK, QUIZ_MAIN_MENU_LINK } from '../../constants';
|
|
|
|
|
import { MATCHING_FRENZY_LINK } from '../../constants';
|
|
|
|
|
import { useAppStateContext } from '../../contexts/AppState';
|
|
|
|
|
import { useMyIonQuizContext } from '../../contexts/MyIonQuiz';
|
|
|
|
|
import IMatchingFrenzyQuestion from '../../interfaces/IMatchingFrenzyQuestion';
|
|
|
|
|
import { listMatchingFrenzyContent } from '../../public_data/listMatchingFrenzyContent';
|
|
|
|
|
import { shuffleArray } from '../../utils/shuffleArray';
|
|
|
|
|
import CountDown from './CountDown';
|
|
|
|
|
import MatchingFrenzyCard from './MatchingFrenzyCard';
|
|
|
|
|
import PressStartToBegin from './PressStartToBegin';
|
|
|
|
|
import './style.css';
|
|
|
|
|
import ConfirmUserQuitQuiz from '../../components/ConfirmUserQuitQuiz';
|
|
|
|
|
import formatTimeDisplay from './formatTimeDisplay';
|
|
|
|
|
import fetchMFQuestions from '../../hooks/fetchMFQuestions';
|
|
|
|
|
import { usePocketBase } from '../../hooks/usePocketBase';
|
|
|
|
|
|
|
|
|
|
function MatchingFrenzyMatchRun() {
|
|
|
|
|
const [loading, setLoading] = useState<boolean>(true);
|
|
|
|
|
|
|
|
|
|
const router = useIonRouter();
|
|
|
|
|
const { p_route } = useParams<{ p_route: string }>();
|
|
|
|
|
const i_p_route = parseInt(p_route);
|
|
|
|
|
|
|
|
|
|
const [question_list, setQuestionList] = useState<IMatchingFrenzyQuestion[] | []>([]);
|
|
|
|
|
const { p_route: cat_id } = useParams<{ p_route: string }>();
|
|
|
|
|
let [start_match, setStartMatch] = useState(false);
|
|
|
|
|
let [test_random, setTestRandom] = useState(0);
|
|
|
|
|
const [show_confirm_user_exit, setShowConfirmUserExit] = useState<boolean>(false);
|
|
|
|
|
const { setMatchingFrenzyInProgress } = useAppStateContext();
|
|
|
|
|
const [question_list, setQuestionList] = useState<IMatchingFrenzyQuestion[]>([]);
|
|
|
|
|
const [current_question_meta, setCurrentQuestionMeta] = useState<IMatchingFrenzyQuestion | undefined>(undefined);
|
|
|
|
|
|
|
|
|
|
const [current_question, setCurrentQuestion] = useState(0);
|
|
|
|
|
const [num_correct, setNumCorrect] = useState(0);
|
|
|
|
|
|
|
|
|
|
const { setTabActive } = useAppStateContext();
|
|
|
|
|
|
|
|
|
|
const [answer_list, setAnswerList] = useState<string[]>([]);
|
|
|
|
|
|
|
|
|
|
const { MATCHING_FRENZY_COUNT_DOWN_S } = useAppStateContext();
|
|
|
|
|
const [countdown_s, setCountDown_s] = useState<number>(MATCHING_FRENZY_COUNT_DOWN_S);
|
|
|
|
|
const [show_time_left_s, setShowTimeLeft] = useState<string>('0:00');
|
|
|
|
|
const { setMatchingFrenzyInProgress } = useAppStateContext();
|
|
|
|
|
const { setMatchingFrenzyCurrentTest, setMatchingFrenzyResult, saveMatchingFrenzyResultToScoreBoard } =
|
|
|
|
|
useMyIonQuizContext();
|
|
|
|
|
const [num_correct, setNumCorrect] = useState(0);
|
|
|
|
|
const [answer_list, setAnswerList] = useState<string[]>([]);
|
|
|
|
|
|
|
|
|
|
let [start_match, setStartMatch] = useState(false);
|
|
|
|
|
let [test_random, setTestRandom] = useState(0);
|
|
|
|
|
// TODO: review useless
|
|
|
|
|
const i_p_route = parseInt(p_route);
|
|
|
|
|
|
|
|
|
|
const formatTimeDisplay = (s: number) => {
|
|
|
|
|
return `${Math.floor(s / 60)}:${(s % 60).toString().padStart(2, '0')}`;
|
|
|
|
|
function processStartMatch() {
|
|
|
|
|
setMatchingFrenzyInProgress(true);
|
|
|
|
|
setStartMatch(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const incNumCorrect = () => {
|
|
|
|
|
setNumCorrect(num_correct + 1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const nextQuestion = () => {
|
|
|
|
@@ -71,15 +72,8 @@ function MatchingFrenzyMatchRun() {
|
|
|
|
|
setCurrentQuestionMeta(question_list[next_question_num]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const incNumCorrect = () => {
|
|
|
|
|
setNumCorrect(num_correct + 1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function processStartMatch() {
|
|
|
|
|
setMatchingFrenzyInProgress(true);
|
|
|
|
|
setStartMatch(true);
|
|
|
|
|
}
|
|
|
|
|
const { setMatchingFrenzyCurrentTest, setMatchingFrenzyResult, saveMatchingFrenzyResultToScoreBoard } =
|
|
|
|
|
useMyIonQuizContext();
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setShowTimeLeft(formatTimeDisplay(countdown_s));
|
|
|
|
@@ -102,9 +96,9 @@ function MatchingFrenzyMatchRun() {
|
|
|
|
|
}, [countdown_s]);
|
|
|
|
|
|
|
|
|
|
const [init_ans, setInitAns] = useState<string[]>([]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!current_question_meta) return;
|
|
|
|
|
|
|
|
|
|
let init_options = [...question_list.map((q) => q.word), ...answer_list, ...init_ans];
|
|
|
|
|
|
|
|
|
|
let all_answer_list = [...new Set(init_options)];
|
|
|
|
@@ -115,83 +109,73 @@ function MatchingFrenzyMatchRun() {
|
|
|
|
|
setAnswerList(shuffleArray([...sliced_shuffle_array, current_question_meta.word]));
|
|
|
|
|
}, [current_question_meta]);
|
|
|
|
|
|
|
|
|
|
const { user, pb } = usePocketBase();
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
(async () => {
|
|
|
|
|
const res_json = await listMatchingFrenzyContent();
|
|
|
|
|
const cat_json = res_json[i_p_route];
|
|
|
|
|
const init_answer = cat_json.init_answer;
|
|
|
|
|
setInitAns(cat_json.init_answer);
|
|
|
|
|
fetchMFQuestions(cat_id, pb)
|
|
|
|
|
.then((result) => {
|
|
|
|
|
console.log(result);
|
|
|
|
|
const cat_json = result.items;
|
|
|
|
|
const init_answer = result.items[0].init_answer;
|
|
|
|
|
setInitAns(init_answer);
|
|
|
|
|
|
|
|
|
|
let temp = res_json[i_p_route].content;
|
|
|
|
|
let shuffled_temp = shuffleArray(temp);
|
|
|
|
|
let temp = result.items;
|
|
|
|
|
let shuffled_temp = shuffleArray(temp);
|
|
|
|
|
|
|
|
|
|
setQuestionList(shuffled_temp);
|
|
|
|
|
setCurrentQuestionMeta(cat_json.content[current_question]);
|
|
|
|
|
})();
|
|
|
|
|
setQuestionList(shuffled_temp);
|
|
|
|
|
setCurrentQuestionMeta(result.items[current_question] as unknown as IMatchingFrenzyQuestion);
|
|
|
|
|
|
|
|
|
|
setTabActive(QUIZ_MAIN_MENU_LINK);
|
|
|
|
|
setTestRandom(Math.random());
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const [show_confirm_user_exit, setShowConfirmUserExit] = useState<boolean>(false);
|
|
|
|
|
setLoading(false);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error);
|
|
|
|
|
});
|
|
|
|
|
}, [cat_id]);
|
|
|
|
|
|
|
|
|
|
if (!current_question_meta) return <LoadingScreen />;
|
|
|
|
|
if (loading) return <LoadingScreen />;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<IonPage>
|
|
|
|
|
<IonContent fullscreen>
|
|
|
|
|
{start_match ? (
|
|
|
|
|
<>
|
|
|
|
|
<div>
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
marginLeft: '1rem',
|
|
|
|
|
marginRight: '1rem',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ width: '33vw' }}>
|
|
|
|
|
<IonButton color="dark" fill="clear" shape="round" onClick={() => setShowConfirmUserExit(true)}>
|
|
|
|
|
<IonIcon slot="icon-only" size="large" icon={arrowBackCircleOutline}></IonIcon>
|
|
|
|
|
</IonButton>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<IonIcon icon={alarmOutline}></IonIcon>
|
|
|
|
|
{countdown_s > 0 ? show_time_left_s : 'times up'}
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ width: '33vw', display: 'flex', justifyContent: 'flex-end' }}>
|
|
|
|
|
Matches:{num_correct}
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
marginLeft: '1rem',
|
|
|
|
|
marginRight: '1rem',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ width: '33vw' }}>
|
|
|
|
|
<IonButton color="dark" fill="clear" shape="round" onClick={() => setShowConfirmUserExit(true)}>
|
|
|
|
|
<IonIcon slot="icon-only" size="large" icon={arrowBackCircleOutline}></IonIcon>
|
|
|
|
|
</IonButton>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ margin: '1rem' }}></div>
|
|
|
|
|
{/* */}
|
|
|
|
|
{/*
|
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'row', gap: '0.3rem' }}>
|
|
|
|
|
<IonIcon icon={alarmOutline}></IonIcon>
|
|
|
|
|
{countdown_s > 0 ? show_time_left_s : 'times up'}
|
|
|
|
|
</div>
|
|
|
|
|
<div>Matches:{num_correct}</div>
|
|
|
|
|
<div>
|
|
|
|
|
<IonIcon icon={alarmOutline}></IonIcon>
|
|
|
|
|
{countdown_s > 0 ? show_time_left_s : 'times up'}
|
|
|
|
|
</div>
|
|
|
|
|
*/}
|
|
|
|
|
|
|
|
|
|
<MatchingFrenzyCard
|
|
|
|
|
num_correct={num_correct}
|
|
|
|
|
incNumCorrect={incNumCorrect}
|
|
|
|
|
//
|
|
|
|
|
nextQuestion={nextQuestion}
|
|
|
|
|
question_meta={{
|
|
|
|
|
//
|
|
|
|
|
word_c: current_question_meta.word_c,
|
|
|
|
|
modal_answer: current_question_meta.word,
|
|
|
|
|
}}
|
|
|
|
|
shuffle_word_list={answer_list}
|
|
|
|
|
/>
|
|
|
|
|
<div style={{ width: '33vw', display: 'flex', justifyContent: 'flex-end' }}>Matches:{num_correct}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
<div style={{ margin: '1rem' }}></div>
|
|
|
|
|
|
|
|
|
|
<MatchingFrenzyCard
|
|
|
|
|
num_correct={num_correct}
|
|
|
|
|
incNumCorrect={incNumCorrect}
|
|
|
|
|
//
|
|
|
|
|
nextQuestion={nextQuestion}
|
|
|
|
|
question_meta={{
|
|
|
|
|
//
|
|
|
|
|
word_c: current_question_meta.word_c,
|
|
|
|
|
modal_answer: current_question_meta.word,
|
|
|
|
|
}}
|
|
|
|
|
shuffle_word_list={answer_list}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<PressStartToBegin processStartMatch={processStartMatch} />
|
|
|
|
|
)}
|
|
|
|
@@ -210,6 +194,7 @@ function MatchingFrenzyMatchRun() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default MatchingFrenzyMatchRun;
|
|
|
|
|
|
|
|
|
|
function isEndOfQuestionList(current_question: number, question_list: [] | IMatchingFrenzyQuestion[]) {
|
|
|
|
|
return current_question >= question_list.length - 1;
|
|
|
|
|
}
|
|
|
|
|