Skip to content
Merged
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
2 changes: 1 addition & 1 deletion app/src/main/java/to/bitkit/ui/components/BottomSheet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fun BottomSheet(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxWidth()
.background(color = Colors.Gray6)
.background(color = Colors.White08)
) {
SheetDragHandle()
}
Expand Down
136 changes: 99 additions & 37 deletions app/src/main/java/to/bitkit/ui/components/Button.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ 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.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
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.shared.util.primaryButtonStyle
import to.bitkit.ui.theme.AppButtonDefaults
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
Expand Down Expand Up @@ -57,41 +60,68 @@ fun PrimaryButton(
size: ButtonSize = ButtonSize.Large,
enabled: Boolean = true,
fullWidth: Boolean = true,
color: Color = Colors.White16,
color: Color? = null,
) {
val contentPadding = PaddingValues(horizontal = size.horizontalPadding.takeIf { text != null } ?: 0.dp)
val buttonShape = MaterialTheme.shapes.large

Button(
onClick = onClick,
enabled = enabled && !isLoading,
colors = AppButtonDefaults.primaryColors.copy(containerColor = color),
contentPadding = contentPadding,
colors = AppButtonDefaults.primaryColors.copy(
containerColor = Color.Transparent,
disabledContainerColor = Color.Transparent
),
contentPadding = PaddingValues(0.dp),
shape = buttonShape,
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)
)
} 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)
.requiredHeight(size.height)
.primaryButtonStyle(
isEnabled = enabled && !isLoading,
shape = buttonShape,
primaryColor = color
)
.padding(contentPadding)
) {
if (isLoading) {
CircularProgressIndicator(
color = Colors.White32,
strokeWidth = 2.dp,
modifier = Modifier.size(size.height / 2)
)
} else {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
if (icon != null) {
Box(
modifier = if (enabled) {
Modifier
} else {
Modifier.graphicsLayer {
colorFilter = ColorFilter.tint(Colors.White32)
}
}
) {
icon()
}
}
text?.let {
Text(
text = text,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
text?.let {
Text(
text = text,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
}
Expand All @@ -110,7 +140,7 @@ fun SecondaryButton(
fullWidth: Boolean = true,
) {
val contentPadding = PaddingValues(horizontal = size.horizontalPadding.takeIf { text != null } ?: 0.dp)
val border = BorderStroke(2.dp, if (enabled) Colors.White16 else Color.Transparent)
val border = BorderStroke(2.dp, if (enabled) Colors.Gray4 else Color.Transparent)
OutlinedButton(
onClick = onClick,
enabled = enabled && !isLoading,
Expand All @@ -134,7 +164,15 @@ fun SecondaryButton(
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
if (icon != null) {
Box(modifier = if (enabled) Modifier else Modifier.alpha(0.5f)) {
Box(
modifier = if (enabled) {
Modifier
} else {
Modifier.graphicsLayer {
colorFilter = ColorFilter.tint(Colors.White32)
}
}
) {
icon()
}
}
Expand Down Expand Up @@ -179,17 +217,30 @@ fun TertiaryButton(
modifier = Modifier.size(size.height / 2)
)
} else {
if (icon != null) {
Box(modifier = if (enabled) Modifier else Modifier.alpha(0.5f)) {
icon()
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
if (icon != null) {
Box(
modifier = if (enabled) {
Modifier
} else {
Modifier.graphicsLayer {
colorFilter = ColorFilter.tint(Colors.White32)
}
}
) {
icon()
}
}
text?.let {
Text(
text = text,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
text?.let {
Text(
text = text,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
}
Expand Down Expand Up @@ -237,6 +288,7 @@ private fun PrimaryButtonPreview() {
)
PrimaryButton(
text = "Primary Small",
fullWidth = false,
size = ButtonSize.Small,
onClick = {},
)
Expand Down Expand Up @@ -339,6 +391,7 @@ private fun SecondaryButtonPreview() {
SecondaryButton(
text = "Secondary Small",
size = ButtonSize.Small,
fullWidth = false,
onClick = {},
)
SecondaryButton(
Expand Down Expand Up @@ -421,11 +474,20 @@ private fun TertiaryButtonPreview() {
TertiaryButton(
text = "Tertiary Disabled",
enabled = false,
icon = {
Icon(
imageVector = Icons.Filled.Favorite,
contentDescription = "",
tint = Colors.Brand,
modifier = Modifier.size(16.dp)
)
},
onClick = {}
)
TertiaryButton(
text = "Tertiary Small",
size = ButtonSize.Small,
fullWidth = false,
onClick = {}
)
TertiaryButton(
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/java/to/bitkit/ui/components/SheetHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import to.bitkit.ui.sheets.BackupRoute
Expand All @@ -31,6 +32,8 @@ import to.bitkit.ui.theme.Colors

enum class SheetSize { LARGE, MEDIUM, SMALL, CALENDAR; }

private val sheetContainerColor = Color(0xFF141414) // Equivalent to White08 on a Black background

@Stable
sealed interface Sheet {
data class Send(val route: SendRoute = SendRoute.Recipient) : Sheet
Expand Down Expand Up @@ -92,7 +95,7 @@ fun SheetHost(
sheetShape = AppShapes.sheet,
sheetContent = sheets,
sheetDragHandle = { SheetDragHandle() },
sheetContainerColor = Colors.Gray6,
sheetContainerColor = sheetContainerColor,
sheetContentColor = MaterialTheme.colorScheme.onSurface,
) {
content()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
82 changes: 77 additions & 5 deletions app/src/main/java/to/bitkit/ui/shared/util/Modifiers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,17 @@ 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.clip
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.draw.shadow
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.Shape
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp
import to.bitkit.ui.theme.Colors

/**
Expand Down Expand Up @@ -71,12 +78,17 @@ fun Modifier.clickableAlpha(
)
}

fun Modifier.gradientBackground(startColor: Color = Colors.Gray6, endColor: Color = Colors.Black): Modifier {
return this.background(
brush = Brush.verticalGradient(
colors = listOf(startColor, endColor)
fun Modifier.gradientBackground(
startColor: Color = Colors.White08,
endColor: Color = Color.White.copy(alpha = 0.012f),
): Modifier {
return this
.background(Color.Black)
.background(
brush = Brush.verticalGradient(
colors = listOf(startColor, endColor)
)
)
)
}

fun Modifier.blockPointerInputPassthrough(): Modifier {
Expand All @@ -97,3 +109,63 @@ fun Modifier.screen(
.fillMaxSize()
.then(if (noBackground) Modifier else Modifier.background(MaterialTheme.colorScheme.background))
.then(if (insets == null) Modifier else Modifier.windowInsetsPadding(insets))

fun Modifier.primaryButtonStyle(
isEnabled: Boolean,
shape: Shape,
primaryColor: Color? = null,
): Modifier {
return this
// Step 1: Add shadow (only when enabled)
.then(
if (isEnabled) {
Modifier.shadow(
elevation = 16.dp,
shape = shape,
clip = false // Don't clip content, just add shadow
)
} else {
Modifier
}
)
// Step 2: Clip to shape first
.clip(shape)
// Step 3: Apply gradient background with border overlay
.then(
if (isEnabled) {
Modifier.drawWithContent {
// Draw the main gradient background filling entire button
val mainBrush = Brush.verticalGradient(
colors = listOf(primaryColor ?: Colors.Gray5, Colors.Gray6),
startY = 0f,
endY = size.height
)
drawRect(
brush = mainBrush,
topLeft = Offset.Zero,
size = size
)

// Draw top border highlight (2dp gradient fade)
val borderHeight = 2.dp.toPx()
drawRect(
brush = Brush.verticalGradient(
colors = listOf(
Colors.White16,
Color.Transparent
),
startY = 0f,
endY = borderHeight
),
topLeft = Offset(0f, 0f),
size = Size(size.width, borderHeight)
)

// Draw the actual button content on top
drawContent()
}
} else {
Modifier.background(Colors.White06)
}
)
}
9 changes: 5 additions & 4 deletions app/src/main/java/to/bitkit/ui/theme/Colors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ object Colors {
val White = Color(0xFFFFFFFF)

// Gray Base
val Gray6 = Color(0xFF151515)
val Gray5 = Color(0xFF1C1C1D)
val Gray4 = Color(0xFF3A343C)
val Gray7 = Color(0xFF101010)
val Gray6 = Color(0xFF1C1C1C)
val Gray5 = Color(0xFF2A2A2A)
val Gray4 = Color(0xFF3A3A3A)
val Gray3 = Color(0xFF48484A)
val Gray2 = Color(0xFF636366)
val Gray1 = Color(0xFF8E8E93)
val Gray1 = Color(0xFF8E8E8E)

// Alpha
val Black50 = Color.Black.copy(alpha = 0.5f)
Expand Down
Loading