Tweak Dialog UI and components

This commit is contained in:
vfsfitvnm
2022-10-04 16:06:38 +02:00
parent 092c967637
commit 693542f6e3
4 changed files with 70 additions and 149 deletions

View File

@@ -1,99 +0,0 @@
package it.vfsfitvnm.vimusic.ui.components
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
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.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.R
@Composable
fun ChunkyButton(
onClick: () -> Unit,
backgroundColor: Color,
modifier: Modifier = Modifier,
text: String? = null,
secondaryText: String? = null,
textStyle: TextStyle = TextStyle.Default,
secondaryTextStyle: TextStyle = TextStyle.Default,
rippleColor: Color = Color.Unspecified,
@DrawableRes icon: Int? = null,
shape: Shape = RoundedCornerShape(16.dp),
colorFilter: ColorFilter = ColorFilter.tint(rippleColor),
isEnabled: Boolean = true,
onMore: (() -> Unit)? = null
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier
.clip(shape)
.background(backgroundColor)
.clickable(enabled = isEnabled, onClick = onClick)
.padding(horizontal = 24.dp, vertical = 16.dp)
) {
icon?.let { icon ->
Image(
painter = painterResource(icon),
contentDescription = null,
colorFilter = colorFilter,
modifier = Modifier
.size(20.dp)
)
}
text?.let { text ->
Column {
BasicText(
text = text,
style = textStyle
)
secondaryText?.let { secondaryText ->
BasicText(
text = secondaryText,
style = secondaryTextStyle
)
}
}
}
onMore?.let { onMore ->
Spacer(
modifier = Modifier
.background(rippleColor.copy(alpha = 0.6f))
.width(1.dp)
.height(24.dp)
)
Image(
// TODO: this is themed...
painter = painterResource(R.drawable.ellipsis_vertical),
contentDescription = null,
colorFilter = ColorFilter.tint(rippleColor.copy(alpha = 0.6f)),
modifier = Modifier
.clickable(onClick = onMore)
.size(20.dp)
)
}
}
}

View File

