fix(music): cover IS the player — tap actually starts playback

The previous layout stacked a non-functional static cover (with a decorative
play-button overlay) above the real VideoView, so tapping the prominent UI
element did nothing while the actual playback widget sat smaller below.

Use LoadThumbAndThenVideoView / VideoView as the primary header so the
album art is the player's own thumbnail and ExoPlayer handles the
tap-to-play / streaming. Falls back to a plain cover only when the event
has no playable URL at all (data-integrity case).
This commit is contained in:
Claude
2026-05-27 01:28:15 +00:00
parent bbb7a1282e
commit db9f4da394
@@ -137,7 +137,34 @@ fun MusicTrackHeader(
}
Column(MaterialTheme.colorScheme.replyModifier) {
MusicTrackCover(image, note, accountViewModel)
if (playableUri != null) {
if (image != null) {
LoadThumbAndThenVideoView(
videoUri = playableUri,
mimeType = mimeType,
title = title,
thumbUri = image,
authorName = note.author?.toBestDisplayName(),
roundedCorner = true,
contentScale = ContentScale.FillWidth,
nostrUriCallback = "nostr:${note.toNEvent()}",
accountViewModel = accountViewModel,
)
} else {
VideoView(
videoUri = playableUri,
mimeType = mimeType,
title = title,
authorName = note.author?.toBestDisplayName(),
roundedCorner = true,
contentScale = ContentScale.FillWidth,
nostrUriCallback = "nostr:${note.toNEvent()}",
accountViewModel = accountViewModel,
)
}
} else {
MusicTrackCover(image, note, accountViewModel)
}
Column(
modifier =
@@ -195,36 +222,6 @@ fun MusicTrackHeader(
}
}
if (playableUri != null) {
Spacer(Modifier.padding(top = 4.dp))
Box(Modifier.fillMaxWidth().clip(RoundedCornerShape(10.dp))) {
if (image != null) {
LoadThumbAndThenVideoView(
videoUri = playableUri,
mimeType = mimeType,
title = title,
thumbUri = image,
authorName = note.author?.toBestDisplayName(),
roundedCorner = true,
contentScale = ContentScale.FillWidth,
nostrUriCallback = "nostr:${note.toNEvent()}",
accountViewModel = accountViewModel,
)
} else {
VideoView(
videoUri = playableUri,
mimeType = mimeType,
title = title,
authorName = note.author?.toBestDisplayName(),
roundedCorner = true,
contentScale = ContentScale.FillWidth,
nostrUriCallback = "nostr:${note.toNEvent()}",
accountViewModel = accountViewModel,
)
}
}
}
description?.takeIf { !makeItShort }?.let {
Spacer(Modifier.padding(top = 4.dp))
val tags = remember(noteEvent) { noteEvent.tags.toImmutableListOfLists() }
@@ -291,24 +288,6 @@ private fun MusicTrackCover(
} else {
DefaultImageHeader(note, accountViewModel, imageModifier)
}
Box(
modifier =
Modifier
.align(Alignment.BottomEnd)
.padding(12.dp)
.size(56.dp)
.clip(CircleShape)
.background(MaterialTheme.colorScheme.primary.copy(alpha = 0.92f)),
contentAlignment = Alignment.Center,
) {
Icon(
symbol = MaterialSymbols.PlayArrow,
contentDescription = null,
tint = MaterialTheme.colorScheme.onPrimary,
modifier = Modifier.size(32.dp),
)
}
}
}