Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MOBILE-212: Highlight current playing song & dynamic PlayButton #518

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package org.listenbrainz.android.ui.components

import androidx.annotation.DrawableRes
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -15,20 +20,27 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil.compose.AsyncImage
import coil.request.ImageRequest
import org.listenbrainz.android.R
import org.listenbrainz.android.model.feed.FeedListenArtist
import org.listenbrainz.android.ui.theme.ListenBrainzTheme
import org.listenbrainz.android.util.BrainzPlayerExtensions.toSong
import org.listenbrainz.android.viewmodel.BrainzPlayerViewModel

@Composable
fun BrainzPlayerListenCard(
Expand All @@ -40,8 +52,18 @@ fun BrainzPlayerListenCard(
onDropdownIconClick: () -> Unit = {},
dropDown: @Composable () -> Unit = {},
dropDownState: Boolean = false,
onPlayIconClick: () -> Unit
onPlayIconClick: () -> Unit,
mediaId: Long? = null,
viewModel: BrainzPlayerViewModel = hiltViewModel()
) {
val isPlaying by viewModel.isPlaying.collectAsState()
val currentlyPlayingSong = viewModel.currentlyPlayingSong.collectAsStateWithLifecycle().value.toSong
val titleColor = if (currentlyPlayingSong.mediaID == mediaId) {
Color(0xFFB94FE5)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use ListenBrainzTheme.colorScheme.signatureInverse maybe or is it not legible enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I’m not wrong, lbSignatureInverse uses lb_orange, but Aerozol asked for a combination of blue and violet. Please suggest any combination or shade you’d like.

} else {
ListenBrainzTheme.colorScheme.listenText
}

Surface(
modifier = modifier
.fillMaxWidth(),
Expand Down Expand Up @@ -72,16 +94,19 @@ fun BrainzPlayerListenCard(
title = title,
goToArtistPage = {},
artists = listOf(FeedListenArtist(subTitle, null, "")),
titleColor = titleColor
)
}
Box(modifier = Modifier
.fillMaxWidth(0.275f)
.align(Alignment.CenterEnd)){
DropdownButton (modifier = Modifier.align(Alignment.Center), onDropdownIconClick = onDropdownIconClick)
if(dropDownState) dropDown()
PlayButton (modifier = Modifier.align(Alignment.CenterEnd)) {
onPlayIconClick()
}
PlayButton(
modifier = Modifier.align(Alignment.CenterEnd),
isPlaying = currentlyPlayingSong.mediaID == mediaId && isPlaying,
onPlayIconClick = onPlayIconClick
)
}


Expand Down Expand Up @@ -110,18 +135,24 @@ private fun DropdownButton(modifier: Modifier = Modifier, onDropdownIconClick: (
}

@Composable
private fun PlayButton(modifier: Modifier = Modifier, onPlayIconClick: () -> Unit) {

private fun PlayButton(modifier: Modifier = Modifier, onPlayIconClick: () -> Unit, isPlaying: Boolean) {
IconButton(
modifier = modifier,
onClick = onPlayIconClick
) {
Icon(
painter = painterResource(id = R.drawable.brainz_player_play_button),
contentDescription = "",
tint = ListenBrainzTheme.colorScheme.hint,
modifier = Modifier.padding(horizontal = ListenBrainzTheme.paddings.insideCard)
)
AnimatedContent(
targetState = isPlaying,
transitionSpec = {
fadeIn(animationSpec = tween(200)) togetherWith fadeOut(animationSpec = tween(300))
}
) { targetState ->
Icon(
painter = painterResource(id = if (targetState) R.drawable.ic_pause else R.drawable.brainz_player_play_button),
contentDescription = "",
tint = ListenBrainzTheme.colorScheme.hint,
modifier = Modifier.padding(horizontal = ListenBrainzTheme.paddings.insideCard)
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,21 @@ 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])
})
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])
}
)
Spacer(modifier = Modifier.height(10.dp))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,30 @@ fun ArtistsOverviewScreen(
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))
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)
)
Spacer(modifier = Modifier.height(10.dp))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,26 @@ private fun PlayedToday(
)) {
itemsIndexed(songsPlayedToday){
index, it ->
BrainzPlayerListenCard(title = it.title, subTitle = it.artist, coverArtUrl = it.albumArt, errorAlbumArt = R.drawable.ic_erroralbumart, onPlayIconClick = {onPlayIconClick(it)}, onDropdownIconClick = {dropDownState.value = Pair(1,index)}, dropDownState = dropDownState.value == Pair(1,index),dropDown = {BrainzPlayerDropDownMenu(
expanded = dropDownState.value == Pair(1,index),
onDismiss = {dropDownState.value = Pair(-1,-1)},
onAddToQueue = {onAddToQueue(it)},
onPlayNext = {onPlayNext(it)},
onAddToExistingPlaylist = {onAddToExistingPlaylist(it)},
onAddToNewPlaylist = {onAddToNewPlaylist(it)}
)})
BrainzPlayerListenCard(
title = it.title,
subTitle = it.artist,
coverArtUrl = it.albumArt,
errorAlbumArt = R.drawable.ic_erroralbumart,
onPlayIconClick = { onPlayIconClick(it) },
onDropdownIconClick = {dropDownState.value = Pair(1,index)},
dropDownState = dropDownState.value == Pair(1,index),
dropDown = {
BrainzPlayerDropDownMenu(
expanded = dropDownState.value == Pair(1,index),
onDismiss = {dropDownState.value = Pair(-1,-1)},
onAddToQueue = {onAddToQueue(it)},
onPlayNext = {onPlayNext(it)},
onAddToExistingPlaylist = {onAddToExistingPlaylist(it)},
onAddToNewPlaylist = {onAddToNewPlaylist(it)}
)
},
mediaId = it.mediaID
)
Spacer(modifier = Modifier.height(5.dp))
}

Expand All @@ -118,14 +130,25 @@ private fun PlayedThisWeek(
)) {
itemsIndexed(songsPlayedThisWeek){
index, it ->
BrainzPlayerListenCard(title = it.title, subTitle = it.artist, coverArtUrl = it.albumArt, errorAlbumArt = R.drawable.ic_erroralbumart, onPlayIconClick = {onPlayIconClick(it)}, onDropdownIconClick = {dropDownState.value = Pair(2,index)}, dropDownState = dropDownState.value == Pair(2,index),dropDown = {BrainzPlayerDropDownMenu(
expanded = dropDownState.value == Pair(2,index),
onDismiss = {dropDownState.value = Pair(-1,-1)},
onAddToQueue = {onAddToQueue(it)},
onPlayNext = {onPlayNext(it)},
onAddToExistingPlaylist = {onAddToExistingPlaylist(it)},
onAddToNewPlaylist = {onAddToNewPlaylist(it)}
)})
BrainzPlayerListenCard(
title = it.title,
subTitle = it.artist,
coverArtUrl = it.albumArt,
errorAlbumArt = R.drawable.ic_erroralbumart,
onPlayIconClick = { onPlayIconClick(it) },
onDropdownIconClick = { dropDownState.value = Pair(2,index) },
dropDownState = dropDownState.value == Pair(2,index),
dropDown = {
BrainzPlayerDropDownMenu(
expanded = dropDownState.value == Pair(2,index),
onDismiss = {dropDownState.value = Pair(-1,-1)},
onAddToQueue = {onAddToQueue(it)},
onPlayNext = {onPlayNext(it)},
onAddToExistingPlaylist = {onAddToExistingPlaylist(it)},
onAddToNewPlaylist = {onAddToNewPlaylist(it)}
)
}
)
Spacer(modifier = Modifier.height(5.dp))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,15 @@ fun SongsOverviewScreen(
val song: Song = songsStarting[startingLetter]!![j-1]
var coverArt: String? = null
coverArt = songsStarting[startingLetter]!![j - 1].albumArt
BrainzPlayerListenCard(modifier = Modifier.padding(start= 10.dp, end = 10.dp),title = songsStarting[startingLetter]!![j - 1].title, subTitle = songsStarting[startingLetter]!![j - 1].artist, coverArtUrl = coverArt, errorAlbumArt = R.drawable.ic_erroralbumart){
onPlayIconClick(song,songsStarting[startingLetter]!!)
}
BrainzPlayerListenCard(
modifier = Modifier.padding(start = 10.dp, end = 10.dp),
title = songsStarting[startingLetter]!![j - 1].title,
subTitle = songsStarting[startingLetter]!![j - 1].artist,
coverArtUrl = coverArt,
errorAlbumArt = R.drawable.ic_erroralbumart,
onPlayIconClick = { onPlayIconClick(song, songsStarting[startingLetter]!!) },
mediaId = song.mediaID
)
Spacer(modifier = Modifier.height(10.dp))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package org.listenbrainz.android.viewmodel

import android.os.Build
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.session.PlaybackStateCompat.REPEAT_MODE_ALL
import android.support.v4.media.session.PlaybackStateCompat.REPEAT_MODE_NONE
import android.support.v4.media.session.PlaybackStateCompat.REPEAT_MODE_ONE
import android.support.v4.media.session.PlaybackStateCompat.SHUFFLE_MODE_ALL
import android.support.v4.media.session.PlaybackStateCompat.SHUFFLE_MODE_NONE
import androidx.annotation.RequiresApi
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -38,8 +34,6 @@ import org.listenbrainz.android.util.BrainzPlayerExtensions.isPrepared
import org.listenbrainz.android.util.BrainzPlayerExtensions.toSong
import org.listenbrainz.android.util.BrainzPlayerUtils.MEDIA_ROOT_ID
import org.listenbrainz.android.util.Resource
import org.listenbrainz.android.util.Transformer.toSongEntity
import java.time.Instant
import javax.inject.Inject

@HiltViewModel
Expand Down Expand Up @@ -82,7 +76,6 @@ class BrainzPlayerViewModel @Inject constructor(
it.toSong
}
_mediaItems.value = Resource(Resource.Status.SUCCESS, songs)

}
})
viewModelScope.launch(Dispatchers.IO) {
Expand Down
Loading