mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
refactor(utils): split componentHelpers grab-bag to owning layers
Per-file routing of the 9-file utils/componentHelpers grab-bag, each driven by
its verified consumer set:
- contextMenu{Actions,Helpers} → features/contextMenu/utils (sole consumer)
- queuePanelHelpers → features/queue/utils (sole consumer)
- nowPlayingHelpers → features/nowPlaying/utils; isRealArtistImage split out to
cover/ (consumed by cover/artistHero, a lower layer)
- appUpdaterHelpers(+test) + listReorder(+test) → lib/util (config/ + lib/hooks
consume them; pure)
- playlistDetailHelpers → lib/format (consumed by 3 features; pure)
- appShellHelpers → app/ (app-shell consumers only)
- userMgmtHelpers left in place: consumed by the a11y-HELD SongInfoModal, so a
move would rewrite a do-not-touch file (same block as licensesData).
Pure moves; tests pass unmodified.
This commit is contained in:
@@ -7,7 +7,7 @@ import type { PlaybackSourceKind } from '@/features/playback/utils/playback/reso
|
||||
import {
|
||||
formatQueueReplayGainParts,
|
||||
renderStars,
|
||||
} from '@/utils/componentHelpers/queuePanelHelpers';
|
||||
} from '@/features/queue/utils/queuePanelHelpers';
|
||||
import { loudnessGainPlaceholderUntilCacheDb } from '@/features/playback/utils/audio/loudnessPlaceholder';
|
||||
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||
import { formatQueueBpmTech, formatQueueMoodLabels } from '@/lib/library/trackEnrichment';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import type { QueueItemRef } from '@/lib/media/trackTypes';
|
||||
import type { QueueDisplayMode } from '@/store/authStoreTypes';
|
||||
import type { DurationMode } from '@/utils/componentHelpers/queuePanelHelpers';
|
||||
import type { DurationMode } from '@/features/queue/utils/queuePanelHelpers';
|
||||
import { formatLongDuration } from '@/lib/format/formatDuration';
|
||||
import { formatClockTime } from '@/lib/format/formatClockTime';
|
||||
import { resolveQueueTrack } from '@/features/playback/store/queueTrackView';
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Star } from 'lucide-react';
|
||||
import type { TFunction } from 'i18next';
|
||||
import type { Track } from '@/lib/media/trackTypes';
|
||||
|
||||
export type { DurationMode } from '@/store/authStoreTypes';
|
||||
|
||||
export function formatQueueReplayGainParts(track: Track, t: TFunction): string[] {
|
||||
const parts: string[] = [];
|
||||
const fmtDb = (db: number) => `${db >= 0 ? '+' : ''}${db.toFixed(1)}`;
|
||||
if (track.replayGainTrackDb != null) {
|
||||
parts.push(t('queue.rgTrack', { db: fmtDb(track.replayGainTrackDb) }));
|
||||
}
|
||||
if (track.replayGainAlbumDb != null) {
|
||||
parts.push(t('queue.rgAlbum', { db: fmtDb(track.replayGainAlbumDb) }));
|
||||
}
|
||||
if (track.replayGainPeak != null) {
|
||||
parts.push(t('queue.rgPeak', { pk: track.replayGainPeak.toFixed(3) }));
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
export function renderStars(rating?: number) {
|
||||
if (!rating) return null;
|
||||
const stars = [];
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
stars.push(
|
||||
<Star
|
||||
key={i}
|
||||
size={12}
|
||||
fill={i <= rating ? 'var(--highlight)' : 'none'}
|
||||
color={i <= rating ? 'var(--highlight)' : 'var(--text-muted)'}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <div style={{ display: 'flex', gap: '2px', alignItems: 'center' }}>{stars}</div>;
|
||||
}
|
||||
Reference in New Issue
Block a user