diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt index f535f5d114..bc2443bc0e 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt @@ -261,6 +261,10 @@ internal object WalletPreviewData { ), ), ), + pullToRefreshConfig = WalletPullToRefreshConfig( + isRefreshing = false, + onRefresh = {}, + ), notifications = persistentListOf( WalletNotification.UnreachableNetworks, WalletNotification.LikeTangemApp(onClick = {}), @@ -293,6 +297,10 @@ internal object WalletPreviewData { ), ), ), + pullToRefreshConfig = WalletPullToRefreshConfig( + isRefreshing = false, + onRefresh = {}, + ), notifications = persistentListOf(WalletNotification.LikeTangemApp(onClick = {})), buttons = manageButtons.map(WalletManageButton::config).toPersistentList(), marketPriceBlockState = MarketPriceBlockState.Content( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletPullToRefreshConfig.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletPullToRefreshConfig.kt new file mode 100644 index 0000000000..8aafa384f0 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletPullToRefreshConfig.kt @@ -0,0 +1,9 @@ +package com.tangem.feature.wallet.presentation.wallet.state + +/** + * Wallet screen top bar config + * + * @property isRefreshing state is indicator visible + * @property onRefresh lambda be invoked when pulled to refresh + */ +data class WalletPullToRefreshConfig(val isRefreshing: Boolean, val onRefresh: () -> Unit) \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt index 12fb96d14e..c4b9c37ee8 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt @@ -7,11 +7,12 @@ import kotlinx.collections.immutable.ImmutableList /** * Wallet screen state holder * - * @property onBackClick lambda be invoked when back button is clicked - * @property topBarConfig top bar config - * @property walletsListConfig wallets list config - * @property contentItems content items - * @property notifications notifications + * @property onBackClick lambda be invoked when back button is clicked + * @property topBarConfig top bar config + * @property walletsListConfig wallets list config + * @property pullToRefreshConfig pull to refresh config + * @property contentItems content items + * @property notifications notifications * [REDACTED_AUTHOR] */ @@ -19,6 +20,7 @@ internal sealed class WalletStateHolder( open val onBackClick: () -> Unit, open val topBarConfig: WalletTopBarConfig, open val walletsListConfig: WalletsListConfig, + open val pullToRefreshConfig: WalletPullToRefreshConfig, open val contentItems: ImmutableList, open val notifications: ImmutableList, ) { @@ -26,40 +28,58 @@ internal sealed class WalletStateHolder( /** * Multi currency wallet content state * - * @property onBackClick lambda be invoked when back button is clicked - * @property topBarConfig top bar config - * @property walletsListConfig wallets list config - * @property contentItems content items - * @property notifications notifications - * @property onOrganizeTokensClick lambda be invoked when organize tokens button is clicked + * @property onBackClick lambda be invoked when back button is clicked + * @property topBarConfig top bar config + * @property walletsListConfig wallets list config + * @property pullToRefreshConfig pull to refresh config + * @property contentItems content items + * @property notifications notifications + * @property onOrganizeTokensClick lambda be invoked when organize tokens button is clicked */ data class MultiCurrencyContent( override val onBackClick: () -> Unit, override val topBarConfig: WalletTopBarConfig, override val walletsListConfig: WalletsListConfig, + override val pullToRefreshConfig: WalletPullToRefreshConfig, override val contentItems: ImmutableList, override val notifications: ImmutableList, val onOrganizeTokensClick: () -> Unit, - ) : WalletStateHolder(onBackClick, topBarConfig, walletsListConfig, contentItems, notifications) + ) : WalletStateHolder( + onBackClick = onBackClick, + topBarConfig = topBarConfig, + walletsListConfig = walletsListConfig, + pullToRefreshConfig = pullToRefreshConfig, + contentItems = contentItems, + notifications = notifications, + ) /** * Single currency wallet content state * - * @property onBackClick lambda be invoked when back button is clicked - * @property topBarConfig top bar config - * @property walletsListConfig wallets list config - * @property contentItems content items - * @property notifications notifications - * @property buttons manage buttons - * @property marketPriceBlockState market price block state + * @property onBackClick lambda be invoked when back button is clicked + * @property topBarConfig top bar config + * @property walletsListConfig wallets list config + * @property pullToRefreshConfig pull to refresh config + * @property contentItems content items + * @property notifications notifications + * @property buttons manage buttons + * @property marketPriceBlockState market price block state */ data class SingleCurrencyContent( override val onBackClick: () -> Unit, override val topBarConfig: WalletTopBarConfig, override val walletsListConfig: WalletsListConfig, + override val pullToRefreshConfig: WalletPullToRefreshConfig, override val contentItems: ImmutableList, override val notifications: ImmutableList, val buttons: ImmutableList, val marketPriceBlockState: MarketPriceBlockState, - ) : WalletStateHolder(onBackClick, topBarConfig, walletsListConfig, contentItems, notifications) + ) : WalletStateHolder( + onBackClick = onBackClick, + topBarConfig = topBarConfig, + walletsListConfig = walletsListConfig, + pullToRefreshConfig = pullToRefreshConfig, + contentItems = contentItems, + notifications = notifications, + ) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt index e281fb492e..42f5485b26 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt @@ -8,6 +8,10 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -44,6 +48,7 @@ import com.tangem.feature.wallet.presentation.wallet.ui.utils.changeWalletAnimat * [REDACTED_AUTHOR] */ +@OptIn(ExperimentalMaterialApi::class) @Suppress("LongMethod") @Composable internal fun WalletScreen(state: WalletStateHolder) { @@ -56,88 +61,102 @@ internal fun WalletScreen(state: WalletStateHolder) { val walletsListState = rememberLazyListState() val changeableItemModifier = Modifier.changeWalletAnimator(walletsListState) + val pullRefreshState = rememberPullRefreshState( + refreshing = state.pullToRefreshConfig.isRefreshing, + onRefresh = state.pullToRefreshConfig.onRefresh, + ) - LazyColumn( + Box( modifier = Modifier .padding(paddingValues = scaffoldPaddings) - .fillMaxSize(), - contentPadding = PaddingValues(vertical = TangemTheme.dimens.spacing8), - horizontalAlignment = Alignment.CenterHorizontally, + .pullRefresh(pullRefreshState), ) { - item { - WalletsList( - config = state.walletsListConfig, - lazyListState = walletsListState, - ) - } - - if (state is WalletStateHolder.SingleCurrencyContent) { + LazyColumn( + modifier = Modifier.fillMaxSize(), + contentPadding = PaddingValues(vertical = TangemTheme.dimens.spacing8), + horizontalAlignment = Alignment.CenterHorizontally, + ) { item { - HorizontalActionChips( - buttons = state.buttons, - modifier = changeableItemModifier - .padding(top = TangemTheme.dimens.spacing14), - contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing16), + WalletsList( + config = state.walletsListConfig, + lazyListState = walletsListState, ) } - } - items( - items = state.notifications, - itemContent = { item -> - Notification( - state = item.state, - modifier = changeableItemModifier - .padding(top = TangemTheme.dimens.spacing14) - .padding(horizontal = TangemTheme.dimens.spacing16), - ) - }, - ) - - if (state is WalletStateHolder.SingleCurrencyContent) { - item { - MarketPriceBlock( - state = state.marketPriceBlockState, - modifier = changeableItemModifier - .padding(top = TangemTheme.dimens.spacing14) - .padding(horizontal = TangemTheme.dimens.spacing16), - ) - } - } - - itemsIndexed( - items = state.contentItems, - key = { index, item -> - when (item) { - is WalletContentItemState.MultiCurrencyItem.NetworkGroupTitle -> item.networkName - is WalletContentItemState.MultiCurrencyItem.Token -> index - is WalletContentItemState.SingleCurrencyItem.Title -> index - is WalletContentItemState.SingleCurrencyItem.GroupTitle -> item.title - is WalletContentItemState.SingleCurrencyItem.Transaction -> index - is WalletContentItemState.Loading -> index + if (state is WalletStateHolder.SingleCurrencyContent) { + item { + HorizontalActionChips( + buttons = state.buttons, + modifier = changeableItemModifier + .padding(top = TangemTheme.dimens.spacing14), + contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing16), + ) } - }, - itemContent = { index, item -> - ContentItem( - item = item, - modifier = changeableItemModifier.walletContentItemDecoration( - currentIndex = index, - lastIndex = state.contentItems.lastIndex, - ), - ) - }, - ) + } - if (state is WalletStateHolder.MultiCurrencyContent) { - item { - OrganizeTokensButton( - onClick = state.onOrganizeTokensClick, - modifier = changeableItemModifier - .padding(top = TangemTheme.dimens.spacing14) - .padding(horizontal = TangemTheme.dimens.spacing16), - ) + items( + items = state.notifications, + itemContent = { item -> + Notification( + state = item.state, + modifier = changeableItemModifier + .padding(top = TangemTheme.dimens.spacing14) + .padding(horizontal = TangemTheme.dimens.spacing16), + ) + }, + ) + + if (state is WalletStateHolder.SingleCurrencyContent) { + item { + MarketPriceBlock( + state = state.marketPriceBlockState, + modifier = changeableItemModifier + .padding(top = TangemTheme.dimens.spacing14) + .padding(horizontal = TangemTheme.dimens.spacing16), + ) + } + } + + itemsIndexed( + items = state.contentItems, + key = { index, item -> + when (item) { + is WalletContentItemState.MultiCurrencyItem.NetworkGroupTitle -> item.networkName + is WalletContentItemState.MultiCurrencyItem.Token -> index + is WalletContentItemState.SingleCurrencyItem.Title -> index + is WalletContentItemState.SingleCurrencyItem.GroupTitle -> item.title + is WalletContentItemState.SingleCurrencyItem.Transaction -> index + is WalletContentItemState.Loading -> index + } + }, + itemContent = { index, item -> + ContentItem( + item = item, + modifier = changeableItemModifier.walletContentItemDecoration( + currentIndex = index, + lastIndex = state.contentItems.lastIndex, + ), + ) + }, + ) + + if (state is WalletStateHolder.MultiCurrencyContent) { + item { + OrganizeTokensButton( + onClick = state.onOrganizeTokensClick, + modifier = changeableItemModifier + .padding(top = TangemTheme.dimens.spacing14) + .padding(horizontal = TangemTheme.dimens.spacing16), + ) + } } } + + PullRefreshIndicator( + refreshing = state.pullToRefreshConfig.isRefreshing, + state = pullRefreshState, + modifier = Modifier.align(Alignment.TopCenter), + ) } } }