diff --git a/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/BrainzPlayerScreen.kt b/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/BrainzPlayerScreen.kt index 03716d8be..dc18315db 100644 --- a/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/BrainzPlayerScreen.kt +++ b/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/BrainzPlayerScreen.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.material3.ElevatedSuggestionChip import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SuggestionChipDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.collectAsState @@ -134,7 +135,7 @@ fun BrainzPlayerHomeScreen( shape = ListenBrainzTheme.shapes.chips, elevation = SuggestionChipDefaults.elevatedSuggestionChipElevation(elevation = 4.dp), label = { - androidx.compose.material3.Text( + Text( text = when (position) { 0 -> "Overview" 1 -> "Recent" @@ -301,39 +302,63 @@ fun BrainzPlayerHomeScreen( ) }, onAddToNewPlaylist = { - artist -> + artist -> }, onAddToExistingPlaylist = { - artist -> + artist -> + }, + onSongClick = { + song -> + brainzPlayerViewModel.changePlayable( + listOf(song), + PlayableType.SONG, + song.mediaID, + 0, + 0L + ) + brainzPlayerViewModel.playOrToggleSong(song, true) + } + ) + 3 -> AlbumsOverViewScreen( + albums = albums, + onPlayIconClick = { album -> + val albumSongs = albumSongsMap[album]!! + brainzPlayerViewModel.changePlayable( + albumSongs.sortedBy { it.trackNumber }, + PlayableType.ALBUM, + album.albumId, + albumSongs + .sortedBy { it.trackNumber } + .indexOf(albumSongs[0]), + 0L + ) + brainzPlayerViewModel.playOrToggleSong(albumSongs[0], true) + }, + onSongClick = { song -> + brainzPlayerViewModel.changePlayable( + listOf(song), + PlayableType.SONG, + song.mediaID, + 0, + 0L + ) + brainzPlayerViewModel.playOrToggleSong(song, true) + }, + albumSongsMap = albumSongsMap + ) + 4 -> SongsOverviewScreen( + songs = songs, + onPlayIconClick = { song , newPlayables -> + brainzPlayerViewModel.changePlayable( + newPlayables, + PlayableType.ALL_SONGS, + song.mediaID, + newPlayables.sortedBy { it.discNumber }.indexOf(song), + 0L + ) + brainzPlayerViewModel.playOrToggleSong(song,true) } ) - 3 -> AlbumsOverViewScreen(albums = albums, onPlayIconClick = { - album -> - val albumSongs = albumSongsMap[album]!! - brainzPlayerViewModel.changePlayable( - albumSongs.sortedBy { it.trackNumber }, - PlayableType.ALBUM, - album.albumId, - albumSongs - .sortedBy { it.trackNumber } - .indexOf (albumSongs[0]), - 0L - ) - brainzPlayerViewModel.playOrToggleSong(albumSongs[0],true) - - - }) - 4 -> SongsOverviewScreen(songs = songs, onPlayIconClick = { - song , newPlayables -> - brainzPlayerViewModel.changePlayable( - newPlayables, - PlayableType.ALL_SONGS, - song.mediaID, - newPlayables.sortedBy { it.discNumber }.indexOf(song), - 0L - ) - brainzPlayerViewModel.playOrToggleSong(song,true) - }) } } } \ No newline at end of file diff --git a/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/overview/AlbumsOverviewScreen.kt b/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/overview/AlbumsOverviewScreen.kt index 977a3a9e4..548763933 100644 --- a/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/overview/AlbumsOverviewScreen.kt +++ b/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/overview/AlbumsOverviewScreen.kt @@ -1,14 +1,26 @@ package org.listenbrainz.android.ui.screens.brainzplayer.overview +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandVertically +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.Font @@ -17,15 +29,22 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.listenbrainz.android.R import org.listenbrainz.android.model.Album +import org.listenbrainz.android.model.Song +import org.listenbrainz.android.model.feed.FeedListenArtist import org.listenbrainz.android.ui.components.BrainzPlayerListenCard +import org.listenbrainz.android.ui.components.ListenCardSmall import org.listenbrainz.android.ui.theme.ListenBrainzTheme @Composable fun AlbumsOverViewScreen( albums : List, - onPlayIconClick: (Album) -> Unit + albumSongsMap: Map>, + onPlayIconClick: (Album) -> Unit, + onSongClick: (Song) -> Unit ) { val albumsStarting: MutableMap> = mutableMapOf() + var expandedAlbum by remember { mutableStateOf(null) } + for (i in 0..25) { albumsStarting['A' + i] = mutableListOf() } @@ -54,14 +73,56 @@ fun AlbumsOverViewScreen( ) for (j in 1..albumsStarting[startingLetter]!!.size) { val coverArt = albumsStarting[startingLetter]!![j - 1].albumArt - BrainzPlayerListenCard(title = albumsStarting[startingLetter]!![j - 1].title, subTitle = albumsStarting[startingLetter]!![j - 1].artist, coverArtUrl = coverArt, errorAlbumArt = R.drawable.ic_erroralbumart, modifier = Modifier.padding( - start = 10.dp, - end = 10.dp, - top = 3.dp, - bottom = 3.dp - ), onPlayIconClick = { - onPlayIconClick(albumsStarting[startingLetter]!![j-1]) - }) + val album = albumsStarting[startingLetter]!![j - 1] + BrainzPlayerListenCard( + title = album.title, + subTitle = album.artist, + coverArtUrl = coverArt, + errorAlbumArt = R.drawable.ic_erroralbumart, + modifier = Modifier + .padding( + start = 10.dp, + end = 10.dp, + top = 3.dp, + bottom = 3.dp + ) + .clickable { + expandedAlbum = if (expandedAlbum == album) null else album + }, + onPlayIconClick = { + onPlayIconClick(album) + } + ) + AnimatedVisibility( + visible = expandedAlbum == album, + enter = fadeIn() + expandVertically(), + exit = fadeOut() + shrinkVertically() + ) { + val albumSongs = albumSongsMap[album]!!.sortedBy { it.trackNumber } + Row(modifier = Modifier.fillMaxWidth()) { + Spacer(modifier = Modifier.weight(0.5f)) + Column( + modifier = Modifier + .weight(3.5f) + .padding(horizontal = ListenBrainzTheme.paddings.horizontal) + ) { + albumSongs.forEach { song -> + ListenCardSmall( + modifier = Modifier + .padding(vertical = 6.dp) + .fillMaxWidth(), + trackName = song.title, + artists = listOf(FeedListenArtist(song.artist, null, "")), + coverArtUrl = song.albumArt, + errorAlbumArt = R.drawable.ic_erroralbumart, + goToArtistPage = {} + ) { + onSongClick(song) + } + } + } + } + } Spacer(modifier = Modifier.height(10.dp)) } } diff --git a/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/overview/ArtistsOverviewScreen.kt b/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/overview/ArtistsOverviewScreen.kt index 3a886e6b4..bad3d81da 100644 --- a/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/overview/ArtistsOverviewScreen.kt +++ b/app/src/main/java/org/listenbrainz/android/ui/screens/brainzplayer/overview/ArtistsOverviewScreen.kt @@ -1,8 +1,16 @@ package org.listenbrainz.android.ui.screens.brainzplayer.overview +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandVertically +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState @@ -21,8 +29,11 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.listenbrainz.android.R import org.listenbrainz.android.model.Artist +import org.listenbrainz.android.model.Song +import org.listenbrainz.android.model.feed.FeedListenArtist import org.listenbrainz.android.ui.components.BrainzPlayerDropDownMenu import org.listenbrainz.android.ui.components.BrainzPlayerListenCard +import org.listenbrainz.android.ui.components.ListenCardSmall import org.listenbrainz.android.ui.theme.ListenBrainzTheme @Composable @@ -33,11 +44,14 @@ fun ArtistsOverviewScreen( onAddToQueue : (Artist) -> Unit, onAddToExistingPlaylist : (Artist) -> Unit, onAddToNewPlaylist : (Artist) -> Unit, + onSongClick: (Song) -> Unit ) { val artistsStarting: MutableMap> = mutableMapOf() var dropdownState by remember { mutableStateOf(Pair(-1,-1)) } + var expandedArtist by remember { mutableStateOf(null) } + for (i in 0..25) { artistsStarting['A' + i] = mutableListOf() } @@ -68,15 +82,71 @@ fun ArtistsOverviewScreen( ) for (j in 1..artistsStarting[startingLetter]!!.size) { var coverArt: String? = null - val artist = artistsStarting[startingLetter]!![j-1] - if (artistsStarting[startingLetter]!![j - 1].albums.isNotEmpty()) - coverArt = artistsStarting[startingLetter]!![j - 1].albums[0].albumArt - BrainzPlayerListenCard(title = artistsStarting[startingLetter]!![j - 1].name, subTitle = when (artistsStarting[startingLetter]!![j - 1].songs.size) { - 1 -> "1 track" - else -> "${artistsStarting[startingLetter]!![j - 1].songs.size} tracks" - }, coverArtUrl = coverArt, errorAlbumArt = R.drawable.ic_artist, onPlayIconClick = { - onPlayClick(artistsStarting[startingLetter]!![j-1]) - }, modifier = Modifier.padding(start = 10.dp, end = 10.dp), dropDown = { BrainzPlayerDropDownMenu(onAddToNewPlaylist = {onAddToNewPlaylist(artist)}, onAddToExistingPlaylist = {onAddToExistingPlaylist(artist)},onAddToQueue = {onAddToQueue(artist)}, onPlayNext = {onPlayNext(artist)},expanded = dropdownState == Pair(i,j-1), onDismiss = {dropdownState = Pair(-1,-1)})}, onDropdownIconClick = {dropdownState = Pair(i,j-1)}, dropDownState = dropdownState == Pair(i,j-1)) + val artist = artistsStarting[startingLetter]!![j - 1] + if (artist.albums.isNotEmpty()) + coverArt = artist.albums[0].albumArt + Column { + BrainzPlayerListenCard( + title = artist.name, + subTitle = when (artist.songs.size) { + 1 -> "1 track" + else -> "${artist.songs.size} tracks" + }, + coverArtUrl = coverArt, + errorAlbumArt = R.drawable.ic_artist, + onPlayIconClick = { + onPlayClick(artist) + }, + modifier = Modifier + .padding(start = 10.dp, end = 10.dp) + .clickable { + expandedArtist = + if (expandedArtist == artist) null else artist + }, + dropDown = { + BrainzPlayerDropDownMenu( + onAddToNewPlaylist = { onAddToNewPlaylist(artist) }, + onAddToExistingPlaylist = { onAddToExistingPlaylist(artist) }, + onAddToQueue = { onAddToQueue(artist) }, + onPlayNext = { onPlayNext(artist) }, + expanded = dropdownState == Pair(i, j - 1), + onDismiss = { dropdownState = Pair(-1, -1) } + ) + }, + onDropdownIconClick = { dropdownState = Pair(i, j - 1) }, + dropDownState = dropdownState == Pair(i, j - 1) + ) + AnimatedVisibility( + visible = expandedArtist == artist, + enter = fadeIn() + expandVertically(), + exit = fadeOut() + shrinkVertically() + ) { + Row(modifier = Modifier.fillMaxWidth()) { + Spacer(modifier = Modifier.weight(0.5f)) + Column( + modifier = Modifier + .weight(3.5f) + .padding(horizontal = ListenBrainzTheme.paddings.horizontal) + ) { + artist.songs.forEach { song -> + ListenCardSmall( + modifier = Modifier + .padding(vertical = 6.dp) + .fillMaxWidth(), + trackName = song.title, + artists = listOf(FeedListenArtist(song.artist, null, "")), + coverArtUrl = song.albumArt, + errorAlbumArt = R.drawable.ic_erroralbumart, + goToArtistPage = {} + ) { + onSongClick(song) + } + } + } + } + } + + } Spacer(modifier = Modifier.height(10.dp)) } }