Wire client SignalrService to the live .NET backend

- @microsoft/signalr client implementing OnlineService: REST auth, hub
  matchmaking, server-driven game state (onState), play/trump, reactions;
  delegates not-yet-server-backed features (profile/friends/shop/chat/rooms)
  to the mock. Selected via NEXT_PUBLIC_USE_SERVER=1 (NEXT_PUBLIC_SERVER_URL)
- game-store live mode: enterServerMatch + applyServerState (maps server DTO,
  hides opponent hands, tally + SFX), inputs route to the hub; no local engine
- MatchmakingScreen auto-enters the live match when the server signals ready
- Verified end-to-end via scripts/live-test.mjs (auth -> hub -> match -> state)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-04 13:13:48 +03:30
parent a3b797c8a3
commit ceccf70de7
11 changed files with 707 additions and 5 deletions
@@ -2,6 +2,7 @@
import { AnimatePresence, motion } from "framer-motion";
import { Crown, Loader2 } from "lucide-react";
import { useEffect } from "react";
import { ScreenShell } from "@/components/online/ScreenHeader";
import { useGameStore } from "@/lib/game-store";
import { useOnlineStore } from "@/lib/online-store";
@@ -16,6 +17,7 @@ export function MatchmakingScreen() {
const mm = useOnlineStore((s) => s.matchmaking);
const cancelMatchmaking = useOnlineStore((s) => s.cancelMatchmaking);
const newOnlineMatch = useGameStore((s) => s.newOnlineMatch);
const enterServerMatch = useGameStore((s) => s.enterServerMatch);
const upgradePlan = useSessionStore((s) => s.upgradePlan);
const goGame = useUIStore((s) => s.goGame);
const go = useUIStore((s) => s.go);
@@ -24,6 +26,14 @@ export function MatchmakingScreen() {
const queued = mm.phase === "queued";
const slots = [0, 1, 2, 3];
// Live server: the server starts the match itself — auto-enter when ready.
useEffect(() => {
if (mm.phase === "ready" && getService().live) {
enterServerMatch(getService());
goGame("home");
}
}, [mm.phase, enterServerMatch, goGame]);
const cancel = async () => {
await cancelMatchmaking();
go("online");