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:
1 parent
3000dc1622
commit
3ceba8a365
4 files changed
+53
No files matched your search
@@ -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) } },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user