From d1184b2c34de2d3721ba1b5c46f236f36c85235f Mon Sep 17 00:00:00 2001
From: Arman Shaikh
Date: Fri, 6 Mar 2026 08:28:00 +0000
Subject: [PATCH] feat: refactor match state management and enhance live
commentary features
---
.../game/ProcrastinationDesktop.tsx | 194 ++++++++++++++----
1 file changed, 158 insertions(+), 36 deletions(-)
diff --git a/src/components/game/ProcrastinationDesktop.tsx b/src/components/game/ProcrastinationDesktop.tsx
index 48808bf..c1816a6 100644
--- a/src/components/game/ProcrastinationDesktop.tsx
+++ b/src/components/game/ProcrastinationDesktop.tsx
@@ -1,7 +1,8 @@
import React, { useState, useCallback, useEffect } from "react";
import { Globe } from "lucide-react";
-const MAX_BALLS_PER_INNINGS = 90 * 6;
+const MATCH_OVERS = 20;
+const MAX_BALLS_PER_INNINGS = MATCH_OVERS * 6;
type BattingTeam = "INDIA" | "AUSTRALIA" | "DONE";
@@ -15,6 +16,8 @@ interface MatchState {
battingTeam: BattingTeam;
india: InningsState;
australia: InningsState;
+ recentBalls: string[];
+ lastBallCommentary: string;
}
function formatOvers(ballsFaced: number) {
@@ -24,6 +27,22 @@ function formatOvers(ballsFaced: number) {
function isInningsComplete(innings: InningsState) {
return innings.wickets >= 10 || innings.balls >= MAX_BALLS_PER_INNINGS;
}
+
+function createInitialMatchState(): MatchState {
+ return {
+ battingTeam: "INDIA",
+ india: { runs: 0, wickets: 0, balls: 0 },
+ australia: { runs: 0, wickets: 0, balls: 0 },
+ recentBalls: [],
+ lastBallCommentary: "Toss: India bat first.",
+ };
+}
+
+function formatRunRate(runs: number, balls: number) {
+ if (balls === 0) return "0.00";
+ return ((runs * 6) / balls).toFixed(2);
+}
+
interface ProcrastinationDesktopProps {
hidden?: boolean;
disabled?: boolean;
@@ -37,11 +56,11 @@ export const ProcrastinationDesktop: React.FC = ({
const [activeTab, setActiveTab] = useState<"cricket" | "cat" | "youtube">(
"cricket",
);
- const [match, setMatch] = useState({
- battingTeam: "INDIA",
- india: { runs: 0, wickets: 0, balls: 0 },
- australia: { runs: 0, wickets: 0, balls: 0 },
- });
+ const [match, setMatch] = useState(createInitialMatchState);
+
+ const resetMatch = useCallback(() => {
+ setMatch(createInitialMatchState());
+ }, []);
useEffect(() => {
const timer = setInterval(() => {
@@ -51,31 +70,61 @@ export const ProcrastinationDesktop: React.FC = ({
const teamKey = prev.battingTeam === "INDIA" ? "india" : "australia";
const currentInnings = prev[teamKey];
+ const australiaChasedTarget =
+ prev.battingTeam === "AUSTRALIA" && prev.australia.runs > prev.india.runs;
+
+ if (australiaChasedTarget) {
+ return { ...prev, battingTeam: "DONE" };
+ }
+
if (isInningsComplete(currentInnings)) {
if (prev.battingTeam === "INDIA") {
- return { ...prev, battingTeam: "AUSTRALIA" };
+ return {
+ ...prev,
+ battingTeam: "AUSTRALIA",
+ recentBalls: [],
+ lastBallCommentary: `Target: ${prev.india.runs + 1} from ${MATCH_OVERS} overs.`,
+ };
}
- return { ...prev, battingTeam: "DONE" };
+ return {
+ ...prev,
+ battingTeam: "DONE",
+ lastBallCommentary: "Australia innings complete.",
+ };
}
const outcomeRoll = Math.random();
let runDelta = 0;
let wicketDelta = 0;
+ let ballSymbol = ".";
+ let ballCommentary = "Dot ball.";
if (outcomeRoll < 0.04) {
wicketDelta = 1;
+ ballSymbol = "W";
+ ballCommentary = "WICKET! Batter dismissed.";
} else if (outcomeRoll < 0.44) {
runDelta = 0;
} else if (outcomeRoll < 0.79) {
runDelta = 1;
+ ballSymbol = "1";
+ ballCommentary = "Single taken.";
} else if (outcomeRoll < 0.91) {
runDelta = 2;
+ ballSymbol = "2";
+ ballCommentary = "Driven for two.";
} else if (outcomeRoll < 0.94) {
runDelta = 3;
+ ballSymbol = "3";
+ ballCommentary = "Excellent running, three runs.";
} else if (outcomeRoll < 0.995) {
runDelta = 4;
+ ballSymbol = "4";
+ ballCommentary = "FOUR! Finds the gap.";
} else {
runDelta = 6;
+ ballSymbol = "6";
+ ballCommentary = "SIX! Huge hit into the stands.";
}
const nextInnings: InningsState = {
@@ -84,16 +133,48 @@ export const ProcrastinationDesktop: React.FC = ({
balls: currentInnings.balls + 1,
};
- const nextState: MatchState = {
- ...prev,
- [teamKey]: nextInnings,
- } as MatchState;
+ const nextState: MatchState =
+ teamKey === "india"
+ ? {
+ ...prev,
+ india: nextInnings,
+ }
+ : {
+ ...prev,
+ australia: nextInnings,
+ };
+
+ const ballPrefix =
+ prev.battingTeam === "INDIA" ? `IND ${formatOvers(nextInnings.balls)}` : `AUS ${formatOvers(nextInnings.balls)}`;
+
+ nextState.recentBalls = [...prev.recentBalls.slice(-11), ballSymbol];
+ nextState.lastBallCommentary = `${ballPrefix}: ${ballCommentary}`;
+
+ const chaseCompleted =
+ prev.battingTeam === "AUSTRALIA" && nextState.australia.runs > nextState.india.runs;
+
+ if (chaseCompleted) {
+ return {
+ ...nextState,
+ battingTeam: "DONE",
+ lastBallCommentary: `${ballPrefix}: ${ballCommentary} Australia complete the chase.`,
+ };
+ }
if (isInningsComplete(nextInnings)) {
if (prev.battingTeam === "INDIA") {
- return { ...nextState, battingTeam: "AUSTRALIA" };
+ return {
+ ...nextState,
+ battingTeam: "AUSTRALIA",
+ recentBalls: [],
+ lastBallCommentary: `India finish on ${nextState.india.runs}/${nextState.india.wickets}. Target: ${nextState.india.runs + 1}`,
+ };
}
- return { ...nextState, battingTeam: "DONE" };
+ return {
+ ...nextState,
+ battingTeam: "DONE",
+ lastBallCommentary: `${ballPrefix}: Innings over.`,
+ };
}
return nextState;
@@ -105,29 +186,38 @@ export const ProcrastinationDesktop: React.FC = ({
const indiaRuns = match.india.runs;
const australiaRuns = match.australia.runs;
+ const target = indiaRuns + 1;
+ const runsNeeded = Math.max(0, target - australiaRuns);
+ const ballsRemaining = Math.max(0, MAX_BALLS_PER_INNINGS - match.australia.balls);
+ const requiredRate =
+ match.battingTeam === "AUSTRALIA" && ballsRemaining > 0 && runsNeeded > 0
+ ? ((runsNeeded * 6) / ballsRemaining).toFixed(2)
+ : "0.00";
+ const currentRate =
+ match.battingTeam === "INDIA"
+ ? formatRunRate(match.india.runs, match.india.balls)
+ : formatRunRate(match.australia.runs, match.australia.balls);
const liveLine =
match.battingTeam === "INDIA"
- ? "● LIVE - India 1st innings in progress"
+ ? `● LIVE - India batting first (${MATCH_OVERS}-over match)`
: match.battingTeam === "AUSTRALIA"
- ? indiaRuns === australiaRuns
- ? "● LIVE - Scores level"
- : australiaRuns < indiaRuns
- ? `● LIVE - Australia trail by ${indiaRuns - australiaRuns} runs`
- : `● LIVE - Australia lead by ${australiaRuns - indiaRuns} runs`
- : indiaRuns === australiaRuns
- ? "● RESULT - Match tied after one innings each"
- : indiaRuns > australiaRuns
- ? `● RESULT - India lead by ${indiaRuns - australiaRuns} runs after one innings each`
- : `● RESULT - Australia lead by ${australiaRuns - indiaRuns} runs after one innings each`;
+ ? australiaRuns >= target
+ ? `● LIVE - Australia have chased ${target}`
+ : `● LIVE - Australia need ${runsNeeded} from ${ballsRemaining} balls`
+ : australiaRuns >= target
+ ? `● RESULT - Australia won by ${10 - match.australia.wickets} wickets`
+ : indiaRuns === australiaRuns
+ ? "● RESULT - Match tied"
+ : `● RESULT - India won by ${indiaRuns - australiaRuns} runs`;
const statusColorClass =
match.battingTeam !== "DONE"
? "text-green-700"
- : indiaRuns > australiaRuns
- ? "text-blue-700"
- : indiaRuns < australiaRuns
- ? "text-red-700"
+ : australiaRuns >= target
+ ? "text-red-700"
+ : indiaRuns > australiaRuns
+ ? "text-blue-700"
: "text-gray-700";
const browserTitle =
@@ -225,8 +315,8 @@ export const ProcrastinationDesktop: React.FC = ({
type="button"
onClick={() => setActiveTab("cricket")}
className={`${activeTab === "cricket"
- ? "bg-[#ECE9D8] border-t border-l border-r border-white border-b-0 font-bold"
- : "bg-[#c0c0c0] border border-[#808080]"
+ ? "bg-[#ECE9D8] border-t border-l border-r border-white border-b-0 font-bold"
+ : "bg-[#c0c0c0] border border-[#808080]"
} px-3 py-1 text-[11px] flex items-center gap-1`}
>
🏏 Cricket Live
@@ -235,8 +325,8 @@ export const ProcrastinationDesktop: React.FC = ({
type="button"
onClick={() => setActiveTab("cat")}
className={`${activeTab === "cat"
- ? "bg-[#ECE9D8] border-t border-l border-r border-white border-b-0 font-bold"
- : "bg-[#c0c0c0] border border-[#808080]"
+ ? "bg-[#ECE9D8] border-t border-l border-r border-white border-b-0 font-bold"
+ : "bg-[#c0c0c0] border border-[#808080]"
} px-3 py-1 text-[11px] flex items-center gap-1`}
>
🐱 Cat Videos
@@ -245,8 +335,8 @@ export const ProcrastinationDesktop: React.FC = ({
type="button"
onClick={() => setActiveTab("youtube")}
className={`${activeTab === "youtube"
- ? "bg-[#ECE9D8] border-t border-l border-r border-white border-b-0 font-bold"
- : "bg-[#c0c0c0] border border-[#808080]"
+ ? "bg-[#ECE9D8] border-t border-l border-r border-white border-b-0 font-bold"
+ : "bg-[#c0c0c0] border border-[#808080]"
} px-3 py-1 text-[11px] flex items-center gap-1`}
>
▶️ YouTube
@@ -282,18 +372,50 @@ export const ProcrastinationDesktop: React.FC = ({
+
+
+
Current RR
+
{currentRate}
+
+
+
+
Req RR
+
{requiredRate}
+
+
+
Balls Left
+
{ballsRemaining}
+
+
+
+
Last Over Feed
+
+ {match.recentBalls.length > 0 ? match.recentBalls.join(" ") : "No balls yet"}
+
+
{liveLine}
+
{match.lastBallCommentary}
-
+
Live Chat (2.4k)
Scorecard
Commentary
+
>
)}