Create PrimaryButton composable

This commit is contained in:
vfsfitvnm 2022-09-28 16:49:41 +02:00
parent c03a3bcc03
commit 42a4d5b43e
7 changed files with 102 additions and 345 deletions

View file

@ -0,0 +1,50 @@
package it.vfsfitvnm.vimusic.ui.components.themed
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@Composable
fun BoxScope.PrimaryButton(
onClick: () -> Unit,
@DrawableRes iconId: Int,
modifier: Modifier = Modifier,
isEnabled: Boolean = true,
) {
val (colorPalette) = LocalAppearance.current
Box(
modifier = modifier
.align(Alignment.BottomEnd)
.padding(all = 16.dp)
.padding(LocalPlayerAwarePaddingValues.current)
.clip(RoundedCornerShape(16.dp))
.clickable(enabled = isEnabled, onClick = onClick)
.background(colorPalette.background2)
.size(62.dp)
) {
Image(
painter = painterResource(iconId),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.align(Alignment.Center)
.size(20.dp)
)
}
}

View file

@ -1,6 +1,7 @@
package it.vfsfitvnm.vimusic.ui.components.themed package it.vfsfitvnm.vimusic.ui.components.themed
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.annotation.DrawableRes
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedContentScope import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.AnimatedVisibilityScope
@ -13,6 +14,7 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@ -85,25 +87,10 @@ fun Scaffold(
} }
primaryIconButtonId?.let { primaryIconButtonId?.let {
Box( PrimaryButton(
modifier = Modifier iconId = primaryIconButtonId,
.align(Alignment.BottomEnd) onClick = onPrimaryIconButtonClick
.padding(all = 16.dp) )
.padding(LocalPlayerAwarePaddingValues.current)
.clip(RoundedCornerShape(16.dp))
.clickable(onClick = onPrimaryIconButtonClick)
.background(colorPalette.background2)
.size(62.dp)
) {
Image(
painter = painterResource(primaryIconButtonId),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.align(Alignment.Center)
.size(20.dp)
)
}
} }
} }
} }

View file

