mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
5231169a71
The mm:ss track-time formatter was hand-rolled in 11 places and the h:mm:ss total-duration formatter in 4 — extract two tested functions: - formatTrackTime(seconds, fallback='0:00') — m:ss, used for track / playback times. fallback param covers the '–' placeholder rows. - formatLongDuration(seconds) — h:mm:ss when >=1h, else m:ss, used for album / queue totals. Behaviour preserved per call site: the unified guard (!seconds || !isFinite || <0 -> fallback) produces identical output to every prior variant for all real inputs; SongRow keeps its '–' via the fallback arg. Removes the formatter exports from 6 componentHelpers files (playerBarHelpers / fullscreenPlayerHelpers deleted — they only exported the formatter) and 7 inline component copies. + formatDuration.test.ts
76 lines
2.9 KiB
TypeScript
76 lines
2.9 KiB
TypeScript
import { ArrowLeftRight } from 'lucide-react';
|
|
import type { TFunction } from 'i18next';
|
|
import type { RadioMetadata } from '../../hooks/useRadioMetadata';
|
|
import { useThemeStore } from '../../store/themeStore';
|
|
import { formatTrackTime } from '../../utils/format/formatDuration';
|
|
import WaveformSeek from '../WaveformSeek';
|
|
import { PlaybackTime, RemainingTime } from './PlaybackClock';
|
|
|
|
interface Props {
|
|
isRadio: boolean;
|
|
radioMeta: RadioMetadata;
|
|
trackId: string | undefined;
|
|
duration: number;
|
|
localShowRemaining: boolean;
|
|
setLocalShowRemaining: (v: boolean) => void;
|
|
disableWaveformCanvas: boolean;
|
|
t: TFunction;
|
|
}
|
|
|
|
export function PlayerSeekbarSection({
|
|
isRadio, radioMeta, trackId, duration, localShowRemaining, setLocalShowRemaining,
|
|
disableWaveformCanvas, t,
|
|
}: Props) {
|
|
return (
|
|
<div className="player-waveform-section">
|
|
{isRadio ? (
|
|
<>
|
|
{radioMeta.source === 'azuracast' && radioMeta.elapsed != null && radioMeta.duration != null && radioMeta.duration > 0 ? (
|
|
<>
|
|
<span className="player-time">{formatTrackTime(radioMeta.elapsed)}</span>
|
|
<div className="player-waveform-wrap">
|
|
<div className="radio-progress-bar">
|
|
<div
|
|
className="radio-progress-fill"
|
|
style={{ width: `${Math.min(100, (radioMeta.elapsed / radioMeta.duration) * 100)}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<span className="player-time">{formatTrackTime(radioMeta.duration)}</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<PlaybackTime className="player-time" />
|
|
<div className="player-waveform-wrap" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
|
<span className="radio-live-badge">{t('radio.live')}</span>
|
|
</div>
|
|
<span className="player-time" style={{ opacity: 0 }}>0:00</span>
|
|
</>
|
|
)}
|
|
</>
|
|
) : (
|
|
<>
|
|
<PlaybackTime className="player-time" />
|
|
<div className="player-waveform-wrap">
|
|
{disableWaveformCanvas
|
|
? <div className="radio-progress-bar" aria-hidden />
|
|
: <WaveformSeek trackId={trackId} />}
|
|
</div>
|
|
<span
|
|
className="player-time player-time-toggle"
|
|
onClick={() => {
|
|
const newVal = !localShowRemaining;
|
|
setLocalShowRemaining(newVal);
|
|
useThemeStore.getState().setShowRemainingTime(newVal);
|
|
}}
|
|
data-tooltip={localShowRemaining ? t('player.showDuration') : t('player.showRemainingTime')}
|
|
>
|
|
{localShowRemaining ? <RemainingTime duration={duration} /> : formatTrackTime(duration)}
|
|
<ArrowLeftRight size={10} style={{ marginLeft: 4, opacity: 0.6 }} />
|
|
</span>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|