aboutsummaryrefslogtreecommitdiffstats
path: root/src/app
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2026-04-16 20:44:54 -0700
committerPinapelz <yukais@pinapelz.com>2026-04-16 20:44:54 -0700
commitcdae9d710a8b32bd2cbbb50fcb78cdfa7ed396b9 (patch)
tree0a5902cea9bf77d0e62aff108d390365a70ef9c5 /src/app
parentb7ab308f5d92172ff6e10d078cb12c1501cd161a (diff)
type: detect intermission for if first line of lrc starts late into
media
Diffstat (limited to 'src/app')
-rw-r--r--src/app/game/page.tsx43
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>
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage