Skip to content

Commit 0e645ac

Browse files
committed
fix(karaoke): unify fullscreen controls across web and desktop
1 parent 7eaed56 commit 0e645ac

4 files changed

Lines changed: 28 additions & 7 deletions

File tree

apps/karaoke/src/App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import { exportLrc, exportSrt, exportTtml, fileBaseName, linesToCues, parseTimedLyrics } from "./lib/lyrics";
1717
import { downloadText, fileToAsset, parseProject, PROJECT_EXTENSION, serializeProject } from "./lib/project";
1818
import { leaveDesktopFullscreen, openKaraokeProjectFromDisk, saveTextToDisk, toggleDesktopFullscreen } from "./lib/desktop";
19+
import { playerPageClassName } from "./lib/player";
1920
import type { BackgroundMode, KaraokeCue, KaraokeProject, ProjectAsset } from "./types";
2021
import "./styles.css";
2122

@@ -311,7 +312,7 @@ function Player({ title, artist, vocalAudio, instrumentalAudio, backgroundImage,
311312

312313
return (
313314
<div
314-
className={`player-page ${fullscreen && !controlsVisible ? "player-page--controls-hidden" : ""}`}
315+
className={playerPageClassName(fullscreen, controlsVisible)}
315316
ref={shell}
316317
onPointerMove={revealControls}
317318
onPointerDown={revealControls}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { describe, expect, it } from "vitest";
2+
import { playerPageClassName } from "./player";
3+
4+
describe("player page classes", () => {
5+
it("marks fullscreen independently of the browser Fullscreen API", () => {
6+
expect(playerPageClassName(true, true)).toBe("player-page player-page--fullscreen");
7+
});
8+
9+
it("hides controls only while fullscreen", () => {
10+
expect(playerPageClassName(true, false)).toBe("player-page player-page--fullscreen player-page--controls-hidden");
11+
expect(playerPageClassName(false, false)).toBe("player-page");
12+
});
13+
});

apps/karaoke/src/lib/player.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function playerPageClassName(fullscreen: boolean, controlsVisible: boolean) {
2+
return [
3+
"player-page",
4+
fullscreen ? "player-page--fullscreen" : "",
5+
fullscreen && !controlsVisible ? "player-page--controls-hidden" : "",
6+
].filter(Boolean).join(" ");
7+
}

apps/karaoke/src/styles.css

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ kbd { padding: 3px 7px; border: 1px solid #bec5c3; border-radius: 6px; backgroun
124124

125125
.player-page { height: 100vh; background: #090b0d; color: white; overflow: hidden; }
126126
.player-layout { height: calc(100vh - 72px); display: grid; grid-template-rows: 1fr auto; }
127-
.player-page:fullscreen .player-layout { height: 100vh; }
127+
.player-page--fullscreen .player-layout { height: 100vh; }
128128
.karaoke-stage { position: relative; overflow: hidden; display: grid; place-items: center; background-size: cover; background-position: center; }
129129
.karaoke-stage--stage { background: radial-gradient(circle at 52% 28%, #2b4148, #080c0e 54%, #020304); }
130130
.karaoke-stage--gray { background: radial-gradient(circle at 50% 28%, #343a3e, #0b0d0e 70%); }
@@ -163,17 +163,17 @@ kbd { padding: 3px 7px; border: 1px solid #bec5c3; border-radius: 6px; backgroun
163163
.player-export svg { width: 14px; }
164164
.export-buttons { display: flex; gap: 7px; }
165165
.export-buttons button { min-height: 32px; background: transparent; }
166-
.player-page:fullscreen .player-controls {
166+
.player-page--fullscreen .player-controls {
167167
position: absolute; z-index: 10; bottom: 12px; left: 50%;
168168
transform: translateX(-50%) translateY(0);
169169
width: min(900px, calc(100% - 30px));
170170
background: rgba(4,7,8,.73); backdrop-filter: blur(14px); border-radius: 18px;
171171
opacity: 1; transition: opacity 220ms ease, transform 220ms ease;
172172
}
173-
.player-page:fullscreen .karaoke-stage { position: absolute; inset: 0; }
174-
.player-page:fullscreen .karaoke-stage__meta { top: 26px; }
175-
.player-page:fullscreen.player-page--controls-hidden { cursor: none; }
176-
.player-page:fullscreen.player-page--controls-hidden .player-controls {
173+
.player-page--fullscreen .karaoke-stage { position: absolute; inset: 0; }
174+
.player-page--fullscreen .karaoke-stage__meta { top: 26px; }
175+
.player-page--fullscreen.player-page--controls-hidden { cursor: none; }
176+
.player-page--fullscreen.player-page--controls-hidden .player-controls {
177177
opacity: 0;
178178
pointer-events: none;
179179
transform: translateX(-50%) translateY(20px);

0 commit comments

Comments
 (0)