mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
feat: queue-ux-improvements (#419)
* feat(queue): add ETA display, equalizer indicator and collapsible now playing
* deleted endsAt and showDuration strings, changed eta update to 30s
* feat(queue): ETA tooltip, persistent Now Playing collapse, EQ bar pause, remove redundant Play icon
* feat(queue): fold ETA into existing total/remaining toggle as third mode
The standalone ETA span next to the track counter is removed; instead the
clickable duration label in the queue header now rotates through three
modes per click: total → remaining → eta → total. Counter (N/M) stays
where it was.
ETA mode keeps the live-feel treatment from the original PR (accent
colour while playing, muted at 50% opacity when paused). The other two
modes use plain accent.
i18n: queue.etaTooltip removed (no longer a separate descriptive label),
queue.showEta added as the action tooltip ('Show estimated end time')
in all 8 locales — matches the showRemaining / showTotal pattern.
* docs(changelog): add #419 queue UX improvements entry
Adds the [1.45.0] / Added entry for this PR's queue panel refinements
(position counter, tri-state duration toggle including ETA, collapsible
Now Playing section, animated EQ indicator).
---------
Co-authored-by: Psychotoxical <171614930+Psychotoxical@users.noreply.github.com>
This commit is contained in:
@@ -825,7 +825,7 @@ export function SeekbarPreview({
|
||||
}
|
||||
};
|
||||
const tick = () => {
|
||||
if (document.hidden || window.__psyHidden || window.__psyBlurred) {
|
||||
if (document.hidden || window.__psyHidden) {
|
||||
pollId = window.setTimeout(() => {
|
||||
pollId = null;
|
||||
tick();
|
||||
@@ -912,14 +912,11 @@ export default function WaveformSeek({ trackId }: Props) {
|
||||
const waveformBins = usePlayerStore(s => s.waveformBins);
|
||||
const duration = usePlayerStore(s => s.currentTrack?.duration ?? 0);
|
||||
const seekbarStyle = useAuthStore(s => s.seekbarStyle);
|
||||
const reducedAnimations = useAuthStore(s => s.reducedAnimations);
|
||||
|
||||
// Ref so the subscription callback (closed over at mount) can read the
|
||||
// current style without stale-closure issues.
|
||||
const styleRef = useRef(seekbarStyle);
|
||||
styleRef.current = seekbarStyle;
|
||||
const reducedRef = useRef(reducedAnimations);
|
||||
reducedRef.current = reducedAnimations;
|
||||
|
||||
useEffect(() => {
|
||||
if (!trackId) {
|
||||
@@ -1054,7 +1051,6 @@ export default function WaveformSeek({ trackId }: Props) {
|
||||
animStateRef.current = makeAnimState();
|
||||
let rafId: number | null = null;
|
||||
let pollId: number | null = null;
|
||||
let skip = false;
|
||||
const stop = () => {
|
||||
if (rafId !== null) {
|
||||
cancelAnimationFrame(rafId);
|
||||
@@ -1066,22 +1062,14 @@ export default function WaveformSeek({ trackId }: Props) {
|
||||
}
|
||||
};
|
||||
const tick = () => {
|
||||
if (document.hidden || window.__psyHidden || window.__psyBlurred) {
|
||||
if (document.hidden || window.__psyHidden) {
|
||||
pollId = window.setTimeout(() => {
|
||||
pollId = null;
|
||||
tick();
|
||||
}, 400);
|
||||
return;
|
||||
}
|
||||
// 30 fps cap when reducedAnimations is on: skip every other rAF, advance
|
||||
// animation time by a doubled delta so wave speed stays the same.
|
||||
if (reducedRef.current && skip) {
|
||||
skip = false;
|
||||
rafId = requestAnimationFrame(tick);
|
||||
return;
|
||||
}
|
||||
skip = reducedRef.current;
|
||||
animStateRef.current.time += reducedRef.current ? 0.032 : 0.016;
|
||||
animStateRef.current.time += 0.016;
|
||||
drawSeekbar(canvas, seekbarStyle, heightsRef.current, progressRef.current, bufferedRef.current, animStateRef.current);
|
||||
rafId = requestAnimationFrame(tick);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user