1
1
"use client" ;
2
- import React , { useEffect , useState } from "react" ;
2
+ import React , { useEffect , useRef , useState } from "react" ;
3
3
import { useRouter } from "next/navigation" ;
4
4
import PeerprepButton from "../shared/PeerprepButton" ;
5
5
import { useQuestionFilter } from "@/contexts/QuestionFilterContext" ;
6
6
import { useUserInfo } from "@/contexts/UserInfoContext" ;
7
+ import { isError , MatchRequest , MatchResponse } from "@/api/structs" ;
8
+ import {
9
+ checkMatchStatus ,
10
+ findMatch ,
11
+ } from "@/app/api/internal/matching/helper" ;
12
+ import { match } from "assert" ;
13
+ import { TIMEOUT } from "dns" ;
7
14
8
- const QUERY_INTERVAL_MILLISECONDS = 2000 ;
15
+ const QUERY_INTERVAL_MILLISECONDS = 5000 ;
16
+ const TIMEOUT_MILLISECONDS = 30000 ;
9
17
10
18
const getMatchRequestTime = ( ) : string => {
11
19
const now = new Date ( ) ;
@@ -41,29 +49,58 @@ const usePeriodicCallback = (
41
49
42
50
const Matchmaking = ( ) => {
43
51
const router = useRouter ( ) ;
44
- const [ isMatching , setIsMatching ] = useState ( false ) ;
52
+ const [ isMatching , setIsMatching ] = useState < boolean > ( false ) ;
45
53
const { difficulty, topics } = useQuestionFilter ( ) ;
46
54
const { userid } = useUserInfo ( ) ;
55
+ const timeout = useRef < NodeJS . Timeout > ( ) ;
47
56
48
- const handleMatch = ( ) => {
57
+ const handleMatch = async ( ) => {
49
58
if ( ! isMatching ) {
59
+ // start 30s timeout
60
+ timeout . current = setTimeout ( ( ) => {
61
+ setIsMatching ( false ) ;
62
+ console . log ( "Match request timed out after 30s" ) ;
63
+ } , TIMEOUT_MILLISECONDS ) ;
64
+
50
65
setIsMatching ( true ) ;
66
+ const matchRequest : MatchRequest = {
67
+ userId : userid ,
68
+ difficulty : difficulty ,
69
+ topicTags : topics ,
70
+ requestTime : getMatchRequestTime ( ) ,
71
+ } ;
51
72
console . log ( "Match attempted" ) ;
52
- console . log ( "Selected Difficulty:" , difficulty ) ;
53
- console . log ( "Selected Topics:" , topics ) ;
54
- console . debug ( "Request time: " , getMatchRequestTime ( ) ) ;
55
- console . debug ( "User id: " , userid ) ;
73
+ console . debug ( matchRequest ) ;
74
+
75
+ const status = await findMatch ( matchRequest ) ;
76
+ if ( status . error ) {
77
+ console . log ( "Failed to find match. Cancel matching." ) ;
78
+ setIsMatching ( false ) ;
79
+ return ;
80
+ }
81
+ console . log ( `Started finding match.` ) ;
56
82
} else {
83
+ // if user manually stopped it clear timeout
84
+ if ( timeout . current ) {
85
+ clearTimeout ( timeout . current ) ;
86
+ }
87
+
57
88
setIsMatching ( false ) ;
58
- console . debug ( "User stopped matching" ) ;
89
+ console . log ( "User stopped matching" ) ;
59
90
}
60
-
61
- // username as userid?
62
- // should probably just use the questionlist selections as params
63
91
} ;
64
92
65
- const queryResource = ( ) => {
66
- console . debug ( "Querying resource blob for matchmaking status" ) ;
93
+ const queryResource = async ( ) => {
94
+ const res = await checkMatchStatus ( userid ) ;
95
+ if ( isError ( res ) ) {
96
+ // for now 404 means no match found so dont stop matching on error, let request timeout
97
+ return ;
98
+ }
99
+ setIsMatching ( false ) ;
100
+ // TODO: iron out what is in a match response and sync up with collab service rooms
101
+ const matchRes : MatchResponse = res as MatchResponse ;
102
+ console . log ( "Match found!" ) ;
103
+ console . debug ( matchRes ) ;
67
104
} ;
68
105
69
106
usePeriodicCallback ( queryResource , QUERY_INTERVAL_MILLISECONDS , isMatching ) ;
@@ -79,7 +116,7 @@ const Matchmaking = () => {
79
116
{ isMatching ? "Cancel Match" : "Find Match" }
80
117
</ PeerprepButton >
81
118
{ isMatching && (
82
- < div className = "w-5 h-5 bg-difficulty-hard rounded-full ml-2" />
119
+ < div className = "w-3 h-3 bg-difficulty-hard rounded-full ml-2" />
83
120
) }
84
121
</ div >
85
122
</ div >
0 commit comments