feat(android): partial-album detail gets Play/Shuffle + track 3-dot menu

You can still enjoy an incomplete album: the downloaded-tracks section now has
Abspielen + Zufall buttons (play/shuffle the downloaded songs) and each
downloaded row gets the 3-dot context menu, threaded from both artist screens.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-09-01 23:58:24 +02:00
1 parent 3000dc1622
commit 3ceba8a365
4 files changed
+53

No files matched your search

+2
View File
@@ -571,6 +571,8 @@ Polish release: Android navigation and offline resilience, download accuracy for
- **Android** — Romaji / Japanese sort support - **Android** — Romaji / Japanese sort support
- **Web + Android** — Backend settings UI rework (move, reorganize) - **Web + Android** — Backend settings UI rework (move, reorganize)
- **Web + Android** — yt-dlp backend update / maintenance - **Web + Android** — yt-dlp backend update / maintenance
- **Web + Andoird** - Safe last played Queue, where it stopped and show last played song loaded (rn only on web kinda with the last song played loaded)
- **Android** - Andorid Auto Sync last played and queue too with Phone then, rn its not really syncing or safin what last played on Android Auto, also check if selecting a song to play on Android Auto works that song is getting played and in a playlist it will play the queue a this point then like it works already in Android and Web
### Known Bugs ### Known Bugs
- **Android (lyrics)** — Synced-lyrics auto-scroll is **not smooth**: it follows playback and highlights the right line, but the list jumps to it rather than gliding. Web autoscroll is smooth. Not yet fixed. - **Android (lyrics)** — Synced-lyrics auto-scroll is **not smooth**: it follows playback and highlights the right line, but the list jumps to it rather than gliding. Web autoscroll is smooth. Not yet fixed.
@@ -156,6 +156,7 @@ fun ArtistDetailScreen(
onPreview = vm::togglePreview, onPreview = vm::togglePreview,
onDownload = vm::showDownloadSheet, onDownload = vm::showDownloadSheet,
onBack = vm::dismissPartialAlbum, onBack = vm::dismissPartialAlbum,
onShowContextMenu = onShowContextMenu,
) )
return return
} }
@@ -115,6 +115,7 @@ fun ExploreScreen(
onPreview = vm::togglePreview, onPreview = vm::togglePreview,
onDownload = vm::showDownloadSheet, onDownload = vm::showDownloadSheet,
onBack = vm::dismissPartialAlbum, onBack = vm::dismissPartialAlbum,
onShowContextMenu = onShowContextMenu,
) )
} }
albumTracks != null && albumItem != null -> { albumTracks != null && albumItem != null -> {
@@ -5,9 +5,12 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.clickable
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Shuffle
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@@ -41,6 +44,7 @@ fun PartialAlbumScreen(
onPreview: (ItunesItem) -> Unit, onPreview: (ItunesItem) -> Unit,
onDownload: (ItunesItem) -> Unit, onDownload: (ItunesItem) -> Unit,
onBack: () -> Unit, onBack: () -> Unit,
onShowContextMenu: ((Song) -> Unit)? = null,
) { ) {
val ia = partialAlbum.itunesAlbum val ia = partialAlbum.itunesAlbum
val nd = partialAlbum.ndAlbum val nd = partialAlbum.ndAlbum
@@ -96,6 +100,50 @@ fun PartialAlbumScreen(
.sortedBy { it.trackNumber ?: 999 } .sortedBy { it.trackNumber ?: 999 }
LazyColumn(Modifier.fillMaxSize()) { LazyColumn(Modifier.fillMaxSize()) {
// ── Play / Shuffle the downloaded tracks (you can still enjoy the album even when not
// every track is downloaded yet) ─────────────────────────────────────────────────
if (downloadedSongs.isNotEmpty()) {
item {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, top = 12.dp, bottom = 4.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.weight(1f)
.clip(RoundedCornerShape(10.dp))
.background(NsAccent)
.clickable { onPlay(downloadedSongs, 0) }
.padding(vertical = 11.dp),
) {
Icon(Icons.Default.PlayArrow, null, tint = NsBackground, modifier = Modifier.size(20.dp))
Spacer(Modifier.width(6.dp))
Text("Abspielen", fontFamily = Outfit, fontWeight = FontWeight.SemiBold,
fontSize = 14.sp, color = NsBackground)
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.weight(1f)
.clip(RoundedCornerShape(10.dp))
.background(NsSurface2)
.clickable { onPlay(downloadedSongs.shuffled(), 0) }
.padding(vertical = 11.dp),
) {
Icon(Icons.Default.Shuffle, null, tint = NsOnSurface, modifier = Modifier.size(18.dp))
Spacer(Modifier.width(6.dp))
Text("Zufall", fontFamily = Outfit, fontWeight = FontWeight.SemiBold,
fontSize = 14.sp, color = NsOnSurface)
}
}
}
}
// ── Downloaded tracks ───────────────────────────────────────────── // ── Downloaded tracks ─────────────────────────────────────────────
if (downloadedSongs.isNotEmpty()) { if (downloadedSongs.isNotEmpty()) {
item { item {
@@ -113,6 +161,7 @@ fun PartialAlbumScreen(
starred = song.starred != null, starred = song.starred != null,
onPlay = { onPlay(downloadedSongs, idx) }, onPlay = { onPlay(downloadedSongs, idx) },
onStarToggle = {}, onStarToggle = {},
onMore = onShowContextMenu?.let { cb -> { cb(song) } },
) )
} }
} }