@ -48,6 +48,7 @@ import it.vfsfitvnm.vimusic.savers.DetailedSongListSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.PrimaryButton
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.Dimensions import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ -266,32 +267,16 @@ fun AlbumOverview(
} }
} }
Box( PrimaryButton(
modifier = Modifier iconId = R.drawable.shuffle,
.align(Alignment.BottomEnd) isEnabled = songs.isNotEmpty(),
.padding(all = 16.dp) onClick = {
.padding(LocalPlayerAwarePaddingValues.current) binder?.stopRadio()
.clip(RoundedCornerShape(16.dp)) binder?.player?.forcePlayFromBeginning(
.clickable(enabled = songs.isNotEmpty()) { songs.shuffled().map(DetailedSong::asMediaItem)
binder?.stopRadio() )
binder?.player?.forcePlayFromBeginning( }
songs )
.shuffled()
.map(DetailedSong::asMediaItem)
)
}
.background(colorPalette.background2)
.size(62.dp)
) {
Image(
painter = painterResource(R.drawable.shuffle),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.align(Alignment.Center)
.size(20.dp)
)
}
} ?: albumResult?.exceptionOrNull()?.let { } ?: albumResult?.exceptionOrNull()?.let {
Box( Box(
modifier = Modifier modifier = Modifier

View file

@ -73,226 +73,4 @@ fun ArtistOverview(
val (colorPalette, typography, thumbnailShape) = LocalAppearance.current val (colorPalette, typography, thumbnailShape) = LocalAppearance.current
val binder = LocalPlayerServiceBinder.current val binder = LocalPlayerServiceBinder.current
val context = LocalContext.current val context = LocalContext.current
// BoxWithConstraints {
// val thumbnailSizeDp = maxWidth - Dimensions.verticalBarWidth
// val thumbnailSizePx = (thumbnailSizeDp - 32.dp).px
//
// viewModel.result?.getOrNull()?.let { albumWithSongs ->
// LazyColumn(
// contentPadding = LocalPlayerAwarePaddingValues.current,
// modifier = Modifier
// .background(colorPalette.background0)
// .fillMaxSize()
// ) {
// item(
// key = "header",
// contentType = 0
// ) {
// Column {
// Header(title = albumWithSongs.album.title ?: "Unknown") {
// if (albumWithSongs.songs.isNotEmpty()) {
// BasicText(
// text = "Enqueue",
// style = typography.xxs.medium,
// modifier = Modifier
// .clip(RoundedCornerShape(16.dp))
// .clickable {
// binder?.player?.enqueue(
// albumWithSongs.songs.map(DetailedSong::asMediaItem)
// )
// }
// .background(colorPalette.background2)
// .padding(all = 8.dp)
// .padding(horizontal = 8.dp)
// )
// }
//
// Spacer(
// modifier = Modifier
// .weight(1f)
// )
//
// Image(
// painter = painterResource(
// if (albumWithSongs.album.bookmarkedAt == null) {
// R.drawable.bookmark_outline
// } else {
// R.drawable.bookmark
// }
// ),
// contentDescription = null,
// colorFilter = ColorFilter.tint(colorPalette.accent),
// modifier = Modifier
// .clickable {
// query {
// Database.update(
// albumWithSongs.album.copy(
// bookmarkedAt = if (albumWithSongs.album.bookmarkedAt == null) {
// System.currentTimeMillis()
// } else {
// null
// }
// )
// )
// }
// }
// .padding(all = 4.dp)
// .size(18.dp)
// )
//
// Image(
// painter = painterResource(R.drawable.share_social),
// contentDescription = null,
// colorFilter = ColorFilter.tint(colorPalette.text),
// modifier = Modifier
// .clickable {
// albumWithSongs.album.shareUrl?.let { url ->
// val sendIntent = Intent().apply {
// action = Intent.ACTION_SEND
// type = "text/plain"
// putExtra(Intent.EXTRA_TEXT, url)
// }
//
// context.startActivity(
// Intent.createChooser(
// sendIntent,
// null
// )
// )
// }
// }
// .padding(all = 4.dp)
// .size(18.dp)
// )
// }
//
// AsyncImage(
// model = albumWithSongs.album.thumbnailUrl?.thumbnail(thumbnailSizePx),
// contentDescription = null,
// modifier = Modifier
// .align(Alignment.CenterHorizontally)
// .padding(all = 16.dp)
// .clip(thumbnailShape)
// .size(thumbnailSizeDp)
// )
// }
// }
//
// itemsIndexed(
// items = albumWithSongs.songs,
// key = { _, song -> song.id }
// ) { index, song ->
// SongItem(
// title = song.title,
// authors = song.artistsText ?: albumWithSongs.album.authorsText,
// durationText = song.durationText,
// onClick = {
// binder?.stopRadio()
// binder?.player?.forcePlayAtIndex(
// albumWithSongs.songs.map(DetailedSong::asMediaItem),
// index
// )
// },
// startContent = {
// BasicText(
// text = "${index + 1}",
// style = typography.s.semiBold.center.color(colorPalette.textDisabled),
// maxLines = 1,
// overflow = TextOverflow.Ellipsis,
// modifier = Modifier
// .width(Dimensions.thumbnails.song)
// )
// },
// menuContent = {
// NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)
// }
// )
// }
// }
//
// Box(
// modifier = Modifier
// .align(Alignment.BottomEnd)
// .padding(all = 16.dp)
// .padding(LocalPlayerAwarePaddingValues.current)
// .clip(RoundedCornerShape(16.dp))
// .clickable(enabled = albumWithSongs.songs.isNotEmpty()) {
// binder?.stopRadio()
// binder?.player?.forcePlayFromBeginning(
// albumWithSongs.songs
// .shuffled()
// .map(DetailedSong::asMediaItem)
// )
// }
// .background(colorPalette.background2)
// .size(62.dp)
// ) {
// Image(
// painter = painterResource(R.drawable.shuffle),
// contentDescription = null,
// colorFilter = ColorFilter.tint(colorPalette.text),
// modifier = Modifier
// .align(Alignment.Center)
// .size(20.dp)
// )
// }
// } ?: viewModel.result?.exceptionOrNull()?.let {
// Box(
// modifier = Modifier
// .pointerInput(Unit) {
// detectTapGestures {
// viewModel.fetch(browseId)
// }
// }
// .align(Alignment.Center)
// .fillMaxSize()
// ) {
// BasicText(
// text = "An error has occurred.\nTap to retry",
// style = typography.s.medium.secondary.center,
// modifier = Modifier
// .align(Alignment.Center)
// )
// }
// } ?: Column(
// modifier = Modifier
// .padding(LocalPlayerAwarePaddingValues.current)
// .shimmer()
// ) {
// HeaderPlaceholder()
//
// Spacer(
// modifier = Modifier
// .align(Alignment.CenterHorizontally)
// .padding(all = 16.dp)
// .clip(thumbnailShape)
// .size(thumbnailSizeDp)
// .background(colorPalette.shimmer)
// )
//
// repeat(3) { index ->
// Row(
// verticalAlignment = Alignment.CenterVertically,
// horizontalArrangement = Arrangement.spacedBy(12.dp),
// modifier = Modifier
// .alpha(1f - index * 0.25f)
// .fillMaxWidth()
// .padding(horizontal = 16.dp, vertical = Dimensions.itemsVerticalPadding)
// .height(Dimensions.thumbnails.song)
// ) {
// Spacer(
// modifier = Modifier
// .background(color = colorPalette.shimmer, shape = thumbnailShape)
// .size(Dimensions.thumbnails.song)
// )
//
// Column {
// TextPlaceholder()
// TextPlaceholder()
// }
// }
// }
// }
// }
} }

View file

@ -1,25 +1,20 @@
package it.vfsfitvnm.vimusic.ui.screens.builtinplaylist package it.vfsfitvnm.vimusic.ui.screens.builtinplaylist
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
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.text.BasicText import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.Database import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
@ -31,6 +26,7 @@ import it.vfsfitvnm.vimusic.savers.DetailedSongListSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.InFavoritesMediaItemMenu import it.vfsfitvnm.vimusic.ui.components.themed.InFavoritesMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.InHistoryMediaItemMenu import it.vfsfitvnm.vimusic.ui.components.themed.InHistoryMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.PrimaryButton
import it.vfsfitvnm.vimusic.ui.styling.Dimensions import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
@ -136,27 +132,15 @@ fun BuiltInPlaylistSongList(builtInPlaylist: BuiltInPlaylist) {
} }
} }
Box( PrimaryButton(
modifier = Modifier iconId = R.drawable.shuffle,
.align(Alignment.BottomEnd) isEnabled = songs.isNotEmpty(),
.padding(all = 16.dp) onClick = {
.padding(LocalPlayerAwarePaddingValues.current) binder?.stopRadio()
.clip(RoundedCornerShape(16.dp)) binder?.player?.forcePlayFromBeginning(
.clickable(enabled = songs.isNotEmpty()) { songs.shuffled().map(DetailedSong::asMediaItem)
binder?.stopRadio() )
binder?.player?.forcePlayFromBeginning(songs.shuffled().map(DetailedSong::asMediaItem)) }
} )
.background(colorPalette.background2)
.size(62.dp)
) {
Image(
painter = painterResource(R.drawable.shuffle),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.align(Alignment.Center)
.size(20.dp)
)
}
} }
} }

