diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt index 32e69dc413..efbc99093b 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt @@ -1,19 +1,11 @@ package com.tangem.features.feed.components.market.details import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.LifecycleStartEffect import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.arkivanov.decompose.ComponentContext @@ -27,32 +19,24 @@ import com.tangem.core.decompose.context.child import com.tangem.core.decompose.context.childByContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.DesignFeatureToggles -import com.tangem.core.ui.R import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState -import com.tangem.core.ui.components.haze.hazeEffectTangem import com.tangem.core.ui.decompose.ComposableBottomSheetComponent import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent -import com.tangem.core.ui.ds.topbar.TangemTopBar -import com.tangem.core.ui.ds.topbar.TangemTopBarType -import com.tangem.core.ui.extensions.clickableSingle import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled -import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.PreselectedTokenDetailsSection import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.models.currency.CryptoCurrency -import com.tangem.features.commonfeatures.api.managefunds.ManageFundsComponent import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent +import com.tangem.features.commonfeatures.api.managefunds.ManageFundsComponent import com.tangem.features.feed.components.market.details.portfolio.api.MarketsPortfolioComponent import com.tangem.features.feed.components.market.details.portfolioblock.PortfolioBlockComponent import com.tangem.features.feed.components.market.details.portfolioblock.PortfolioBlockParentClickIntents import com.tangem.features.feed.model.market.details.MarketsTokenDetailsModel import com.tangem.features.feed.model.market.details.analytics.MarketDetailsAnalyticsEvent import com.tangem.features.feed.model.market.details.state.TokenNetworksState -import com.tangem.features.feed.ui.LocalIsOpenedInBottomSheet import com.tangem.features.feed.ui.market.detailed.MarketsTokenDetailsContent -import com.tangem.features.feed.ui.market.detailed.MarketsTokenDetailsTopBar +import com.tangem.features.feed.ui.market.detailed.MarketsTokenDetailsTitle import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import kotlinx.serialization.Serializable @@ -187,58 +171,12 @@ internal class DefaultMarketsTokenDetailsComponent( @Composable override fun Title(bottomSheetState: State) { val state by model.state.collectAsStateWithLifecycle() - val background = LocalMainBottomSheetColor.current.value - if (LocalRedesignEnabled.current) { - TangemTopBar( - startContent = { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), - contentDescription = null, - tint = TangemTheme.colors2.graphic.neutral.primary, - modifier = Modifier - .size(TangemTheme.dimens2.x11) - .clip(CircleShape) - .hazeEffectTangem { blurRadius = 8.dp } - .clickableSingle( - onClick = { params.onBackClicked() }, - enabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ) - .padding(TangemTheme.dimens2.x2), - ) - }, - endContent = { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_share_new_24), - contentDescription = null, - tint = TangemTheme.colors2.graphic.neutral.primary, - modifier = Modifier - .size(TangemTheme.dimens2.x11) - .clip(CircleShape) - .hazeEffectTangem { blurRadius = 8.dp } - .clickableSingle( - onClick = state.onShareClick, - enabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ) - .padding(TangemTheme.dimens2.x2_5), - ) - }, - type = if (LocalIsOpenedInBottomSheet.current) { - TangemTopBarType.BottomSheet - } else { - TangemTopBarType.Default - }, - ) - } else { - MarketsTokenDetailsTopBar( - onBackClick = { params.onBackClicked() }, - isBackButtonEnabled = bottomSheetState.value == BottomSheetState.EXPANDED, - shouldShowPriceSubtitle = state.shouldShowPriceSubtitle, - tokenName = state.tokenName, - tokenPrice = state.priceText, - backgroundColor = background, - onShareClick = state.onShareClick, - ) - } + MarketsTokenDetailsTitle( + state = state, + backgroundColor = LocalMainBottomSheetColor.current.value, + isBackButtonEnabled = bottomSheetState.value == BottomSheetState.EXPANDED, + onBackClick = { params.onBackClicked() }, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt index b8b2361bed..a87365998c 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt @@ -289,6 +289,8 @@ internal class MarketsTokenDetailsModel @Inject constructor( onScroll = {}, ), onShareClick = ::onShareClick, + isAddToPortfolioButtonVisible = false, + onAddToPortfolioClick = ::openAddToPortfolio, ), ) @@ -344,6 +346,18 @@ internal class MarketsTokenDetailsModel @Inject constructor( } } } + if (isAddToPortfolioAvailable) { + addToPortfolioManager.setTokenParams(params.token) + addToPortfolioManager.state + .map { managerState -> + managerState is AddToPortfolioManager.State.Ready && managerState.isAvailableToAdd + } + .distinctUntilChanged() + .onEach { isVisible -> + state.update { it.copy(isAddToPortfolioButtonVisible = isVisible) } + } + .launchIn(modelScope) + } addToPortfolioManager.onDismiss.receiveAsFlow() .onEach { addToPortfolioSheetNavigation.dismiss() } .launchIn(modelScope) diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsTitle.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsTitle.kt new file mode 100644 index 0000000000..95f163f3dc --- /dev/null +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsTitle.kt @@ -0,0 +1,122 @@ +package com.tangem.features.feed.ui.market.detailed + +import androidx.compose.animation.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +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.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.R +import com.tangem.core.ui.components.haze.hazeEffectTangem +import com.tangem.core.ui.ds.topbar.TangemTopBar +import com.tangem.core.ui.ds.topbar.TangemTopBarType +import com.tangem.core.ui.extensions.clickableSingle +import com.tangem.core.ui.res.LocalRedesignEnabled +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.generated.icons.Icons +import com.tangem.core.ui.res.generated.icons.ic_sign_plus_24 +import com.tangem.features.feed.ui.LocalIsOpenedInBottomSheet +import com.tangem.features.feed.ui.market.detailed.state.MarketsTokenDetailsUM + +@Composable +internal fun MarketsTokenDetailsTitle( + state: MarketsTokenDetailsUM, + backgroundColor: Color, + isBackButtonEnabled: Boolean, + onBackClick: () -> Unit, +) { + if (LocalRedesignEnabled.current) { + MarketsTokenDetailsRedesignTopBar( + isAddToPortfolioButtonVisible = state.isAddToPortfolioButtonVisible, + onAddToPortfolioClick = state.onAddToPortfolioClick, + onShareClick = state.onShareClick, + isBackButtonEnabled = isBackButtonEnabled, + onBackClick = onBackClick, + ) + } else { + MarketsTokenDetailsTopBar( + onBackClick = onBackClick, + isBackButtonEnabled = isBackButtonEnabled, + shouldShowPriceSubtitle = state.shouldShowPriceSubtitle, + tokenName = state.tokenName, + tokenPrice = state.priceText, + backgroundColor = backgroundColor, + onShareClick = state.onShareClick, + ) + } +} + +@Composable +private fun MarketsTokenDetailsRedesignTopBar( + isAddToPortfolioButtonVisible: Boolean, + onAddToPortfolioClick: () -> Unit, + onShareClick: () -> Unit, + isBackButtonEnabled: Boolean, + onBackClick: () -> Unit, +) { + TangemTopBar( + startContent = { + TopBarHazeIconButton( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), + onClick = onBackClick, + enabled = isBackButtonEnabled, + contentPadding = TangemTheme.dimens2.x2, + ) + }, + endContent = { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + AnimatedVisibility( + visible = isAddToPortfolioButtonVisible, + enter = fadeIn() + scaleIn(), + exit = fadeOut() + scaleOut(), + ) { + TopBarHazeIconButton( + imageVector = Icons.ic_sign_plus_24, + onClick = onAddToPortfolioClick, + enabled = isBackButtonEnabled, + contentPadding = TangemTheme.dimens2.x2_5, + ) + } + TopBarHazeIconButton( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_share_new_24), + onClick = onShareClick, + enabled = isBackButtonEnabled, + contentPadding = TangemTheme.dimens2.x2_5, + ) + } + }, + type = if (LocalIsOpenedInBottomSheet.current) { + TangemTopBarType.BottomSheet + } else { + TangemTopBarType.Default + }, + ) +} + +@Composable +private fun TopBarHazeIconButton(imageVector: ImageVector, onClick: () -> Unit, enabled: Boolean, contentPadding: Dp) { + Icon( + imageVector = imageVector, + contentDescription = null, + tint = TangemTheme.colors2.graphic.neutral.primary, + modifier = Modifier + .size(TangemTheme.dimens2.x11) + .clip(CircleShape) + .hazeEffectTangem { blurRadius = 8.dp } + .clickableSingle(onClick = onClick, enabled = enabled) + .padding(contentPadding), + ) +} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/preview/MarketsTokenDetailsPreview.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/preview/MarketsTokenDetailsPreview.kt index c73cfa497c..c36104bfdc 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/preview/MarketsTokenDetailsPreview.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/preview/MarketsTokenDetailsPreview.kt @@ -51,6 +51,8 @@ internal object MarketsTokenDetailsPreview { onScroll = {}, ), onShareClick = {}, + isAddToPortfolioButtonVisible = false, + onAddToPortfolioClick = {}, priceAnnotated = stringReference("$0.00000000324"), ) @@ -147,6 +149,8 @@ internal object MarketsTokenDetailsPreview { onScroll = {}, ), onShareClick = {}, + isAddToPortfolioButtonVisible = false, + onAddToPortfolioClick = {}, priceAnnotated = stringReference("$0.00000000324"), ) } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MarketsTokenDetailsUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MarketsTokenDetailsUM.kt index a9e4a602a4..08786be8d9 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MarketsTokenDetailsUM.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MarketsTokenDetailsUM.kt @@ -32,6 +32,8 @@ internal data class MarketsTokenDetailsUM( val onShouldShowPriceSubtitleChange: (Boolean) -> Unit, val relatedNews: RelatedNews, val onShareClick: () -> Unit, + val isAddToPortfolioButtonVisible: Boolean, + val onAddToPortfolioClick: () -> Unit, val scrollToSection: StateEvent = consumedEvent(), ) {