mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-27 17:06:42 +00:00
refactor(player-bar): H7 — split PlayerBar.tsx 802 → 354 LOC across 10 files (#670)
* refactor(player-bar): H7 — extract PlaybackTime + RemainingTime + formatTime The two memoized clock components (which update the DOM imperatively from the playbackProgress store without re-rendering PlayerBar) move into components/playerBar/PlaybackClock.tsx. formatTime helper → utils/playerBarHelpers.ts. PlayerBar.tsx: 802 → 765 LOC. * refactor(player-bar): H7 — extract PlayerTrackInfo The cover-art wrap + title/artist marquees + star + last.fm love buttons move into their own component. The new file uses PlayerState['openContextMenu'] for prop typing so the union literal type carries through. PlayerBar.tsx: 765 → 674 LOC. * refactor(player-bar): H7 — extract PlayerTransportControls Stop/Prev/Play/Next/Repeat buttons (with the preview-ring + schedule-badge overlays around play/pause) move into PlayerTransportControls.tsx. The component uses ReturnType<...> on the source hooks to derive its playPauseBind + scheduleRemaining prop types so the new file stays in lockstep with usePlaybackDelayPress + usePlaybackScheduleRemaining. PlayerBar.tsx: 674 → 621 LOC. * refactor(player-bar): H7 — extract PlayerSeekbarSection The waveform / radio progress / time-label block moves into its own component. PlayerSeekbarSection branches on isRadio (AzuraCast progress bar with elapsed+duration when available; LIVE badge otherwise) vs. regular track (WaveformSeek or perf-flag fallback + duration ↔ remaining toggle). PlayerBar.tsx: 621 → 582 LOC. * refactor(player-bar): H7 — extract PlayerVolume + PlayerOverflowMenu + 2 hooks PlayerVolume.tsx is the reusable volume button + slider combo, used in three layouts (inline, full menu, volume-only menu) — `inputId` / `sectionModifier` / `wrapModifier` props handle the variants without class duplication. PlayerOverflowMenu.tsx is the portaled Ellipsis-button menu that hosts EQ / mini-player buttons + a PlayerVolume instance. useFloatingPlayerBar owns the docked/floating layout computation (ResizeObserver on sidebar + queue panel). useUtilityOverflowMenu owns the overflow detection, menu open/mode state, close-on-outside-click / Escape, position recompute on resize/scroll, and the wheel-menu timer. PlayerBar.tsx: 582 → 354 LOC.
This commit is contained in:
committed by
GitHub
parent
383bbbd75f
commit
988806e6b1
@@ -0,0 +1,35 @@
|
||||
import { memo, useEffect, useRef } from 'react';
|
||||
import { getPlaybackProgressSnapshot, subscribePlaybackProgress } from '../../store/playbackProgress';
|
||||
import { formatTime } from '../../utils/playerBarHelpers';
|
||||
|
||||
/** Renders the playback clock without ever causing PlayerBar to re-render.
|
||||
* Updates the DOM directly via an imperative store subscription. */
|
||||
export const PlaybackTime = memo(function PlaybackTime({ className }: { className?: string }) {
|
||||
const spanRef = useRef<HTMLSpanElement>(null);
|
||||
useEffect(() => {
|
||||
if (spanRef.current) {
|
||||
spanRef.current.textContent = formatTime(getPlaybackProgressSnapshot().currentTime);
|
||||
}
|
||||
return subscribePlaybackProgress(state => {
|
||||
if (spanRef.current) spanRef.current.textContent = formatTime(state.currentTime);
|
||||
});
|
||||
}, []);
|
||||
return <span className={className} ref={spanRef} />;
|
||||
});
|
||||
|
||||
/** Renders the remaining time (duration - currentTime) without causing PlayerBar
|
||||
* to re-render. */
|
||||
export const RemainingTime = memo(function RemainingTime({ duration, className }: { duration: number; className?: string }) {
|
||||
const spanRef = useRef<HTMLSpanElement>(null);
|
||||
useEffect(() => {
|
||||
const updateRemaining = () => {
|
||||
if (spanRef.current) {
|
||||
const remaining = Math.max(0, duration - getPlaybackProgressSnapshot().currentTime);
|
||||
spanRef.current.textContent = `-${formatTime(remaining)}`;
|
||||
}
|
||||
};
|
||||
updateRemaining();
|
||||
return subscribePlaybackProgress(updateRemaining);
|
||||
}, [duration]);
|
||||
return <span className={className} ref={spanRef} />;
|
||||
});
|
||||
Reference in New Issue
Block a user