View file

@ -19,7 +19,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
@ -42,6 +41,7 @@ import it.vfsfitvnm.vimusic.transaction
import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog
import it.vfsfitvnm.vimusic.ui.components.themed.Header import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.InPlaylistMediaItemMenu import it.vfsfitvnm.vimusic.ui.components.themed.InPlaylistMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.PrimaryButton
import it.vfsfitvnm.vimusic.ui.components.themed.TextFieldDialog import it.vfsfitvnm.vimusic.ui.components.themed.TextFieldDialog
import it.vfsfitvnm.vimusic.ui.styling.Dimensions import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ -267,32 +267,18 @@ fun LocalPlaylistSongList(
} }
} }
Box( PrimaryButton(
modifier = Modifier iconId = R.drawable.shuffle,
.align(Alignment.BottomEnd) isEnabled = playlistWithSongs?.songs?.isNotEmpty() == true,
.padding(all = 16.dp) onClick = {
.padding(LocalPlayerAwarePaddingValues.current) playlistWithSongs?.songs
.clip(RoundedCornerShape(16.dp)) ?.shuffled()
.clickable(enabled = playlistWithSongs?.songs?.isNotEmpty() == true) { ?.map(DetailedSong::asMediaItem)
playlistWithSongs?.songs ?.let { mediaItems ->
?.shuffled() binder?.stopRadio()
?.map(DetailedSong::asMediaItem) binder?.player?.forcePlayFromBeginning(mediaItems)
?.let { mediaItems -> }
binder?.stopRadio() }
binder?.player?.forcePlayFromBeginning(mediaItems) )
}
}
.background(colorPalette.background2)
.size(62.dp)
) {
Image(
painter = painterResource(R.drawable.shuffle),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.align(Alignment.Center)
.size(20.dp)
)
}
} }
} }

View file

@ -46,6 +46,7 @@ import it.vfsfitvnm.vimusic.transaction
import it.vfsfitvnm.vimusic.ui.components.themed.Header import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.PrimaryButton
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.Dimensions import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ -234,30 +235,16 @@ fun PlaylistSongList(
} }
} }
Box( PrimaryButton(
modifier = Modifier iconId = R.drawable.shuffle,
.align(Alignment.BottomEnd) isEnabled = playlist.songs?.isNotEmpty() == true,
.padding(all = 16.dp) onClick = {
.padding(LocalPlayerAwarePaddingValues.current) playlist.songs?.map(YouTube.Item.Song::asMediaItem)?.let { mediaItems ->
.clip(RoundedCornerShape(16.dp)) binder?.stopRadio()
.clickable(enabled = playlist.songs?.isNotEmpty() == true) { binder?.player?.forcePlayFromBeginning(mediaItems.shuffled())
playlist.songs?.map(YouTube.Item.Song::asMediaItem)?.let { mediaItems ->
binder?.stopRadio()
binder?.player?.forcePlayFromBeginning(mediaItems.shuffled())
}
} }
.background(colorPalette.background2) }
.size(62.dp) )
) {
Image(
painter = painterResource(R.drawable.shuffle),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.align(Alignment.Center)
.size(20.dp)
)
}
} ?: playlistResult?.exceptionOrNull()?.let { } ?: playlistResult?.exceptionOrNull()?.let {
Box( Box(
modifier = Modifier modifier = Modifier