mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
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:
committed by
GitHub
parent
0153435787
commit
4b1dd3c29f
@@ -12,6 +12,7 @@ import CachedImage, { useCachedUrl } from './CachedImage';
|
||||
import { usePlayerStore } from '../store/playerStore';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { playAlbum } from '../utils/playback/playAlbum';
|
||||
import { formatHumanHoursMinutes } from '../utils/format/formatHumanDuration';
|
||||
import AlbumRow from './AlbumRow';
|
||||
|
||||
const ANCHOR_HISTORY_KEY_PREFIX = 'psysonic_because_anchor_history:';
|
||||
@@ -72,13 +73,6 @@ function buildAnchorPool(sources: SubsonicAlbum[][], limit: number): Anchor[] {
|
||||
return out;
|
||||
}
|
||||
|
||||
function formatAlbumDuration(seconds: number, t: (key: string, opts?: Record<string, unknown>) => string): string {
|
||||
const totalMin = Math.max(0, Math.round(seconds / 60));
|
||||
const hours = Math.floor(totalMin / 60);
|
||||
const minutes = totalMin % 60;
|
||||
if (hours > 0) return t('common.durationHoursMinutes', { hours, minutes });
|
||||
return t('common.durationMinutesOnly', { minutes: totalMin });
|
||||
}
|
||||
|
||||
/** Both rotation memories are **per-server** — server A and server B keep
|
||||
* independent state, so switching servers doesn't snap the anchor cooldown
|
||||
@@ -353,7 +347,7 @@ const BecauseCard = memo(function BecauseCard({ album, anchor, disableArtwork }:
|
||||
<div className="because-card-meta">
|
||||
{album.year ? <span>{album.year}</span> : null}
|
||||
{album.songCount ? <span>{t('home.becauseYouLikeTracks', { count: album.songCount })}</span> : null}
|
||||
{album.duration ? <span>{formatAlbumDuration(album.duration, t)}</span> : null}
|
||||
{album.duration ? <span>{formatHumanHoursMinutes(album.duration)}</span> : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user