Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improve Pubky profile restore, contact editing, and contact routing flows #905

### Fixed
- Align tab colors, Show details button, notifications bell figure, and home activity count with iOS #907
- Polish Terms of Use screen padding to match iOS #903

## [2.2.0] - 2026-04-07
Expand Down
11 changes: 8 additions & 3 deletions app/src/main/java/to/bitkit/ui/ContentView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,11 @@ fun ContentView(

TimedSheetType.NOTIFICATIONS -> {
BackgroundPaymentsIntroSheet(
onContinue = {
onLater = {
appViewModel.dismissTimedSheet()
settingsViewModel.setBgPaymentsIntroSeen(true)
},
onEnable = {
appViewModel.dismissTimedSheet()
navController.navigateTo(Routes.BackgroundPaymentsSettings)
settingsViewModel.setBgPaymentsIntroSeen(true)
Expand Down Expand Up @@ -1145,9 +1149,10 @@ private fun NavGraphBuilder.generalSettingsSubScreens(navController: NavHostCont
composableWithDefaultTransitions<Routes.BackgroundPaymentsIntro> {
BackgroundPaymentsIntroScreen(
onBack = { navController.popBackStack() },
onContinue = {
onLater = { navController.popBackStack() },
onEnable = {
navController.navigateTo(Routes.BackgroundPaymentsSettings)
}
},
)
}
}
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/java/to/bitkit/ui/components/EmptyWalletView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import to.bitkit.R
import to.bitkit.ui.shared.modifiers.rememberDebouncedClick
import to.bitkit.ui.theme.AppThemeSurface
Expand All @@ -36,8 +37,11 @@ import to.bitkit.ui.utils.withAccent
fun EmptyStateView(
text: AnnotatedString,
modifier: Modifier = Modifier,
isSmallScreen: Boolean = false,
onClose: (() -> Unit)? = null,
) {
val fontSize = if (isSmallScreen) 32.sp else 44.sp
val arrowMaxHeight = if (isSmallScreen) 96.dp else 144.dp
Box(modifier = modifier) {
Column(
modifier = Modifier
Expand All @@ -52,14 +56,15 @@ fun EmptyStateView(
) {
Display(
text = text,
fontSize = fontSize,
modifier = Modifier.width(220.dp)
)
Image(
painter = painterResource(id = R.drawable.empty_state_arrow),
contentDescription = null,
contentScale = ContentScale.Fit,
modifier = Modifier
.heightIn(max = 144.dp)
.heightIn(max = arrowMaxHeight)
.offset(x = (-10).dp)
)
Spacer(modifier = Modifier.weight(1f))
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/to/bitkit/ui/components/Text.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@ fun Display(
fun Display(
text: AnnotatedString,
modifier: Modifier = Modifier,
fontSize: TextUnit = 44.sp,
color: Color = MaterialTheme.colorScheme.primary,
) {
Text(
text = text.toUpperCase(),
style = AppTextStyles.Display.merge(
fontSize = fontSize,
lineHeight = fontSize,
color = color,
),
modifier = modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package to.bitkit.ui.screens.shop.shopDiscover
import android.annotation.SuppressLint
import android.view.ViewGroup
import android.webkit.WebView
import androidx.annotation.StringRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
Expand All @@ -15,102 +16,85 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRowDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
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.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import kotlinx.collections.immutable.toImmutableList
import to.bitkit.R
import to.bitkit.env.Env
import to.bitkit.ext.configureForBasicWebContent
import to.bitkit.models.BitrefillCategory
import to.bitkit.ui.components.BodyM
import to.bitkit.ui.components.CaptionB
import to.bitkit.ui.components.SuggestionCard
import to.bitkit.ui.components.Text13Up
import to.bitkit.ui.components.VerticalSpacer
import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.scaffold.DrawerNavIcon
import to.bitkit.ui.scaffold.ScreenColumn
import to.bitkit.ui.screens.wallets.activity.components.CustomTabRowWithSpacing
import to.bitkit.ui.screens.wallets.activity.components.TabItem
import to.bitkit.ui.shared.modifiers.clickableAlpha
import to.bitkit.ui.shared.util.gradientBackground
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
import to.bitkit.ui.theme.Shapes

@OptIn(ExperimentalMaterial3Api::class)
private enum class ShopDiscoverTab(@StringRes private val titleRes: Int) : TabItem {
Shop(R.string.other__shop__discover__tabs__shop),
Map(R.string.other__shop__discover__tabs__map);

override val uiText @Composable get() = stringResource(titleRes)
}

@Composable
fun ShopDiscoverScreen(
onBack: () -> Unit,
navigateWebView: (String, String) -> Unit, // Page, Title
modifier: Modifier = Modifier,
) {
var selectedTabIndex by remember { mutableIntStateOf(0) }
val tabTitles = listOf(
stringResource(R.string.other__shop__discover__tabs__shop),
stringResource(R.string.other__shop__discover__tabs__map),
)
val tabs = remember { ShopDiscoverTab.entries.toImmutableList() }
var selectedTab by remember { mutableStateOf(ShopDiscoverTab.Shop) }

ScreenColumn(
modifier = Modifier.gradientBackground(),
) {
ScreenColumn(modifier = modifier) {
AppTopBar(
titleText = stringResource(R.string.other__shop__discover__nav_title),
onBackClick = onBack,
actions = { DrawerNavIcon() },
)

PrimaryTabRow(
selectedTabIndex = selectedTabIndex,
containerColor = Color.Transparent,
indicator = {
TabRowDefaults.PrimaryIndicator(
modifier = Modifier.tabIndicatorOffset(selectedTabIndex),
color = Colors.Yellow,
width = Dp.Unspecified,
)
},
modifier = Modifier.padding(horizontal = 16.dp),
) {
tabTitles.forEachIndexed { index, title ->
Tab(
selected = selectedTabIndex == index,
onClick = { selectedTabIndex = index },
unselectedContentColor = Colors.White64,
text = { CaptionB(title) },
)
}
}
CustomTabRowWithSpacing(
tabs = tabs,
currentTabIndex = tabs.indexOf(selectedTab),
selectedColor = Colors.White,
onTabChange = { selectedTab = it },
modifier = Modifier.padding(horizontal = 16.dp)
)

when (selectedTabIndex) {
0 -> ShopTabContent(navigateWebView = navigateWebView)
1 -> MapTabContent()
when (selectedTab) {
ShopDiscoverTab.Shop -> ShopTabContent(navigateWebView = navigateWebView)
ShopDiscoverTab.Map -> MapTabContent()
}
}
}

@Composable
private fun ShopTabContent(
navigateWebView: (String, String) -> Unit,
modifier: Modifier = Modifier,
) {
LazyColumn(
modifier = Modifier.padding(horizontal = 16.dp),
modifier = modifier.padding(horizontal = 16.dp)
) {
item {
VerticalSpacer(16.dp)
Expand All @@ -120,31 +104,29 @@ private fun ShopTabContent(
) {
val title = stringResource(R.string.other__shop__discover__gift_cards__title)
SuggestionCard(
modifier = Modifier.weight(1f),
gradientColor = Colors.Green24,
title = title,
description = stringResource(R.string.other__shop__discover__gift_cards__description),
icon = R.drawable.gift,
captionColor = Colors.Gray1,

disableGlow = true,
onClick = {
navigateWebView("gift-cards", title)
},
modifier = Modifier.weight(1f)
)
val title2 = stringResource(R.string.other__shop__discover__esims__title)
SuggestionCard(
modifier = Modifier.weight(1f),
gradientColor = Colors.Yellow24,
title = title2,
description = stringResource(R.string.other__shop__discover__esims__description),
icon = R.drawable.globe,
captionColor = Colors.Gray1,

disableGlow = true,
onClick = {
navigateWebView("esims", title2)
},
modifier = Modifier.weight(1f)
)
}

Expand All @@ -155,31 +137,29 @@ private fun ShopTabContent(
) {
val title = stringResource(R.string.other__shop__discover__refill__title)
SuggestionCard(
modifier = Modifier.weight(1f),
gradientColor = Colors.Purple24,
title = title,
description = stringResource(R.string.other__shop__discover__refill__description),
icon = R.drawable.phone,
captionColor = Colors.Gray1,

disableGlow = true,
onClick = {
navigateWebView("refill", title)
},
modifier = Modifier.weight(1f)
)
val title2 = stringResource(R.string.other__shop__discover__travel__title)
SuggestionCard(
modifier = Modifier.weight(1f),
gradientColor = Colors.Red24,
title = title2,
description = stringResource(R.string.other__shop__discover__travel__description),
icon = R.drawable.rocket_2,

disableGlow = true,
captionColor = Colors.Gray1,
onClick = {
navigateWebView("buy/travel", title2)
},
modifier = Modifier.weight(1f)
)
}

Expand All @@ -193,38 +173,38 @@ private fun ShopTabContent(
items(items = BitrefillCategory.entries.toList(), key = { it.name }) { item ->
Column {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clickableAlpha {
navigateWebView(item.route, item.title)
}
.padding(top = 8.5.dp, bottom = 10.5.dp),
verticalAlignment = Alignment.CenterVertically,
.padding(top = 8.5.dp, bottom = 10.5.dp)
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.clip(CircleShape)
.size(32.dp)
.background(Colors.White10),
contentAlignment = Alignment.Center,
.background(Colors.White10)
) {
Icon(
imageVector = item.icon,
contentDescription = null,
tint = Colors.White64,
modifier = Modifier.size(16.dp),
modifier = Modifier.size(16.dp)
)
}
BodyM(
text = item.title,
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp),
.padding(horizontal = 8.dp)
)
Icon(
painter = painterResource(R.drawable.ic_chevron_right),
contentDescription = null,
tint = Colors.White64,
modifier = Modifier.size(24.dp),
modifier = Modifier.size(24.dp)
)
}
HorizontalDivider()
Expand All @@ -235,7 +215,9 @@ private fun ShopTabContent(

@SuppressLint("SetJavaScriptEnabled")
@Composable
private fun MapTabContent() {
private fun MapTabContent(
modifier: Modifier = Modifier,
) {
var isLoading by remember { mutableStateOf(true) }

val webViewClient = remember {
Expand All @@ -245,13 +227,12 @@ private fun MapTabContent() {
}

Box(
modifier = Modifier
.padding(top = 16.dp, start = 16.dp, end = 16.dp)
.clip(Shapes.medium),
contentAlignment = Alignment.Center,
modifier = modifier
.padding(top = 16.dp, start = 16.dp, end = 16.dp)
.clip(Shapes.medium)
) {
AndroidView(
modifier = Modifier.fillMaxWidth(),
factory = { context ->
WebView(context).apply {
layoutParams = ViewGroup.LayoutParams(
Expand All @@ -264,6 +245,7 @@ private fun MapTabContent() {
loadUrl(Env.BTC_MAP_URL)
}
},
modifier = Modifier.fillMaxWidth()
)

if (isLoading) {
Expand Down
Loading
Loading