1
1
import React , { useState , useEffect } from 'react' ;
2
2
import {
3
+ Button ,
3
4
Modal ,
4
5
} from 'antd' ;
5
6
import 'typeface-montserrat' ;
@@ -11,17 +12,37 @@ import JoinedMatchContent from './modalContent/JoinedMatchContent';
11
12
import MatchNotFoundContent from './modalContent/MatchNotFoundContent' ;
12
13
import MatchCancelledContent from './modalContent/MatchCancelledContent' ;
13
14
import useMatching from '../services/use-matching' ;
15
+ import { useTimer } from 'react-timer-hook' ;
14
16
15
17
interface MatchingModalProps {
16
18
isOpen : boolean ;
17
19
close : ( ) => void ;
18
20
}
19
21
22
+ const MATCH_TIMEOUT = 30 ;
23
+ const JOIN_TIMEOUT = 5 ;
24
+
20
25
const MatchingModal : React . FC < MatchingModalProps > = ( { isOpen, close : _close } ) => {
21
26
const matchingState = useMatching ( ) ;
22
27
const [ closedType , setClosedType ] = useState < "finding" | "cancelled" | "joined" > ( "finding" ) ;
23
- const [ timeoutAfter , setTimeoutAfter ] = useState < number > ( 9999 ) ;
24
28
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 ;
25
46
26
47
function close ( ) {
27
48
// clean up matching and closedType State
@@ -32,43 +53,57 @@ const MatchingModal: React.FC<MatchingModalProps> = ({ isOpen, close: _close })
32
53
_close ( ) ;
33
54
}
34
55
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
+
35
68
const renderModalContent = ( ) => {
36
69
switch ( matchingState . state ) {
37
70
case 'closed' :
38
71
switch ( closedType ) {
39
72
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
+ } } /> ;
41
79
case "cancelled" :
42
80
return < MatchCancelledContent
43
81
reselect = { ( ) => {
44
82
setClosedType ( "finding" ) ;
45
83
} }
46
84
retry = { ( ) => { } }
47
- canceledIn = { timeoutAfter }
85
+ canceledIn = { passed }
48
86
/> ;
49
87
case "joined" :
50
88
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 ?? "" }
56
94
/> ;
57
95
}
58
96
case 'matching' :
59
97
return < MatchingInProgressContent
60
- cancelMatch = { ( timeoutAfter : number ) => {
98
+ cancelMatch = { ( ) => {
61
99
setClosedType ( "cancelled" ) ;
62
- setTimeoutAfter ( timeoutAfter ) ;
63
100
matchingState . cancel ( ) ;
101
+ pauseTimer ( ) ;
64
102
} }
65
- timeout = { ( timeoutAfter : number ) => {
66
- matchingState . timeout ( )
67
- setTimeoutAfter ( timeoutAfter ) ;
68
- } }
103
+ timePassed = { passed }
69
104
/> ;
70
105
case 'cancelling' :
71
- return < MatchingInProgressContent cancelMatch = { ( ) => { } } timeout = { ( ) => { } } /> ;
106
+ return < MatchingInProgressContent cancelMatch = { ( ) => { } } timePassed = { passed } /> ;
72
107
case 'starting' :
73
108
return < FindMatchContent beginMatch = { ( ) => { } } />
74
109
case 'found' :
@@ -83,9 +118,10 @@ const MatchingModal: React.FC<MatchingModalProps> = ({ isOpen, close: _close })
83
118
} }
84
119
name1 = { matchingState . info . myName }
85
120
name2 = { matchingState . info . partnerName }
86
- />
121
+ joiningIn = { totalSeconds }
122
+ />
87
123
case 'timeout' :
88
- return < MatchNotFoundContent reselect = { matchingState . ok } retry = { ( ) => { } } timedOutIn = { 10 } /> ;
124
+ return < MatchNotFoundContent reselect = { matchingState . ok } retry = { ( ) => { } } timedOutIn = { passed } /> ;
89
125
default :
90
126
throw new Error ( 'Invalid matching state.' ) ;
91
127
}
0 commit comments