From 782e5fb528061fdc91fee16ad4900fcebe550760 Mon Sep 17 00:00:00 2001 From: Kegongteng Date: Mon, 15 Jun 2026 19:30:39 +0800 Subject: [PATCH] number-ball --- app/page.tsx | 1 + components/logic.tsx | 19 +++++++++++++++---- components/number-ball.tsx | 13 +++++++++---- components/single-panel.tsx | 8 +------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 17ccb7d..bdbbd98 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -69,6 +69,7 @@ export default function Page() { number={n} state={actions.getBallState(n)} colorIndex={actions.getBallColorIndex(n)} + dimmed={actions.getBallDimmed(n)} size="large" /> ))} diff --git a/components/logic.tsx b/components/logic.tsx index a97a265..0a1b072 100644 --- a/components/logic.tsx +++ b/components/logic.tsx @@ -88,6 +88,7 @@ export interface RollCallActions { clearResult: () => void getBallState: (n: number) => "idle" | "highlighted" | "used" getBallColorIndex: (n: number) => number | undefined + getBallDimmed: (n: number) => boolean } export const COLORS = [ @@ -112,7 +113,7 @@ export const COLORS = [ export function useRollCallLogic(): [RollCallState, RollCallActions] { const [mode, setMode] = useState("single") - const [totalTasks, setTotalTasks] = useState(20) + const [totalTasks, setTotalTasks] = useState(35) const [pickCount, setPickCount] = useState(1) const [rounds, setRounds] = useState(1) const [allowRepeat, setAllowRepeat] = useState(false) @@ -251,14 +252,15 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] { const getBallState = useCallback((n: number): "idle" | "highlighted" | "used" => { if (mode === "single") { - const isInRecords = selectedRecords.some(r => r.number === n) - if (isInRecords) return "highlighted" + // Only highlight current round's selections + const isCurrentRound = singleHighlighted.includes(n) + if (isCurrentRound) return "highlighted" return "idle" } if (highlighted.has(n)) return "highlighted" if (hasResult && usedAll.size > 0 && !usedAll.has(n)) return "used" return "idle" - }, [mode, selectedRecords, highlighted, hasResult, usedAll]) + }, [mode, singleHighlighted, highlighted, hasResult, usedAll]) const getBallColorIndex = useCallback((n: number): number | undefined => { if (mode === "single") { @@ -275,6 +277,14 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] { return undefined }, [mode, selectedRecords, groups]) + const getBallDimmed = useCallback((n: number): boolean => { + // Only dim in single mode when there are highlighted numbers + if (mode === "single" && singleHighlighted.length > 0) { + return !singleHighlighted.includes(n) + } + return false + }, [mode, singleHighlighted]) + const state: RollCallState = { mode, totalTasks, @@ -308,6 +318,7 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] { clearResult, getBallState, getBallColorIndex, + getBallDimmed, } return [state, actions] diff --git a/components/number-ball.tsx b/components/number-ball.tsx index c73ca02..8e9c9a0 100644 --- a/components/number-ball.tsx +++ b/components/number-ball.tsx @@ -8,19 +8,23 @@ interface NumberBallProps { state: "idle" | "highlighted" | "used" colorIndex?: number size?: "normal" | "large" + dimmed?: boolean } -export function NumberBall({ number, state, colorIndex, size = "normal" }: NumberBallProps) { +export function NumberBall({ number, state, colorIndex, size = "normal", dimmed = false }: NumberBallProps) { const isHighlighted = state === "highlighted" - const borderColor = isHighlighted && colorIndex !== undefined + const hasColor = colorIndex !== undefined + + const borderColor = hasColor ? COLORS[colorIndex] : state === "idle" ? "#e2e6ea" : "#eef0f2" - const bgColor = isHighlighted && colorIndex !== undefined + const bgColor = isHighlighted && hasColor ? COLORS[colorIndex] : "transparent" - const textColor = isHighlighted && colorIndex !== undefined + const textColor = isHighlighted && hasColor ? "#ffffff" + : hasColor ? COLORS[colorIndex] : state === "idle" ? "#8a95a1" : "#cdd2d8" @@ -30,6 +34,7 @@ export function NumberBall({ number, state, colorIndex, size = "normal" }: Numbe "flex items-center justify-center font-mono select-none transition-all duration-150", size === "normal" && "w-8 h-8 text-sm", size === "large" && "w-14 h-14 text-lg", + dimmed && !isHighlighted && "opacity-30", )} style={{ border: `1px solid ${borderColor}`, diff --git a/components/single-panel.tsx b/components/single-panel.tsx index 91fb691..fb6b5f7 100644 --- a/components/single-panel.tsx +++ b/components/single-panel.tsx @@ -8,13 +8,7 @@ interface SingleModePanelProps { export function SingleModePanel({ singleBatches }: SingleModePanelProps) { if (singleBatches.length === 0) { - return ( -
-
- — AWAITING INPUT — -
-
- ) + return null } // Reverse to show newest first -- 2.52.0