fix improperly ported metadata logic

This commit is contained in:
Boof2015
2026-07-05 02:10:25 -04:00
parent 34ffda7190
commit 3a25966dde
29 changed files with 1349 additions and 110 deletions
+4
View File
@@ -39,6 +39,7 @@ import {
skipToPrevious,
togglePlay
} from '@/audio/playbackController';
import { compareTracksByDiscTrackTitle } from '@/library/albumIdentity';
import { dbTrackToTrack } from '@/library/trackAdapter';
import { albumArtworkSource } from '@/library/artwork';
import { formatDuration } from '@/lib/format';
@@ -407,6 +408,9 @@ export default function HomeScreen() {
list.push(track);
map.set(track.album_identity_key, list);
}
// Store tracks are artist-ordered; a multi-artist compilation would play
// blocked by artist without an explicit album-order sort.
for (const list of map.values()) list.sort(compareTracksByDiscTrackTitle);
return map;
}, [randomAlbumNeedsTracks, tracks]);
const randomTracks =
+27 -10
View File
@@ -15,8 +15,9 @@ import { colors, spacing } from '@/theme';
import { useLibraryStore } from '@/stores/libraryStore';
import { usePlayerStore } from '@/stores/playerStore';
import { playTracks, shuffleTracks } from '@/audio/playbackController';
import { compareTracksByDiscTrackTitle } from '@/library/albumIdentity';
import { dbTrackToTrack } from '@/library/trackAdapter';
import { albumArtworkSource, artworkThumbUri } from '@/library/artwork';
import { albumArtworkSource, artworkThumbUri, artworkUri } from '@/library/artwork';
import { formatDuration } from '@/lib/format';
import { useLibraryDetailBack } from '@/navigation/useLibraryDetailBack';
import type { DbTrack } from '@/types/library';
@@ -45,10 +46,13 @@ export default function AlbumScreen() {
useDetailCollapse();
const album = albums.find((entry) => entry.identity_key === key);
// Store tracks are ordered artist/album/disc/track, so the filtered slice
// keeps disc/track order within one album.
// Store tracks are artist-ordered, so a multi-artist group (Various Artists
// compilation) would come out blocked by artist — re-sort into album order.
const tracks = useMemo(
() => allTracks.filter((track) => track.album_identity_key === key),
() =>
allTracks
.filter((track) => track.album_identity_key === key)
.sort(compareTracksByDiscTrackTitle),
[allTracks, key]
);
@@ -80,12 +84,25 @@ export default function AlbumScreen() {
void playTracks(tracks.map(dbTrackToTrack), index);
};
const artSource = album ? albumArtworkSource(album) : null;
// Eligibility can filter an album out of the store list (a single reached via
// "go to album") — fall back to the filtered tracks' own metadata.
const fallbackTrack = tracks[0];
const headerArtist =
album?.artist ??
fallbackTrack?.album_display_artist ??
fallbackTrack?.album_artist ??
fallbackTrack?.artist;
const headerArtworkHash = album?.artwork_hash ?? fallbackTrack?.artwork_hash ?? null;
const artSource = album
? albumArtworkSource(album)
: headerArtworkHash
? artworkUri(headerArtworkHash)
: null;
// Blur the cached thumbnail, not the full-res cover (remote albums have no
// local thumb — their server URL is already sized reasonably).
const backdropUri = album?.artwork_hash ? artworkThumbUri(album.artwork_hash) : artSource;
const backdropUri = headerArtworkHash ? artworkThumbUri(headerArtworkHash) : artSource;
const meta = [
album?.year ? String(album.year) : null,
(album?.year ?? fallbackTrack?.year) ? String(album?.year ?? fallbackTrack?.year) : null,
`${tracks.length} ${tracks.length === 1 ? 'track' : 'tracks'}`,
formatDuration(totalDuration),
]
@@ -130,12 +147,12 @@ export default function AlbumScreen() {
)
}
backdropUri={backdropUri}
title={album?.album ?? 'Album'}
title={album?.album ?? tracks[0]?.album ?? 'Album'}
heroMeta={
<>
{album?.artist ? (
{headerArtist ? (
<Text variant="body" color={colors.textSecondary} numberOfLines={1}>
{album.artist}
{headerArtist}
</Text>
) : null}
<Text variant="label">{meta}</Text>
+9
View File
@@ -234,6 +234,8 @@ export default function SettingsScreen() {
const groupingMode = useSettingsStore((s) => s.artistGroupingMode);
const setArtistGroupingMode = useSettingsStore((s) => s.setArtistGroupingMode);
const includeSingles = useSettingsStore((s) => s.includeSingles);
const setIncludeSingles = useSettingsStore((s) => s.setIncludeSingles);
const normalizationEnabled = useAudioSettingsStore((s) => s.normalizationEnabled);
const normalizationTargetLufs = useAudioSettingsStore((s) => s.normalizationTargetLufs);
@@ -357,6 +359,13 @@ export default function SettingsScreen() {
})}
</View>
<ToggleRow
title="Show singles in Albums"
description="Include 1-track albums in the Albums view. Off matches desktop."
value={includeSingles}
onValueChange={(v) => void setIncludeSingles(v)}
/>
<Text variant="label" color={colors.textTertiary} style={[styles.sectionLabel, styles.sectionSpacing]}>
REMOTE SOURCES
</Text>
+5 -4
View File
@@ -34,7 +34,7 @@ import {
} from '@/theme';
import { WIDE_MIN_WIDTH, isWideWindow } from '@/theme/adaptive';
import { motion } from '@/theme/motion';
import { resolveCanonicalBrowseArtist, resolveStrictBrowseArtist } from '@/library/artistGrouping';
import { resolveNavigationArtist } from '@/library/artistGrouping';
import { useLibraryStore } from '@/stores/libraryStore';
import { usePlayerStore } from '@/stores/playerStore';
import { usePlaylistStore } from '@/stores/playlistStore';
@@ -288,9 +288,10 @@ export default function NowPlayingScreen() {
[libraryTracks, track]
);
const artistName = track
? artistGroupingMode === 'fileTags'
? resolveStrictBrowseArtist(libraryTrack ?? { artist: track.artist, album_artist: track.albumArtist ?? null })
: resolveCanonicalBrowseArtist(libraryTrack ?? { artist: track.artist, album_artist: track.albumArtist ?? null })
? resolveNavigationArtist(
libraryTrack ?? { artist: track.artist, album_artist: track.albumArtist ?? null },
artistGroupingMode
)
: '';
const albumKey = track?.albumIdentityKey ?? libraryTrack?.album_identity_key;