diff options
| author | Pinapelz <yukais@pinapelz.com> | 2026-04-16 20:44:54 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2026-04-16 20:44:54 -0700 |
| commit | cdae9d710a8b32bd2cbbb50fcb78cdfa7ed396b9 (patch) | |
| tree | 0a5902cea9bf77d0e62aff108d390365a70ef9c5 | |
| parent | b7ab308f5d92172ff6e10d078cb12c1501cd161a (diff) | |
type: detect intermission for if first line of lrc starts late into
media
| -rw-r--r-- | src/app/game/page.tsx | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/src/app/game/page.tsx b/src/app/game/page.tsx index 3ad7009..f43b3c4 100644 --- a/src/app/game/page.tsx +++ b/src/app/game/page.tsx @@ -257,6 +257,17 @@ function GameInner() { return idx; }, [currentMs, gameLines]); + const intermissionData = useMemo(() => { + const firstMs = gameLines[0]?.millisecond ?? 0; + if (firstMs <= 0) { + return { pct: 100, remainingMs: 0 }; + } + const clampedCurrent = Math.max(0, currentMs); + const remainingMs = Math.max(0, firstMs - clampedCurrent); + const pct = Math.min(100, Math.max(0, (clampedCurrent / firstMs) * 100)); + return { pct, remainingMs }; + }, [gameLines, currentMs]); + useEffect(() => { const idx = g.displayedLineIdx; if (idx < 0 || !gameLines[idx]) { @@ -397,14 +408,6 @@ function GameInner() { media.play(); setPhase("playing"); gameStartTimeRef.current = Date.now(); - if (gameLines[0]) { - dispatch({ - type: "ADVANCE", - newIdx: 0, - prevCompleted: true, - }); - lastHandledIdxRef.current = 0; - } }; countdownIntervalRef.current = window.setInterval(() => { @@ -685,7 +688,29 @@ function GameInner() { <GameArea> {phase === "playing" && g.displayedLineIdx < 0 && - gameLines.length > 0 && <GetReadyText>Get ready...</GetReadyText>} + gameLines.length > 0 && ( + <> + <UpcomingWrap> + <UpcomingLabel>Next</UpcomingLabel> + <UpcomingText>{gameLines[0]?.content ?? ""}</UpcomingText> + </UpcomingWrap> + <CurrentWrap style={{ position: "relative" }}> + <LineTimingRow> + <LineTimingMeta> + Time to first line:{" "} + <LineTimingValue> + {Math.max(0, intermissionData.remainingMs / 1000).toFixed(1)}s + </LineTimingValue> + </LineTimingMeta> + </LineTimingRow> + <LineTimingBar> + <LineTimingFill $pct={intermissionData.pct} /> + </LineTimingBar> + <CharRow ref={charRowRef} /> + <CompletedLineFade>[INTERMISSION]</CompletedLineFade> + </CurrentWrap> + </> + )} {g.displayedLineIdx >= 0 && gameLines[g.displayedLineIdx] && ( <> <UpcomingWrap> |