@@ -34,7 +34,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
@@ -49,10 +48,8 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import it.vfsfitvnm.vimusic.ui.components.ChunkyButton
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.center import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.drawCircle import it.vfsfitvnm.vimusic.utils.drawCircle
import it.vfsfitvnm.vimusic.utils.medium import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.secondary import it.vfsfitvnm.vimusic.utils.secondary
@@ -93,9 +90,7 @@ fun TextFieldDialog(
) { ) {
BasicTextField( BasicTextField(
value = textFieldValue, value = textFieldValue,
onValueChange = { onValueChange = { textFieldValue = it },
textFieldValue = it
},
textStyle = typography.xs.semiBold.center, textStyle = typography.xs.semiBold.center,
singleLine = singleLine, singleLine = singleLine,
maxLines = maxLines, maxLines = maxLines,
@@ -142,19 +137,14 @@ fun TextFieldDialog(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
) { ) {
ChunkyButton( DialogTextButton(
backgroundColor = Color.Transparent,
text = cancelText, text = cancelText,
textStyle = typography.xs.semiBold,
shape = RoundedCornerShape(36.dp),
onClick = onCancel onClick = onCancel
) )
ChunkyButton( DialogTextButton(
backgroundColor = colorPalette.accent, primary = true,
text = doneText, text = doneText,
textStyle = typography.xs.semiBold.color(colorPalette.onAccent),
shape = RoundedCornerShape(36.dp),
onClick = { onClick = {
if (isTextInputValid(textFieldValue.text)) { if (isTextInputValid(textFieldValue.text)) {
onDismiss() onDismiss()
@@ -181,7 +171,7 @@ fun ConfirmationDialog(
confirmText: String = "Confirm", confirmText: String = "Confirm",
onCancel: () -> Unit = onDismiss onCancel: () -> Unit = onDismiss
) { ) {
val (colorPalette, typography) = LocalAppearance.current val (_, typography) = LocalAppearance.current
DefaultDialog( DefaultDialog(
onDismiss = onDismiss, onDismiss = onDismiss,
@@ -189,7 +179,7 @@ fun ConfirmationDialog(
) { ) {
BasicText( BasicText(
text = text, text = text,
style = typography.xs.semiBold.center, style = typography.s.medium.center,
modifier = Modifier modifier = Modifier
.padding(all = 16.dp) .padding(all = 16.dp)
) )
@@ -199,19 +189,14 @@ fun ConfirmationDialog(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
) { ) {
ChunkyButton( DialogTextButton(
backgroundColor = Color.Transparent,
text = cancelText, text = cancelText,
textStyle = typography.xs.semiBold,
shape = RoundedCornerShape(36.dp),
onClick = onCancel onClick = onCancel
) )
ChunkyButton( DialogTextButton(
backgroundColor = colorPalette.accent,
text = confirmText, text = confirmText,
textStyle = typography.xs.semiBold.color(colorPalette.onAccent), primary = true,
shape = RoundedCornerShape(36.dp),
onClick = { onClick = {
onConfirm() onConfirm()
onDismiss() onDismiss()
@@ -265,10 +250,7 @@ inline fun <T> ValueSelectorDialog(
Column( Column(
modifier = modifier modifier = modifier
.padding(all = 48.dp) .padding(all = 48.dp)
.background( .background(color = colorPalette.background1, shape = RoundedCornerShape(8.dp))
color = colorPalette.background1,
shape = RoundedCornerShape(8.dp)
)
.padding(vertical = 16.dp), .padding(vertical = 16.dp),
) { ) {
BasicText( BasicText(
@@ -336,16 +318,17 @@ inline fun <T> ValueSelectorDialog(
} }
} }
BasicText( Box(
text = "Cancel",
style = typography.xs.semiBold,
modifier = Modifier modifier = Modifier
.padding(horizontal = 24.dp)
.clip(RoundedCornerShape(36.dp))
.clickable(onClick = onDismiss)
.padding(horizontal = 24.dp, vertical = 16.dp)
.align(Alignment.End) .align(Alignment.End)
) .padding(end = 24.dp)
) {
DialogTextButton(
text = "Cancel",
onClick = onDismiss,
modifier = Modifier
)
}
} }
} }
} }

View File

@@ -0,0 +1,42 @@
package it.vfsfitvnm.vimusic.ui.components.themed
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.medium
@Composable
fun DialogTextButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
primary: Boolean = false,
) {
val (colorPalette, typography) = LocalAppearance.current
val textColor = when {
!enabled -> colorPalette.textDisabled
primary -> colorPalette.onAccent
else -> colorPalette.text
}
BasicText(
text = text,
style = typography.xs.medium.color(textColor),
modifier = modifier
.clip(RoundedCornerShape(36.dp))
.background(if (primary) colorPalette.accent else Color.Transparent)
.clickable(enabled = enabled, onClick = onClick)
.padding(horizontal = 20.dp, vertical = 16.dp)
)
}

View File

@@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
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.collectAsState import androidx.compose.runtime.collectAsState
@@ -31,7 +30,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -47,7 +45,6 @@ import it.vfsfitvnm.vimusic.models.Playlist
import it.vfsfitvnm.vimusic.models.SongPlaylistMap import it.vfsfitvnm.vimusic.models.SongPlaylistMap
import it.vfsfitvnm.vimusic.query import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.transaction import it.vfsfitvnm.vimusic.transaction
import it.vfsfitvnm.vimusic.ui.components.ChunkyButton
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.screens.albumRoute import it.vfsfitvnm.vimusic.ui.screens.albumRoute
import it.vfsfitvnm.vimusic.ui.screens.artistRoute import it.vfsfitvnm.vimusic.ui.screens.artistRoute
@@ -55,7 +52,6 @@ import it.vfsfitvnm.vimusic.ui.screens.viewPlaylistsRoute
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.addNext import it.vfsfitvnm.vimusic.utils.addNext
import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.enqueue import it.vfsfitvnm.vimusic.utils.enqueue
import it.vfsfitvnm.vimusic.utils.forcePlay import it.vfsfitvnm.vimusic.utils.forcePlay
import it.vfsfitvnm.vimusic.utils.semiBold import it.vfsfitvnm.vimusic.utils.semiBold
@@ -245,7 +241,10 @@ fun BaseMediaItemMenu(
val sendIntent = Intent().apply { val sendIntent = Intent().apply {
action = Intent.ACTION_SEND action = Intent.ACTION_SEND
type = "text/plain" type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "https://music.youtube.com/watch?v=${mediaItem.mediaId}") putExtra(
Intent.EXTRA_TEXT,
"https://music.youtube.com/watch?v=${mediaItem.mediaId}"
)
} }
context.startActivity(Intent.createChooser(sendIntent, null)) context.startActivity(Intent.createChooser(sendIntent, null))
@@ -280,9 +279,11 @@ fun MediaItemMenu(
when (targetState.route) { when (targetState.route) {
viewPlaylistsRoute -> slideIntoContainer(AnimatedContentScope.SlideDirection.Left) with viewPlaylistsRoute -> slideIntoContainer(AnimatedContentScope.SlideDirection.Left) with
slideOutOfContainer(AnimatedContentScope.SlideDirection.Left) slideOutOfContainer(AnimatedContentScope.SlideDirection.Left)
else -> when (initialState.route) { else -> when (initialState.route) {
viewPlaylistsRoute -> slideIntoContainer(AnimatedContentScope.SlideDirection.Right) with viewPlaylistsRoute -> slideIntoContainer(AnimatedContentScope.SlideDirection.Right) with
slideOutOfContainer(AnimatedContentScope.SlideDirection.Right) slideOutOfContainer(AnimatedContentScope.SlideDirection.Right)
else -> EnterTransition.None with ExitTransition.None else -> EnterTransition.None with ExitTransition.None
} }
} }
@@ -511,20 +512,14 @@ fun MediaItemMenu(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
) { ) {
ChunkyButton( DialogTextButton(
backgroundColor = Color.Transparent,
text = "Cancel", text = "Cancel",
textStyle = typography.xs.semiBold,
shape = RoundedCornerShape(36.dp),
onClick = { isShowingSleepTimerDialog = false } onClick = { isShowingSleepTimerDialog = false }
) )
ChunkyButton( DialogTextButton(
backgroundColor = colorPalette.accent,
text = "Set", text = "Set",
textStyle = typography.xs.semiBold.color(colorPalette.onAccent), enabled = amount > 0,
shape = RoundedCornerShape(36.dp),
isEnabled = amount > 0,
onClick = { onClick = {
binder?.startSleepTimer(amount * 10 * 60 * 1000L) binder?.startSleepTimer(amount * 10 * 60 * 1000L)
isShowingSleepTimerDialog = false isShowingSleepTimerDialog = false