diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreenTest.kt index e9d6d043e..ca0ead064 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreenTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreenTest.kt @@ -45,7 +45,6 @@ class BlocksEditScreenTest { composeTestRule.setContent { AppThemeSurface { BlocksEditContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickShowBlock = { blockClicked = true }, onClickShowTime = { timeClicked = true }, @@ -111,7 +110,6 @@ class BlocksEditScreenTest { composeTestRule.setContent { AppThemeSurface { BlocksEditContent( - onClose = {}, onBack = {}, onClickShowBlock = {}, onClickShowTime = {}, @@ -143,7 +141,6 @@ class BlocksEditScreenTest { composeTestRule.setContent { AppThemeSurface { BlocksEditContent( - onClose = {}, onBack = {}, onClickShowBlock = {}, onClickShowTime = {}, @@ -177,7 +174,6 @@ class BlocksEditScreenTest { composeTestRule.setContent { AppThemeSurface { BlocksEditContent( - onClose = {}, onBack = {}, onClickShowBlock = {}, onClickShowTime = {}, @@ -220,7 +216,6 @@ class BlocksEditScreenTest { composeTestRule.setContent { AppThemeSurface { BlocksEditContent( - onClose = {}, onBack = {}, onClickShowBlock = { blockClicked = true }, onClickShowTime = { timeClicked = true }, @@ -277,7 +272,6 @@ class BlocksEditScreenTest { composeTestRule.setContent { AppThemeSurface { BlocksEditContent( - onClose = {}, onBack = {}, onClickShowBlock = {}, onClickShowTime = {}, @@ -305,7 +299,6 @@ class BlocksEditScreenTest { composeTestRule.setContent { AppThemeSurface { BlocksEditContent( - onClose = {}, onBack = {}, onClickShowBlock = {}, onClickShowTime = {}, diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreenTest.kt index 5f2f0aca8..a2ebf2f56 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreenTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreenTest.kt @@ -38,7 +38,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = { editClicked = true }, onClickDelete = { deleteClicked = true }, @@ -95,7 +94,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = { editClicked = true }, onClickDelete = { deleteClicked = true }, @@ -137,7 +135,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -162,7 +159,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -200,7 +196,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = {}, onClickDelete = {}, @@ -232,7 +227,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -258,7 +252,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -291,7 +284,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -314,7 +306,6 @@ class BlocksPreviewContentTest { composeTestRule.setContent { AppThemeSurface { BlocksPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreenTest.kt index ab799b484..5112f7f2a 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreenTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreenTest.kt @@ -31,7 +31,6 @@ class FactsEditContentTest { composeTestRule.setContent { AppThemeSurface { FactsEditContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickShowSource = { sourceClicked = true }, onClickReset = { resetClicked = true }, @@ -93,7 +92,6 @@ class FactsEditContentTest { composeTestRule.setContent { AppThemeSurface { FactsEditContent( - onClose = {}, onBack = {}, onClickShowSource = {}, onClickReset = { resetClicked = true }, @@ -118,7 +116,6 @@ class FactsEditContentTest { composeTestRule.setContent { AppThemeSurface { FactsEditContent( - onClose = {}, onBack = {}, onClickShowSource = {}, onClickReset = {}, @@ -139,7 +136,6 @@ class FactsEditContentTest { composeTestRule.setContent { AppThemeSurface { FactsEditContent( - onClose = {}, onBack = {}, onClickShowSource = {}, onClickReset = {}, @@ -178,7 +174,6 @@ class FactsEditContentTest { composeTestRule.setContent { AppThemeSurface { FactsEditContent( - onClose = {}, onBack = {}, onClickShowSource = {}, onClickReset = {}, @@ -200,7 +195,6 @@ class FactsEditContentTest { composeTestRule.setContent { AppThemeSurface { FactsEditContent( - onClose = {}, onBack = {}, onClickShowSource = {}, onClickReset = {}, @@ -228,7 +222,6 @@ class FactsEditContentTest { composeTestRule.setContent { AppThemeSurface { FactsEditContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickShowSource = { sourceClicked = true }, onClickReset = { resetClicked = true }, diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreenTest.kt index 960638e33..d6432096e 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreenTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreenTest.kt @@ -30,7 +30,6 @@ class FactsPreviewContentTest { composeTestRule.setContent { AppThemeSurface { FactsPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = { editClicked = true }, onClickDelete = { deleteClicked = true }, @@ -87,7 +86,6 @@ class FactsPreviewContentTest { composeTestRule.setContent { AppThemeSurface { FactsPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = { editClicked = true }, onClickDelete = { deleteClicked = true }, @@ -122,7 +120,6 @@ class FactsPreviewContentTest { composeTestRule.setContent { AppThemeSurface { FactsPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -147,7 +144,6 @@ class FactsPreviewContentTest { composeTestRule.setContent { AppThemeSurface { FactsPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -185,7 +181,6 @@ class FactsPreviewContentTest { composeTestRule.setContent { AppThemeSurface { FactsPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = {}, onClickDelete = {}, @@ -210,7 +205,6 @@ class FactsPreviewContentTest { composeTestRule.setContent { AppThemeSurface { FactsPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -236,7 +230,6 @@ class FactsPreviewContentTest { composeTestRule.setContent { AppThemeSurface { FactsPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -262,7 +255,6 @@ class FactsPreviewContentTest { composeTestRule.setContent { AppThemeSurface { FactsPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditContentTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditContentTest.kt index f78d729a8..d75e43d29 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditContentTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditContentTest.kt @@ -42,7 +42,6 @@ class HeadlinesEditContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesEditContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickTime = { timeClicked = true }, onClickReset = { resetClicked = true }, @@ -118,7 +117,6 @@ class HeadlinesEditContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesEditContent( - onClose = {}, onBack = {}, onClickTime = {}, onClickReset = { resetClicked = true }, @@ -150,7 +148,6 @@ class HeadlinesEditContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesEditContent( - onClose = {}, onBack = {}, onClickTime = {}, onClickReset = {}, @@ -177,7 +174,6 @@ class HeadlinesEditContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesEditContent( - onClose = {}, onBack = {}, onClickTime = {}, onClickReset = {}, @@ -199,7 +195,6 @@ class HeadlinesEditContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesEditContent( - onClose = {}, onBack = {}, onClickTime = {}, onClickReset = {}, @@ -246,7 +241,6 @@ class HeadlinesEditContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesEditContent( - onClose = {}, onBack = {}, onClickTime = {}, onClickReset = {}, @@ -272,7 +266,6 @@ class HeadlinesEditContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesEditContent( - onClose = {}, onBack = {}, onClickTime = {}, onClickReset = {}, @@ -305,7 +298,6 @@ class HeadlinesEditContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesEditContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickTime = { timeClicked = true }, onClickReset = { resetClicked = true }, diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt index e037640b7..435db6b21 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt @@ -39,7 +39,6 @@ class HeadlinesPreviewContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = { editClicked = true }, onClickDelete = { deleteClicked = true }, @@ -96,7 +95,6 @@ class HeadlinesPreviewContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = { editClicked = true }, onClickDelete = { deleteClicked = true }, @@ -134,7 +132,6 @@ class HeadlinesPreviewContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -159,7 +156,6 @@ class HeadlinesPreviewContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -197,7 +193,6 @@ class HeadlinesPreviewContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = {}, onClickDelete = {}, @@ -223,7 +218,6 @@ class HeadlinesPreviewContentTest { composeTestRule.setContent { AppThemeSurface { HeadlinesPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreenTest.kt index df07f2497..7d2317cc6 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreenTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreenTest.kt @@ -44,7 +44,6 @@ class WeatherEditScreenTest { composeTestRule.setContent { AppThemeSurface { WeatherEditContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickShowTitle = { titleClicked = true }, onClickShowDescription = { descriptionClicked = true }, @@ -106,7 +105,6 @@ class WeatherEditScreenTest { composeTestRule.setContent { AppThemeSurface { WeatherEditContent( - onClose = {}, onBack = {}, onClickShowTitle = {}, onClickShowDescription = {}, @@ -136,7 +134,6 @@ class WeatherEditScreenTest { composeTestRule.setContent { AppThemeSurface { WeatherEditContent( - onClose = {}, onBack = {}, onClickShowTitle = {}, onClickShowDescription = {}, @@ -166,7 +163,6 @@ class WeatherEditScreenTest { composeTestRule.setContent { AppThemeSurface { WeatherEditContent( - onClose = {}, onBack = {}, onClickShowTitle = {}, onClickShowDescription = {}, @@ -203,7 +199,6 @@ class WeatherEditScreenTest { composeTestRule.setContent { AppThemeSurface { WeatherEditContent( - onClose = {}, onBack = {}, onClickShowTitle = { titleClicked = true }, onClickShowDescription = { descriptionClicked = true }, @@ -251,7 +246,6 @@ class WeatherEditScreenTest { composeTestRule.setContent { AppThemeSurface { WeatherEditContent( - onClose = {}, onBack = {}, onClickShowTitle = {}, onClickShowDescription = {}, @@ -277,7 +271,6 @@ class WeatherEditScreenTest { composeTestRule.setContent { AppThemeSurface { WeatherEditContent( - onClose = {}, onBack = {}, onClickShowTitle = {}, onClickShowDescription = {}, @@ -326,7 +319,6 @@ class WeatherEditScreenTest { composeTestRule.setContent { AppThemeSurface { WeatherEditContent( - onClose = {}, onBack = {}, onClickShowTitle = {}, onClickShowDescription = {}, diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreenTest.kt index 8c1de2847..f408613e0 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreenTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreenTest.kt @@ -40,7 +40,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = { editClicked = true }, onClickDelete = { deleteClicked = true }, @@ -97,7 +96,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = { editClicked = true }, onClickDelete = { deleteClicked = true }, @@ -137,7 +135,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -162,7 +159,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -200,7 +196,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = { closeClicked = true }, onBack = { backClicked = true }, onClickEdit = {}, onClickDelete = {}, @@ -230,7 +225,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -256,7 +250,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -287,7 +280,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -310,7 +302,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, @@ -333,7 +324,6 @@ class WeatherPreviewContentTest { composeTestRule.setContent { AppThemeSurface { WeatherPreviewContent( - onClose = {}, onBack = {}, onClickEdit = {}, onClickDelete = {}, diff --git a/app/src/androidTest/java/to/bitkit/ui/settings/support/ReportIssueScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/settings/support/ReportIssueScreenTest.kt index 845e0ed55..d7e9f2c2b 100644 --- a/app/src/androidTest/java/to/bitkit/ui/settings/support/ReportIssueScreenTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/settings/support/ReportIssueScreenTest.kt @@ -29,7 +29,6 @@ class ReportIssueContentTest { AppThemeSurface { ReportIssueContent( onBack = {}, - onClose = {}, onConfirm = {}, onUpdateEmail = {}, onUpdateMessage = {}, @@ -54,7 +53,6 @@ class ReportIssueContentTest { AppThemeSurface { ReportIssueContent( onBack = {}, - onClose = {}, onConfirm = {}, onUpdateEmail = { emailUpdated = it }, onUpdateMessage = {}, @@ -77,7 +75,6 @@ class ReportIssueContentTest { AppThemeSurface { ReportIssueContent( onBack = {}, - onClose = {}, onConfirm = {}, onUpdateEmail = {}, onUpdateMessage = { messageUpdated = it }, @@ -100,7 +97,6 @@ class ReportIssueContentTest { AppThemeSurface { ReportIssueContent( onBack = {}, - onClose = {}, onConfirm = { sendClicked = true }, onUpdateEmail = {}, onUpdateMessage = {}, @@ -121,7 +117,6 @@ class ReportIssueContentTest { AppThemeSurface { ReportIssueContent( onBack = {}, - onClose = {}, onConfirm = {}, onUpdateEmail = {}, onUpdateMessage = {}, @@ -140,7 +135,6 @@ class ReportIssueContentTest { AppThemeSurface { ReportIssueContent( onBack = {}, - onClose = {}, onConfirm = {}, onUpdateEmail = {}, onUpdateMessage = {}, @@ -163,7 +157,6 @@ class ReportIssueContentTest { AppThemeSurface { ReportIssueContent( onBack = {}, - onClose = {}, onConfirm = {}, onUpdateEmail = {}, onUpdateMessage = {}, diff --git a/app/src/main/java/to/bitkit/ui/components/Button.kt b/app/src/main/java/to/bitkit/ui/components/Button.kt index 55d3ddcfc..0d6927414 100644 --- a/app/src/main/java/to/bitkit/ui/components/Button.kt +++ b/app/src/main/java/to/bitkit/ui/components/Button.kt @@ -1,6 +1,11 @@ package to.bitkit.ui.components +import androidx.compose.animation.animateColorAsState import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -13,22 +18,27 @@ import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.Home -import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon -import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.Text -import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import to.bitkit.ui.theme.AppButtonDefaults +import to.bitkit.ui.shared.util.gradientBackground +import to.bitkit.ui.shared.util.innerShadow import to.bitkit.ui.theme.AppThemeSurface import to.bitkit.ui.theme.Colors @@ -57,41 +67,89 @@ fun PrimaryButton( size: ButtonSize = ButtonSize.Large, enabled: Boolean = true, fullWidth: Boolean = true, - color: Color = Colors.White16, ) { + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + val contentPadding = PaddingValues(horizontal = size.horizontalPadding.takeIf { text != null } ?: 0.dp) - Button( - onClick = onClick, - enabled = enabled && !isLoading, - colors = AppButtonDefaults.primaryColors.copy(containerColor = color), - contentPadding = contentPadding, + val shape = MaterialTheme.shapes.extraLarge + + Surface( + shape = shape, + color = Color.Transparent, modifier = Modifier .then(if (fullWidth) Modifier.fillMaxWidth() else Modifier) .requiredHeight(size.height) .then(modifier) - ) { - if (isLoading) { - CircularProgressIndicator( - color = Colors.White32, - strokeWidth = 2.dp, - modifier = Modifier.size(size.height / 2) + .then( + if (enabled) { + Modifier.shadow( + elevation = 4.dp, + shape = shape, + ambientColor = Colors.White.copy(alpha = if (isPressed) 0.4f else 0.25f), + spotColor = Colors.White.copy(alpha = if (isPressed) 0.4f else 0.25f) + ) + } else { + Modifier + } ) - } else { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - if (icon != null) { - Box(modifier = if (enabled) Modifier else Modifier.alpha(0.5f)) { - icon() - } + .then( + when { + !enabled -> Modifier.background(color = Colors.White06, shape = shape) + isPressed -> Modifier.gradientBackground(startColor = Colors.Gray3, endColor = Colors.Gray4) + else -> Modifier.gradientBackground(startColor = Colors.Gray4, endColor = Colors.Gray5) } - text?.let { - Text( - text = text, - maxLines = 1, - overflow = TextOverflow.Ellipsis, + ) + .then(if (enabled) Modifier else Modifier.alpha(0.32f)) + .then( + if (enabled) { + Modifier.innerShadow( + color = Colors.White.copy(alpha = if (isPressed) 0.1f else 0.05f), + blurRadius = 4.dp, + shape = shape ) + } else { + Modifier + } + ) + .clickable( + onClick = onClick, + enabled = enabled && !isLoading, + interactionSource = interactionSource, + indication = null + ) + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .then(if (fullWidth) Modifier.fillMaxWidth() else Modifier) + .padding(contentPadding) + ) { + if (isLoading) { + CircularProgressIndicator( + color = Colors.White32, + strokeWidth = 2.dp, + modifier = Modifier.size(size.height / 2) + ) + } else { + CompositionLocalProvider(LocalContentColor provides Colors.White) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + if (icon != null) { + Box(modifier = if (enabled) Modifier else Modifier.alpha(0.5f)) { + icon() + } + } + text?.let { + Text( + text = text, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } } } } @@ -109,42 +167,70 @@ fun SecondaryButton( enabled: Boolean = true, fullWidth: Boolean = true, ) { + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + + val backgroundColor by animateColorAsState( + targetValue = if (isPressed) Colors.White10 else Colors.White01, + label = "secondaryButtonBackground" + ) + val borderColor by animateColorAsState( + targetValue = if (enabled) Colors.Gray4 else Color.Transparent, + label = "secondaryButtonBorder" + ) + val contentPadding = PaddingValues(horizontal = size.horizontalPadding.takeIf { text != null } ?: 0.dp) - val border = BorderStroke(2.dp, if (enabled) Colors.White16 else Color.Transparent) - OutlinedButton( - onClick = onClick, - enabled = enabled && !isLoading, - colors = AppButtonDefaults.secondaryColors, - contentPadding = contentPadding, - border = border, + val shape = MaterialTheme.shapes.extraLarge + + Surface( + shape = shape, + color = backgroundColor, + border = BorderStroke(2.dp, borderColor), modifier = Modifier .then(if (fullWidth) Modifier.fillMaxWidth() else Modifier) .requiredHeight(size.height) .then(modifier) - ) { - if (isLoading) { - CircularProgressIndicator( - color = Colors.White32, - strokeWidth = 2.dp, - modifier = Modifier.size(size.height / 2) + .clickable( + onClick = onClick, + enabled = enabled && !isLoading, + interactionSource = interactionSource, + indication = null ) - } else { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - if (icon != null) { - Box(modifier = if (enabled) Modifier else Modifier.alpha(0.5f)) { - icon() + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .then(if (fullWidth) Modifier.fillMaxWidth() else Modifier) + .padding(contentPadding) + ) { + if (isLoading) { + CircularProgressIndicator( + color = Colors.White32, + strokeWidth = 2.dp, + modifier = Modifier.size(size.height / 2) + ) + } else { + CompositionLocalProvider( + LocalContentColor provides if (enabled) Colors.White80 else Colors.White32 + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + if (icon != null) { + Box(modifier = if (enabled) Modifier else Modifier.alpha(0.5f)) { + icon() + } + } + text?.let { + Text( + text = text, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } } } - text?.let { - Text( - text = text, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } } } } @@ -161,35 +247,67 @@ fun TertiaryButton( enabled: Boolean = true, fullWidth: Boolean = true, ) { + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + + val textColor by animateColorAsState( + targetValue = when { + !enabled -> Colors.White32 + isPressed -> Colors.White + else -> Colors.White80 + }, + label = "tertiaryButtonText" + ) + val contentPadding = PaddingValues(horizontal = size.horizontalPadding.takeIf { text != null } ?: 0.dp) - TextButton( - onClick = onClick, - enabled = enabled && !isLoading, - colors = AppButtonDefaults.tertiaryColors, - contentPadding = contentPadding, + val shape = MaterialTheme.shapes.extraLarge + + Surface( + shape = shape, + color = Color.Transparent, modifier = Modifier .then(if (fullWidth) Modifier.fillMaxWidth() else Modifier) .requiredHeight(size.height) .then(modifier) - ) { - if (isLoading) { - CircularProgressIndicator( - color = Colors.White32, - strokeWidth = 2.dp, - modifier = Modifier.size(size.height / 2) + .clickable( + onClick = onClick, + enabled = enabled && !isLoading, + interactionSource = interactionSource, + indication = null ) - } else { - if (icon != null) { - Box(modifier = if (enabled) Modifier else Modifier.alpha(0.5f)) { - icon() - } - } - text?.let { - Text( - text = text, - maxLines = 1, - overflow = TextOverflow.Ellipsis, + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .then(if (fullWidth) Modifier.fillMaxWidth() else Modifier) + .padding(contentPadding) + ) { + if (isLoading) { + CircularProgressIndicator( + color = Colors.White32, + strokeWidth = 2.dp, + modifier = Modifier.size(size.height / 2) ) + } else { + CompositionLocalProvider(LocalContentColor provides textColor) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + if (icon != null) { + Box(modifier = if (enabled) Modifier else Modifier.alpha(0.5f)) { + icon() + } + } + text?.let { + Text( + text = text, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } + } } } } @@ -241,11 +359,10 @@ private fun PrimaryButtonPreview() { onClick = {}, ) PrimaryButton( - text = "Primary Small Color Not Full", + text = "Primary Small Not Full", size = ButtonSize.Small, onClick = {}, fullWidth = false, - color = Colors.Brand, ) PrimaryButton( text = "Primary Small Loading", @@ -267,7 +384,7 @@ private fun PrimaryButtonPreview() { PrimaryButton( text = null, onClick = {}, - fullWidth = false, + fullWidth = true, size = ButtonSize.Large, icon = { Icon( @@ -280,7 +397,7 @@ private fun PrimaryButtonPreview() { PrimaryButton( text = null, onClick = {}, - fullWidth = false, + fullWidth = true, size = ButtonSize.Small, enabled = false, icon = { @@ -361,7 +478,7 @@ private fun SecondaryButtonPreview() { SecondaryButton( text = null, onClick = {}, - fullWidth = false, + fullWidth = true, size = ButtonSize.Large, icon = { Icon( @@ -374,7 +491,7 @@ private fun SecondaryButtonPreview() { SecondaryButton( text = null, onClick = {}, - fullWidth = false, + fullWidth = true, size = ButtonSize.Small, enabled = false, icon = { diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt index 8304d608c..3f33a53b9 100644 --- a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt @@ -265,7 +265,6 @@ private fun ReceiveQrSlide( size = ButtonSize.Small, onClick = onClickEditInvoice, fullWidth = false, - color = Colors.White10, icon = { Icon( painter = painterResource(R.drawable.ic_pencil_simple), @@ -288,7 +287,6 @@ private fun ReceiveQrSlide( coroutineScope.launch { qrButtonTooltipState.show() } }, fullWidth = false, - color = Colors.White10, icon = { Icon( painter = painterResource(R.drawable.ic_copy), @@ -309,7 +307,6 @@ private fun ReceiveQrSlide( } ?: shareText(context, uri) }, fullWidth = false, - color = Colors.White10, icon = { Icon( painter = painterResource(R.drawable.ic_share), @@ -412,7 +409,6 @@ private fun CopyAddressCard( coroutineScope.launch { tooltipState.show() } }, fullWidth = false, - color = Colors.White10, icon = { Icon( painter = painterResource(R.drawable.ic_copy), @@ -428,7 +424,6 @@ private fun CopyAddressCard( size = ButtonSize.Small, onClick = { shareText(context, address) }, fullWidth = false, - color = Colors.White10, icon = { Icon( painter = painterResource(R.drawable.ic_share), diff --git a/app/src/main/java/to/bitkit/ui/settings/advanced/AddressViewerScreen.kt b/app/src/main/java/to/bitkit/ui/settings/advanced/AddressViewerScreen.kt index deb9dd4fa..d677e0e92 100644 --- a/app/src/main/java/to/bitkit/ui/settings/advanced/AddressViewerScreen.kt +++ b/app/src/main/java/to/bitkit/ui/settings/advanced/AddressViewerScreen.kt @@ -165,13 +165,11 @@ private fun AddressViewerContent( text = stringResource(R.string.settings__addr__addr_change), size = ButtonSize.Small, onClick = { onSwitchAddressType(false) }, - color = if (uiState.showReceiveAddresses) Colors.White16 else Colors.Brand, modifier = Modifier.weight(1f) ) PrimaryButton( text = stringResource(R.string.settings__addr__addr_receiving), size = ButtonSize.Small, - color = if (uiState.showReceiveAddresses) Colors.Brand else Colors.White16, onClick = { onSwitchAddressType(true) }, modifier = Modifier.weight(1f) ) diff --git a/app/src/main/java/to/bitkit/ui/settings/backups/ConfirmMnemonicScreen.kt b/app/src/main/java/to/bitkit/ui/settings/backups/ConfirmMnemonicScreen.kt index 8b7166a0c..48f4f4ca1 100644 --- a/app/src/main/java/to/bitkit/ui/settings/backups/ConfirmMnemonicScreen.kt +++ b/app/src/main/java/to/bitkit/ui/settings/backups/ConfirmMnemonicScreen.kt @@ -157,10 +157,10 @@ private fun ConfirmMnemonicContent( shuffledWords.forEachIndexed { index, word -> PrimaryButton( text = word, - color = if (pressedStates.getOrNull(index) == true) Colors.White32 else Colors.White16, fullWidth = false, size = ButtonSize.Small, onClick = { onWordPress(word, index) }, + enabled = pressedStates.getOrNull(index) != true, modifier = Modifier.testTag("Word-$word") ) } diff --git a/app/src/main/java/to/bitkit/ui/settings/backups/ShowMnemonicScreen.kt b/app/src/main/java/to/bitkit/ui/settings/backups/ShowMnemonicScreen.kt index 4da79b388..c5650ef5f 100644 --- a/app/src/main/java/to/bitkit/ui/settings/backups/ShowMnemonicScreen.kt +++ b/app/src/main/java/to/bitkit/ui/settings/backups/ShowMnemonicScreen.kt @@ -168,7 +168,6 @@ private fun ShowMnemonicContent( text = stringResource(R.string.security__mnemonic_reveal), fullWidth = false, onClick = onRevealClick, - color = Colors.Black50, modifier = Modifier .alpha(buttonAlpha) .testTag("TapToReveal") diff --git a/app/src/main/java/to/bitkit/ui/shared/util/Modifiers.kt b/app/src/main/java/to/bitkit/ui/shared/util/Modifiers.kt index befd166c8..98960f7fb 100644 --- a/app/src/main/java/to/bitkit/ui/shared/util/Modifiers.kt +++ b/app/src/main/java/to/bitkit/ui/shared/util/Modifiers.kt @@ -17,10 +17,19 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.composed +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Outline +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.graphics.drawscope.clipPath import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp import to.bitkit.ui.theme.Colors /** @@ -79,6 +88,54 @@ fun Modifier.gradientBackground(startColor: Color = Colors.Gray6, endColor: Colo ) } +/** + * Draws an inner highlight at the top edge to create depth/volume effect. + * Matches iOS shadow: .shadow(color: shadowColor, radius: 0, x: 0, y: -1) + * + * @param color The highlight color (typically white with alpha) + * @param blurRadius The blur radius for soft edges (use 0.dp for sharp, 2-4.dp for smooth) + * @param shape The shape to clip the highlight to (must match parent shape) + */ +fun Modifier.innerShadow( + color: Color, + blurRadius: Dp = 4.dp, + shape: Shape, +): Modifier = this.drawWithContent { + // Draw content first (gradient, etc) + drawContent() + + // Convert blur radius to pixels using DrawScope's density + val blurRadiusPx = blurRadius.toPx() + + // Get shape outline for clipping + val outline = shape.createOutline(size, layoutDirection, this) + + // Convert outline to path + val path = when (outline) { + is Outline.Rectangle -> Path().apply { addRect(outline.rect) } + is Outline.Rounded -> Path().apply { addRoundRect(outline.roundRect) } + is Outline.Generic -> outline.path + } + + // Clip to shape and draw top edge highlight with soft gradient + clipPath(path) { + drawRect( + brush = Brush.verticalGradient( + colors = listOf( + color, + color.copy(alpha = color.alpha * 0.7f), + color.copy(alpha = color.alpha * 0.3f), + Color.Transparent + ), + startY = 0f, + endY = blurRadiusPx * 2.5f + ), + topLeft = Offset(0f, 0f), + size = Size(size.width, blurRadiusPx * 2.5f) + ) + } +} + fun Modifier.blockPointerInputPassthrough(): Modifier { return this.pointerInput(Unit) { awaitPointerEventScope { diff --git a/app/src/main/java/to/bitkit/ui/theme/Colors.kt b/app/src/main/java/to/bitkit/ui/theme/Colors.kt index 087296203..02a91e13c 100644 --- a/app/src/main/java/to/bitkit/ui/theme/Colors.kt +++ b/app/src/main/java/to/bitkit/ui/theme/Colors.kt @@ -17,9 +17,9 @@ object Colors { // Gray Base val Gray6 = Color(0xFF151515) - val Gray5 = Color(0xFF1C1C1D) - val Gray4 = Color(0xFF3A343C) - val Gray3 = Color(0xFF48484A) + val Gray5 = Color(0xFF1C1C1C) + val Gray4 = Color(0xFF2A2A2A) + val Gray3 = Color(0xFF3A3A3A) val Gray2 = Color(0xFF636366) val Gray1 = Color(0xFF8E8E93) @@ -28,6 +28,7 @@ object Colors { val Black70 = Color.Black.copy(alpha = 0.7f) val Black92 = Color.Black.copy(alpha = 0.92f) val Black25 = Color.Black.copy(alpha = 0.25f) + val White01 = Color.White.copy(alpha = 0.01f) val White06 = Color.White.copy(alpha = 0.06f) val White08 = Color.White.copy(alpha = 0.08f) val White10 = Color.White.copy(alpha = 0.10f)