refactor(dedup): consolidate byte / sanitize / clock / album-duration helpers (Phase L, part 2) (#692)

Findings 5-8 of the dedup audit:

- F5 byte formatters: appUpdaterHelpers.fmtBytes + ZipDownloadOverlay
  .formatMB route through the existing formatBytes; a new formatMb
  (always-MB) backs playlistDetailHelpers.formatSize, AlbumHeader and
  the 4 inline DeviceSyncPreSyncModal expressions. SongInfoModal.format
  Size is intentionally left — it uses decimal (1e6) divisors, not 1024.
- F6 sanitizeHtml: extracted to utils/sanitizeHtml.ts; AlbumHeader,
  ComposerDetail and the (now-empty, deleted) artistDetailHelpers use it
  directly. nowPlayingHelpers keeps its own export but now delegates to
  the shared sanitiser and only adds its trailing-link strip on top.
- F7 album duration: BecauseYouLikeRail's formatAlbumDuration drops in
  favour of the shared formatHumanHoursMinutes. Behaviour note: total
  minutes now floor instead of round (<=1 min display difference,
  matches every other caller).
- F8 clock time: extracted to utils/format/formatClockTime.ts;
  PlaybackDelayModal + QueueHeader use it (toLocaleTimeString and
  Intl.DateTimeFormat produced identical output).

Behaviour preserved except the two explicitly noted divergences (F7
round->floor; F5 appUpdater/Zip now show GB above 1 GB instead of a
large MB number).
This commit is contained in:
Frank Stellmacher
2026-05-14 15:19:42 +02:00
committed by GitHub
parent 0153435787
commit 4b1dd3c29f
15 changed files with 50 additions and 105 deletions
+2 -6
View File
@@ -5,6 +5,7 @@ import { usePlayerStore } from '../../store/playerStore';
import type { Track } from '../../store/playerStoreTypes';
import type { DurationMode } from '../../utils/componentHelpers/queuePanelHelpers';
import { formatLongDuration } from '../../utils/format/formatDuration';
import { formatClockTime } from '../../utils/format/formatClockTime';
interface Props {
queue: Track[];
@@ -35,16 +36,11 @@ export function QueueHeader({
const remainingSecs = Math.max(0, (queue[queueIndex]?.duration ?? 0) - currentTime + futureTracksDuration);
const fmtEta = (secs: number) => {
const finishTime = new Date(Date.now() + secs * 1000);
return new Intl.DateTimeFormat(undefined, { hour: '2-digit', minute: '2-digit' }).format(finishTime);
};
let dur: string | null = null;
if (queue.length > 0) {
if (durationMode === 'total') dur = formatLongDuration(Math.floor(totalSecs));
else if (durationMode === 'remaining') dur = `-${formatLongDuration(Math.floor(remainingSecs))}`;
else dur = fmtEta(remainingSecs);
else dur = formatClockTime(Date.now() + remainingSecs * 1000);
}
const nextMode: DurationMode =