Skip to content

Commit e677b06

Browse files
committed
Show embedded album art for local songs missing a cached cover
UnifiedTrack.artworkUri now falls back to the audio file's file:// URI when the scan didn't cache a JPG (or it was evicted), so the registered AudioFileCoverFetcher extracts the embedded picture on demand for the song list — matching the fallback toLegacyTrack() already does for the player. Layer the music-note placeholder behind the cover in the local SongList row so tracks that genuinely have no art still show the icon instead of a blank.
1 parent ac24ba8 commit e677b06

2 files changed

Lines changed: 25 additions & 16 deletions

File tree

app/src/main/java/tf/monochrome/android/data/local/repository/LocalMediaRepository.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import tf.monochrome.android.domain.model.TrackLyrics
1818
import tf.monochrome.android.domain.model.UnifiedAlbum
1919
import tf.monochrome.android.domain.model.UnifiedArtist
2020
import tf.monochrome.android.domain.model.UnifiedTrack
21+
import java.io.File
2122
import javax.inject.Inject
2223
import javax.inject.Singleton
2324

@@ -113,7 +114,12 @@ class LocalMediaRepository @Inject constructor(
113114
albumArtistName = albumArtist,
114115
albumTitle = album,
115116
albumId = albumId?.let { "local_album_$it" },
116-
artworkUri = artworkCacheKey,
117+
// Fall back to the audio file's own file:// URI when the scan
118+
// didn't cache a JPG (or it was evicted). The registered
119+
// AudioFileCoverFetcher extracts the embedded picture on demand,
120+
// so song rows show the cover even on cache misses — matching
121+
// what toLegacyTrack() already does for the player.
122+
artworkUri = artworkCacheKey ?: android.net.Uri.fromFile(File(filePath)).toString(),
117123
codec = codec,
118124
sampleRate = sampleRate,
119125
bitDepth = bitDepth,

app/src/main/java/tf/monochrome/android/ui/library/LocalLibraryTab.kt

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -601,24 +601,27 @@ fun SongList(
601601
.padding(horizontal = MonoDimens.listItemPaddingH, vertical = MonoDimens.spacingSm),
602602
verticalAlignment = Alignment.CenterVertically
603603
) {
604-
if (track.artworkUri != null) {
605-
AsyncImage(
606-
model = track.artworkUri,
604+
// Music-note placeholder sits underneath the artwork: if the
605+
// cover loads (cached JPG, sidecar, or embedded art pulled on
606+
// demand by AudioFileCoverFetcher) it covers the icon; if the
607+
// file genuinely has no art the icon stays visible.
608+
Box(
609+
modifier = Modifier
610+
.size(48.dp)
611+
.clip(MonoDimens.shapeSm),
612+
contentAlignment = Alignment.Center
613+
) {
614+
Icon(
615+
Icons.Default.MusicNote,
607616
contentDescription = null,
608-
contentScale = ContentScale.Crop,
609-
modifier = Modifier
610-
.size(48.dp)
611-
.clip(MonoDimens.shapeSm)
617+
tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f)
612618
)
613-
} else {
614-
Box(
615-
modifier = Modifier.size(48.dp),
616-
contentAlignment = Alignment.Center
617-
) {
618-
Icon(
619-
Icons.Default.MusicNote,
619+
if (track.artworkUri != null) {
620+
AsyncImage(
621+
model = track.artworkUri,
620622
contentDescription = null,
621-
tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f)
623+
contentScale = ContentScale.Crop,
624+
modifier = Modifier.matchParentSize()
622625
)
623626
}
624627
}

0 commit comments

Comments
 (0)