From 1707a044135f37907220de5d5859db9564c3fccb Mon Sep 17 00:00:00 2001 From: Rafael Date: Thu, 26 Dec 2024 15:48:35 +0600 Subject: [PATCH] Change scrolling part for premium features list --- .../ui/SelectSubscriptionScreen.kt | 248 ++++++++++++------ .../modules/usersubscription/ui/UiElements.kt | 87 +----- 2 files changed, 177 insertions(+), 158 deletions(-) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/usersubscription/ui/SelectSubscriptionScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/usersubscription/ui/SelectSubscriptionScreen.kt index b7811fb49f..ef15af0657 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/usersubscription/ui/SelectSubscriptionScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/usersubscription/ui/SelectSubscriptionScreen.kt @@ -1,16 +1,33 @@ package io.horizontalsystems.bankwallet.modules.usersubscription.ui +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +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.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll +import androidx.compose.material.Icon import androidx.compose.material.Scaffold +import androidx.compose.material.Tab +import androidx.compose.material.TabRow +import androidx.compose.material.TabRowDefaults +import androidx.compose.material.TabRowDefaults.tabIndicatorOffset +import androidx.compose.material.Text import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.SheetState import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -18,7 +35,10 @@ import androidx.compose.runtime.rememberCoroutineScope 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.platform.LocalContext +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -32,6 +52,7 @@ import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.components.RadialBackground import io.horizontalsystems.bankwallet.ui.compose.components.VSpacer import io.horizontalsystems.bankwallet.ui.compose.components.body_grey +import io.horizontalsystems.subscriptions.core.Subscription import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @@ -45,7 +66,6 @@ fun SelectSubscriptionScreen( } val uiState = viewModel.uiState - val subscriptions = uiState.subscriptions val coroutineScope = rememberCoroutineScope() @@ -53,6 +73,8 @@ fun SelectSubscriptionScreen( val modalBottomSheetState = androidx.compose.material3.rememberModalBottomSheetState(skipPartiallyExpanded = true) var isBottomSheetVisible by remember { mutableStateOf(false) } + val scrollScope = rememberCoroutineScope() + val pagerState = rememberPagerState(initialPage = selectedTabIndex.value) { 2 } Scaffold( backgroundColor = ComposeAppTheme.colors.tyler, @@ -70,90 +92,170 @@ fun SelectSubscriptionScreen( ) { RadialBackground() Column { + VSpacer(12.dp) + body_grey( + text = stringResource(R.string.Premium_ChoosePlanForYou), + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) + VSpacer(24.dp) Column( modifier = Modifier - .padding(paddingValues) - .weight(1f) - .verticalScroll(rememberScrollState()) - ) - { - VSpacer(12.dp) - body_grey( - text = stringResource(R.string.Premium_ChoosePlanForYou), - modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Center + .padding(horizontal = 16.dp) + .clip(RoundedCornerShape(12.dp)), + ) { + SubscriptionTabs( + subscriptions = subscriptions, + selectedTabIndex = selectedTabIndex, + onTabSelected = { + scrollScope.launch { + pagerState.scrollToPage(it) + } + } ) - VSpacer(24.dp) - if (subscriptions.isNotEmpty()) { - PlanTabs( - items = subscriptions, - selectedTabIndex = selectedTabIndex.value, - onTabChange = { index -> - selectedTabIndex.value = index + Column( + modifier = Modifier + .padding(paddingValues) + .weight(1f) + .verticalScroll(rememberScrollState()) + ) { + if (subscriptions.isNotEmpty()) { + HorizontalPager( + state = pagerState, + userScrollEnabled = false + ) { page -> + PlanItems(subscriptions[page].actions) } - ) - VSpacer(32.dp) + VSpacer(32.dp) + } } - } - ButtonsGroupWithShade { - Column( - modifier = Modifier.padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - ButtonPrimaryCustomColor( - modifier = Modifier.fillMaxWidth(), - title = stringResource(R.string.Premium_TryForFree), - brush = yellowGradient, - onClick = { - coroutineScope.launch { - isBottomSheetVisible = true - modalBottomSheetState.show() - } - }, - ) - VSpacer(12.dp) - ColoredTextSecondaryButton( - title = stringResource(R.string.Premium_Restore), - onClick = { - // - }, - color = ComposeAppTheme.colors.leah - ) + ButtonsGroupWithShade { + Column( + modifier = Modifier.padding(horizontal = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + ButtonPrimaryCustomColor( + modifier = Modifier.fillMaxWidth(), + title = stringResource(R.string.Premium_TryForFree), + brush = yellowGradient, + onClick = { + coroutineScope.launch { + isBottomSheetVisible = true + modalBottomSheetState.show() + } + }, + ) + VSpacer(12.dp) + ColoredTextSecondaryButton( + title = stringResource(R.string.Premium_Restore), + onClick = { + // + }, + color = ComposeAppTheme.colors.leah + ) + } } } } + if (isBottomSheetVisible) { + SubscriptionBottomSheet( + modalBottomSheetState = modalBottomSheetState, + subscriptions = subscriptions, + selectedTabIndex = selectedTabIndex, + navController = navController, + hideBottomSheet = { + coroutineScope.launch { + modalBottomSheetState.hide() + } + isBottomSheetVisible = false + } + ) + } + } + } +} + +@Composable +@OptIn(ExperimentalMaterial3Api::class) +private fun SubscriptionBottomSheet( + modalBottomSheetState: SheetState, + subscriptions: List, + selectedTabIndex: MutableState, + navController: NavController, + hideBottomSheet: () -> Unit +) { + ModalBottomSheet( + onDismissRequest = hideBottomSheet, + sheetState = modalBottomSheetState, + containerColor = ComposeAppTheme.colors.transparent + ) { + if (subscriptions.isNotEmpty()) { + SelectSubscriptionBottomSheet( + subscriptionId = subscriptions[selectedTabIndex.value].id, + type = PremiumPlanType.entries[selectedTabIndex.value], + onDismiss = hideBottomSheet, + onSubscribeClick = { type -> + hideBottomSheet() + navController.navigate("premium_subscribed_page?type=${type.name}") + } + ) } - if (isBottomSheetVisible) { - ModalBottomSheet( - onDismissRequest = { - coroutineScope.launch { - modalBottomSheetState.hide() + } +} + +@Composable +private fun SubscriptionTabs( + subscriptions: List, + selectedTabIndex: MutableState, + onTabSelected: (Int) -> Unit = {} +) { + if (subscriptions.isNotEmpty()) { + TabRow( + selectedTabIndex = selectedTabIndex.value, + backgroundColor = ComposeAppTheme.colors.transparent, // Dark background + contentColor = Color(0xFFEDD716), + indicator = { tabPositions -> + TabRowDefaults.Indicator( + Modifier + .tabIndicatorOffset(tabPositions[selectedTabIndex.value]) + .height(0.dp), // No indicator line + color = Color.Transparent + ) + } + ) { + subscriptions.forEachIndexed { index, tab -> + Tab( + selected = selectedTabIndex.value == index, + onClick = { + selectedTabIndex.value = index + onTabSelected(index) + }, + modifier = Modifier.background( + brush = + if (selectedTabIndex.value == index) yellowGradient else steelBrush, + ), + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .height(44.dp) + .padding(vertical = 8.dp, horizontal = 16.dp) + ) { + Icon( + painter = painterResource(if (index == 0) R.drawable.prem_star_yellow_16 else R.drawable.prem_crown_yellow_16), + contentDescription = null, + tint = if (selectedTabIndex.value == index) ComposeAppTheme.colors.dark else ComposeAppTheme.colors.jacob, + modifier = Modifier.size(18.dp) + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = tab.name, + color = if (selectedTabIndex.value == index) ComposeAppTheme.colors.dark else ComposeAppTheme.colors.grey, + style = ComposeAppTheme.typography.captionSB + ) } - isBottomSheetVisible = false - }, - sheetState = modalBottomSheetState, - containerColor = ComposeAppTheme.colors.transparent - ) { - if (subscriptions.isNotEmpty()) { - SelectSubscriptionBottomSheet( - subscriptionId = subscriptions[selectedTabIndex.value].id, - type = PremiumPlanType.entries[selectedTabIndex.value], - onDismiss = { - coroutineScope.launch { - modalBottomSheetState.hide() - isBottomSheetVisible = false - } - }, - onSubscribeClick = { type -> - coroutineScope.launch { - modalBottomSheetState.hide() - isBottomSheetVisible = false - navController.navigate("premium_subscribed_page?type=${type.name}") - } - } - ) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/usersubscription/ui/UiElements.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/usersubscription/ui/UiElements.kt index fbe3b47c6c..35cef5ea63 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/usersubscription/ui/UiElements.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/usersubscription/ui/UiElements.kt @@ -16,24 +16,17 @@ 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.pager.HorizontalPager -import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Divider import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon import androidx.compose.material.ProvideTextStyle import androidx.compose.material.Surface -import androidx.compose.material.Tab -import androidx.compose.material.TabRow -import androidx.compose.material.TabRowDefaults -import androidx.compose.material.TabRowDefaults.tabIndicatorOffset import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -73,10 +66,8 @@ import io.horizontalsystems.bankwallet.ui.compose.components.subhead2_jacob import io.horizontalsystems.bankwallet.ui.compose.components.subhead2_remus import io.horizontalsystems.bankwallet.ui.extensions.BottomSheetHeader import io.horizontalsystems.subscriptions.core.IPaidAction -import io.horizontalsystems.subscriptions.core.Subscription import io.horizontalsystems.subscriptions.core.VIPClub import io.horizontalsystems.subscriptions.core.VIPSupport -import kotlinx.coroutines.launch enum class PremiumPlanType(@StringRes val titleResId: Int) { ProPlan(R.string.Premium_PlanPro), @@ -90,7 +81,7 @@ val yellowGradient = Brush.horizontalGradient( ) ) -private val steelBrush = Brush.horizontalGradient( +val steelBrush = Brush.horizontalGradient( colors = listOf(Steel20, Steel20) ) @@ -227,81 +218,7 @@ fun SubscriptionOption( } @Composable -fun PlanTabs( - items: List, - selectedTabIndex: Int, - onTabChange: (Int) -> Unit -) { - - val pagerState = rememberPagerState(initialPage = selectedTabIndex) { 2 } - val scrollScope = rememberCoroutineScope() - - Column( - modifier = Modifier - .padding(horizontal = 16.dp) - .clip(RoundedCornerShape(12.dp)), - ) { - TabRow( - selectedTabIndex = selectedTabIndex, - backgroundColor = ComposeAppTheme.colors.transparent, // Dark background - contentColor = Color(0xFFEDD716), - indicator = { tabPositions -> - TabRowDefaults.Indicator( - Modifier - .tabIndicatorOffset(tabPositions[selectedTabIndex]) - .height(0.dp), // No indicator line - color = Color.Transparent - ) - } - ) { - items.forEachIndexed { index, tab -> - Tab( - selected = selectedTabIndex == index, - onClick = { - onTabChange(index) - scrollScope.launch { - pagerState.scrollToPage(index) - } - }, - modifier = Modifier.background( - brush = - if (selectedTabIndex == index) yellowGradient else steelBrush, - ), - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .height(44.dp) - .padding(vertical = 8.dp, horizontal = 16.dp) - ) { - Icon( - painter = painterResource(if (index == 0) R.drawable.prem_star_yellow_16 else R.drawable.prem_crown_yellow_16), - contentDescription = null, - tint = if (selectedTabIndex == index) ComposeAppTheme.colors.dark else ComposeAppTheme.colors.jacob, - modifier = Modifier.size(18.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = tab.name, - color = if (selectedTabIndex == index) ComposeAppTheme.colors.dark else ComposeAppTheme.colors.grey, - style = ComposeAppTheme.typography.captionSB - ) - } - } - } - } - - HorizontalPager( - state = pagerState, - userScrollEnabled = false - ) { page -> - PlanItems(items[page].actions) - } - } -} - -@Composable -private fun PlanItems(items: List) { +fun PlanItems(items: List) { Column { items.forEachIndexed { index, item -> PremiumFeatureItem(