From 8555675740d750ac62309de1f8885d2ea230cc22 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Sat, 29 Nov 2025 02:44:54 +0530 Subject: [PATCH] =?UTF-8?q?-=20Added=20isQueueing=20state=20to=20Player=20?= =?UTF-8?q?component=20to=20track=20matchmaking=20state.=20-=20Implemented?= =?UTF-8?q?=20animated=20"Finding=20opponent=E2=80=A6"=20UI=20with=20pulsi?= =?UTF-8?q?ng=20dots=20using=20Framer=20Motion.=20-=20Added=20cancelQueue(?= =?UTF-8?q?)=20to=20allow=20players=20to=20cancel=20matchmaking=20mid-sear?= =?UTF-8?q?ch.=20-=20Updated=20startQueue()=20to=20set=20queueing=20state?= =?UTF-8?q?=20immediately=20for=20instant=20feedback.=20-=20Improved=20pla?= =?UTF-8?q?yer=20experience=20by=20clearly=20showing=20matchmaking=20progr?= =?UTF-8?q?ess=20instead=20of=20silent=20waiting.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tictactoe/Player.tsx | 103 ++++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 18 deletions(-) diff --git a/src/tictactoe/Player.tsx b/src/tictactoe/Player.tsx index 64880f1..faa47f3 100644 --- a/src/tictactoe/Player.tsx +++ b/src/tictactoe/Player.tsx @@ -21,6 +21,7 @@ export default function Player({ localStorage.getItem("username") ?? "" ); const [selectedMode, setSelectedMode] = useState("classic"); + const [isQueueing, setIsQueueing] = useState(false); // ------------------------------------------ // CONNECT @@ -36,8 +37,21 @@ export default function Player({ // MATCHMAKING // ------------------------------------------ async function startQueue(selectedMode: string) { - const ticket = await joinMatchmaker(selectedMode); - console.log("Queued:", ticket); + setIsQueueing(true); + + try { + const ticket = await joinMatchmaker(selectedMode); + console.log("Queued:", ticket); + } catch (err) { + console.error("Matchmaking failed:", err); + setIsQueueing(false); + } + } + + function cancelQueue() { + setIsQueueing(false); + // Nakama matchmaker tickets auto-expire by default in your setup. + // If you later add manual ticket cancel RPC, call it here. } useEffect(() => { @@ -148,22 +162,75 @@ export default function Player({ - startQueue(selectedMode)} - style={{ - padding: "10px 20px", - borderRadius: "12px", - background: "#3498db", - color: "white", - border: "none", - marginRight: "10px", - cursor: "pointer", - fontWeight: 600, - }} - > - Join Matchmaking - + {!isQueueing && ( + startQueue(selectedMode)} + style={{ + padding: "10px 20px", + borderRadius: "12px", + background: "#3498db", + color: "white", + border: "none", + marginRight: "10px", + cursor: "pointer", + fontWeight: 600, + }} + > + Join Matchmaking + + )} + + {/* Queueing animation */} + {isQueueing && ( + +
+ Finding an opponent… +
+ + {/* Animated pulsing dots */} + + ● ● ● + + + {/* Cancel button */} + +
+ )}