feat: optimize media controls in song view

- Center media control buttons horizontally
- Remove tempo button (playspeed always 1x)
- Display time above button group for better UX
- Clean up unused SpeedSelector component
This commit is contained in:
Mistral Vibe
2026-04-07 14:13:14 +00:00
parent 3a36469789
commit b75c716dba
3 changed files with 338 additions and 184 deletions

View File

@@ -561,55 +561,56 @@ export function SongPage() {
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: 10,
gap: 8,
padding: "4px 0 12px",
flexShrink: 0,
}}
>
{/* Speed selector */}
<SpeedSelector />
{/* Skip back */}
<TransportButton onClick={() => seekTo(Math.max(0, currentTime - 30))} title="30s">
<IconSkipBack />
</TransportButton>
{/* Play/Pause */}
<button
onClick={isPlaying ? pause : play}
disabled={!activeVersion}
style={{
width: 46,
height: 46,
background: "#e8a22a",
borderRadius: "50%",
border: "none",
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: activeVersion ? "pointer" : "default",
opacity: activeVersion ? 1 : 0.4,
flexShrink: 0,
transition: "background 0.15s, transform 0.15s",
}}
onMouseEnter={(e) => { if (activeVersion) e.currentTarget.style.background = "#f0b740"; }}
onMouseLeave={(e) => { e.currentTarget.style.background = "#e8a22a"; }}
>
{isPlaying ? <IconPause /> : <IconPlay />}
</button>
{/* Skip forward */}
<TransportButton onClick={() => seekTo(currentTime + 30)} title="+30s">
<IconSkipFwd />
</TransportButton>
{/* Time display */}
<span style={{ fontFamily: "monospace", fontSize: 12, color: "rgba(255,255,255,0.35)", marginLeft: 4 }}>
{/* Time display - moved above buttons */}
<span style={{ fontFamily: "monospace", fontSize: 12, color: "rgba(255,255,255,0.35)", marginBottom: 4 }}>
<span style={{ color: "#d8d8e0" }}>{formatTime(currentTime)}</span>
{isReady && duration > 0 ? ` / ${formatTime(duration)}` : ""}
</span>
{/* Button group - centered */}
<div style={{ display: "flex", alignItems: "center", gap: 10 }}>
{/* Skip back */}
<TransportButton onClick={() => seekTo(Math.max(0, currentTime - 30))} title="30s">
<IconSkipBack />
</TransportButton>
{/* Play/Pause */}
<button
onClick={isPlaying ? pause : play}
disabled={!activeVersion}
style={{
width: 46,
height: 46,
background: "#e8a22a",
borderRadius: "50%",
border: "none",
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: activeVersion ? "pointer" : "default",
opacity: activeVersion ? 1 : 0.4,
flexShrink: 0,
transition: "background 0.15s, transform 0.15s",
}}
onMouseEnter={(e) => { if (activeVersion) e.currentTarget.style.background = "#f0b740"; }}
onMouseLeave={(e) => { e.currentTarget.style.background = "#e8a22a"; }}
>
{isPlaying ? <IconPause /> : <IconPlay />}
</button>
{/* Skip forward */}
<TransportButton onClick={() => seekTo(currentTime + 30)} title="+30s">
<IconSkipFwd />
</TransportButton>
</div>
</div>
@@ -958,26 +959,4 @@ function TransportButton({ onClick, title, children }: { onClick: () => void; ti
);
}
const SPEEDS = [0.5, 0.75, 1, 1.25, 1.5, 2];
function SpeedSelector() {
const [idx, setIdx] = useState(2);
return (
<button
onClick={() => setIdx((i) => (i + 1) % SPEEDS.length)}
style={{
fontSize: 11,
color: "rgba(255,255,255,0.28)",
background: "rgba(255,255,255,0.06)",
border: "1px solid rgba(255,255,255,0.07)",
borderRadius: 4,
padding: "3px 7px",
cursor: "pointer",
fontFamily: "inherit",
marginRight: 2,
}}
>
{SPEEDS[idx]}×
</button>
);
}