Skip to content

Commit bf9ce45

Browse files
committed
Fixes to matching timer (Lift timer state up into modal)
1 parent 23fdb95 commit bf9ce45

File tree

5 files changed

+74
-36
lines changed

5 files changed

+74
-36
lines changed

apps/frontend/src/app/matching/MatchingModal.tsx

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useState, useEffect } from 'react';
22
import {
3+
Button,
34
Modal,
45
} from 'antd';
56
import 'typeface-montserrat';
@@ -11,17 +12,37 @@ import JoinedMatchContent from './modalContent/JoinedMatchContent';
1112
import MatchNotFoundContent from './modalContent/MatchNotFoundContent';
1213
import MatchCancelledContent from './modalContent/MatchCancelledContent';
1314
import useMatching from '../services/use-matching';
15+
import { useTimer } from 'react-timer-hook';
1416

1517
interface MatchingModalProps {
1618
isOpen: boolean;
1719
close: () => void;
1820
}
1921

22+
const MATCH_TIMEOUT = 30;
23+
const JOIN_TIMEOUT = 5;
24+
2025
const MatchingModal: React.FC<MatchingModalProps> = ({ isOpen, close: _close }) => {
2126
const matchingState = useMatching();
2227
const [closedType, setClosedType] = useState<"finding" | "cancelled" | "joined">("finding");
23-
const [timeoutAfter, setTimeoutAfter] = useState<number>(9999);
2428
const isClosable = ["timeout", "closed"].includes(matchingState.state);
29+
const { totalSeconds, pause: pauseTimer, restart: restartTimer } = useTimer({
30+
expiryTimestamp: new Date(Date.now() + MATCH_TIMEOUT * 1000),
31+
autoStart: false,
32+
onExpire() {
33+
if (matchingState.state === "matching") {
34+
matchingState.timeout();
35+
return;
36+
}
37+
if (matchingState.state === "found") {
38+
matchingState.ok();
39+
setClosedType("joined");
40+
return;
41+
}
42+
console.warn(`matching is in ${matchingState.state}`)
43+
},
44+
});
45+
const passed = MATCH_TIMEOUT - totalSeconds;
2546

2647
function close() {
2748
// clean up matching and closedType State
@@ -32,43 +53,57 @@ const MatchingModal: React.FC<MatchingModalProps> = ({ isOpen, close: _close })
3253
_close();
3354
}
3455

56+
useEffect(() => {
57+
if (matchingState.state === "cancelling" || matchingState.state === "timeout") {
58+
pauseTimer();
59+
return;
60+
}
61+
if (matchingState.state === "found") {
62+
restartTimer(
63+
new Date(Date.now() + JOIN_TIMEOUT * 1000),
64+
)
65+
}
66+
}, [matchingState])
67+
3568
const renderModalContent = () => {
3669
switch (matchingState.state) {
3770
case 'closed':
3871
switch (closedType) {
3972
case "finding":
40-
return <FindMatchContent beginMatch={matchingState.start}/>;
73+
return <FindMatchContent beginMatch={params => {
74+
restartTimer(
75+
new Date(Date.now() + MATCH_TIMEOUT * 1000),
76+
);
77+
matchingState.start(params);
78+
}}/>;
4179
case "cancelled":
4280
return <MatchCancelledContent
4381
reselect={() => {
4482
setClosedType("finding");
4583
}}
4684
retry={() => {}}
47-
canceledIn={timeoutAfter}
85+
canceledIn={passed}
4886
/>;
4987
case "joined":
5088
return <JoinedMatchContent
51-
cancel={() => {
52-
setClosedType("cancelled");
53-
}}
54-
name1={matchingState.info?.myName || ""}
55-
name2={matchingState.info?.partnerName || ""}
89+
cancel={() => {
90+
setClosedType("cancelled");
91+
}}
92+
name1={matchingState.info?.myName ?? ""}
93+
name2={matchingState.info?.partnerName ??""}
5694
/>;
5795
}
5896
case 'matching':
5997
return <MatchingInProgressContent
60-
cancelMatch={(timeoutAfter: number) => {
98+
cancelMatch={() => {
6199
setClosedType("cancelled");
62-
setTimeoutAfter(timeoutAfter);
63100
matchingState.cancel();
101+
pauseTimer();
64102
}}
65-
timeout={(timeoutAfter: number) => {
66-
matchingState.timeout()
67-
setTimeoutAfter(timeoutAfter);
68-
}}
103+
timePassed={passed}
69104
/>;
70105
case 'cancelling':
71-
return <MatchingInProgressContent cancelMatch={() => {}} timeout={() => {}}/>;
106+
return <MatchingInProgressContent cancelMatch={() => {}} timePassed={passed}/>;
72107
case 'starting':
73108
return <FindMatchContent beginMatch={() => {}}/>
74109
case 'found':
@@ -83,9 +118,10 @@ const MatchingModal: React.FC<MatchingModalProps> = ({ isOpen, close: _close })
83118
}}
84119
name1={matchingState.info.myName}
85120
name2={matchingState.info.partnerName}
86-
/>
121+
joiningIn={totalSeconds}
122+
/>
87123
case 'timeout':
88-
return <MatchNotFoundContent reselect={matchingState.ok} retry={() => {}} timedOutIn={10}/>;
124+
return <MatchNotFoundContent reselect={matchingState.ok} retry={() => {}} timedOutIn={passed}/>;
89125
default:
90126
throw new Error('Invalid matching state.');
91127
}

apps/frontend/src/app/matching/modalContent/FindMatchContent.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ const FindMatchContent: React.FC<Props> = ({ beginMatch }) => {
6262
</div>
6363
<button className="find-match-button"
6464
onClick={async () => {
65+
async function ValidateUser() {
66+
return {
67+
data: {
68+
69+
username:"asdasd",
70+
}
71+
}
72+
}
6573
setIsLoading(true);
6674
const user = await ValidateUser();
6775
beginMatch({

apps/frontend/src/app/matching/modalContent/JoinedMatchContent.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'typeface-montserrat';
99
import './styles.scss';
1010
import { handleCancelMatch } from '../handlers';
1111
import { formatTime } from '@/utils/DateTime';
12+
import { useStopwatch } from 'react-timer-hook';
1213

1314

1415
interface Props {
@@ -21,6 +22,9 @@ const JoinedMatchContent: React.FC<Props> = ({cancel, name1: me, name2: you}) =>
2122
const matchAlreadyJoined = () => {
2223
throw new Error('Match already joined.');
2324
}
25+
const { totalSeconds } = useStopwatch({
26+
autoStart: true
27+
})
2428

2529
return (
2630
<div className="joined-match-content">
@@ -45,7 +49,7 @@ const JoinedMatchContent: React.FC<Props> = ({cancel, name1: me, name2: you}) =>
4549
</div>
4650
<div className="match-status-label">Match Found!</div>
4751
<div className="match-status-message">
48-
Waiting for others... {formatTime(83)}
52+
Waiting for others... {formatTime(totalSeconds)}
4953
</div>
5054
<button className="joined-match-deactivated-button"
5155
disabled

apps/frontend/src/app/matching/modalContent/MatchFoundContent.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,18 @@ import 'typeface-montserrat';
55
import './styles.scss';
66
import { handleCancelMatch, handleJoinMatch } from '../handlers';
77
import { formatTime } from '@/utils/DateTime';
8-
import { useTimer } from "react-timer-hook"
98

109
interface Props {
1110
join(): void,
1211
cancel(): void,
1312
name1: string, // user's username
1413
name2: string, // matched user's username
14+
joiningIn: number,
1515
}
1616

1717
const TIMEOUT = 10;
1818

19-
const MatchFoundContent: React.FC<Props> = ({join, cancel, name1: me, name2: you}) => {
20-
const { totalSeconds } = useTimer({
21-
expiryTimestamp: new Date(Date.now() + 10 * 1000),
22-
onExpire: join
23-
});
19+
const MatchFoundContent: React.FC<Props> = ({join, cancel, name1: me, name2: you, joiningIn}) => {
2420

2521
return (
2622
<div className="matching-found-content">
@@ -45,7 +41,7 @@ const MatchFoundContent: React.FC<Props> = ({join, cancel, name1: me, name2: you
4541
</div>
4642
<div className="match-status-label">Match Found!</div>
4743
<div className="match-status-message">
48-
Joining in... {formatTime(totalSeconds)}
44+
Joining in... {formatTime(joiningIn)}
4945
</div>
5046
<button className="join-match-button"
5147
onClick={join}

apps/frontend/src/app/matching/modalContent/MatchingInProgressContent.tsx

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,24 @@ import { handleCancelMatch } from '../handlers';
66
import { useTimer } from "react-timer-hook"
77
import {formatTime} from '@/utils/DateTime';
88

9-
const TIMEOUT = 10;
10-
119
interface Props {
12-
cancelMatch(cancelledIn: number): void
13-
timeout(timeoutIn: number): void
10+
cancelMatch(): void
11+
timePassed: number
1412
}
1513

16-
const MatchingInProgressContent: React.FC<Props> = ({cancelMatch: cancel, timeout}) => {
17-
const { totalSeconds } = useTimer({
18-
expiryTimestamp: new Date(Date.now() + 10 * 1000),
19-
onExpire: () => timeout(TIMEOUT - totalSeconds),
20-
});
14+
const MatchingInProgressContent: React.FC<Props> = ({cancelMatch: cancel, timePassed}) => {
2115

2216
return (
2317
<div className="matching-in-progess-content">
2418
<LoadingOutlined className="loading-icon"/>
2519
<div className="match-status-label">Matching in Progress</div>
2620
<div className="match-status-message">
2721
Please be patient as we match you with other online users<br/><br/>
28-
{formatTime(TIMEOUT - totalSeconds)}
22+
{formatTime(timePassed)}
2923
</div>
3024
<button className="cancel-match-button"
3125
onClick={() => {
32-
cancel(TIMEOUT - totalSeconds);
26+
cancel();
3327
}}
3428
>
3529
Cancel

0 commit comments

Comments
 (0)