Updated on 2026-08-14
This commit is contained in:
parent
3a754e96a6
commit
34609aeb8c
10 changed files with 123 additions and 38 deletions
|
|
@ -26,6 +26,8 @@ import com.tangem.core.ui.R
|
|||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
/**
|
||||
* A top bar composable that displays a title and optional start and end icons.
|
||||
|
|
@ -34,8 +36,8 @@ import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
|||
* @param title The title text to be displayed in the center of the top bar.
|
||||
* @param modifier Modifier to be applied to the top bar.
|
||||
* @param subtitle Optional subtitle text to be displayed below the title.
|
||||
* @param startActionUM Optional action data for the start action icon.
|
||||
* @param endActionUM Optional action data for the end action icon.
|
||||
* @param startAction Optional action data for the start action icon.
|
||||
* @param endActions List of end action icons to display on the right side.
|
||||
* @param titleIconRes Optional drawable resource ID for the icon to be displayed next to the title.
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -45,8 +47,8 @@ fun TangemTopBar(
|
|||
modifier: Modifier = Modifier,
|
||||
title: TextReference? = null,
|
||||
subtitle: TextReference? = null,
|
||||
startActionUM: TangemTopBarActionUM? = null,
|
||||
endActionUM: TangemTopBarActionUM? = null,
|
||||
startAction: TangemTopBarActionUM? = null,
|
||||
endActions: ImmutableList<TangemTopBarActionUM> = persistentListOf(),
|
||||
@DrawableRes titleIconRes: Int? = null,
|
||||
) {
|
||||
TangemTopBar(
|
||||
|
|
@ -54,13 +56,19 @@ fun TangemTopBar(
|
|||
subtitle = subtitle,
|
||||
titleIconRes = titleIconRes,
|
||||
modifier = modifier,
|
||||
startContent = if (startActionUM != null) {
|
||||
{ TangemTopBarActionContent(startActionUM) }
|
||||
startContent = if (startAction != null) {
|
||||
{ TangemTopBarActionContent(startAction) }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
endContent = if (endActionUM != null) {
|
||||
{ TangemTopBarActionContent(endActionUM) }
|
||||
endContent = if (endActions.isNotEmpty()) {
|
||||
{
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1)) {
|
||||
endActions.forEach { action ->
|
||||
TangemTopBarActionContent(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
null
|
||||
},
|
||||
|
|
@ -215,7 +223,17 @@ private fun TangemTopBar_Preview(@PreviewParameter(PreviewProvider::class) param
|
|||
titleIconRes = params.titleIconRes,
|
||||
modifier = Modifier.background(TangemTheme.colors2.surface.level1),
|
||||
startContent = params.startActionUM?.let { { TangemTopBarActionContent(it) } },
|
||||
endContent = params.endActionUM?.let { { TangemTopBarActionContent(it) } },
|
||||
endContent = if (params.endActions.isNotEmpty()) {
|
||||
{
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1)) {
|
||||
params.endActions.forEach { action ->
|
||||
TangemTopBarActionContent(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +243,7 @@ private class TangemTopBarPreviewData(
|
|||
val subtitle: TextReference? = null,
|
||||
val titleIconRes: Int? = null,
|
||||
val startActionUM: TangemTopBarActionUM? = null,
|
||||
val endActionUM: TangemTopBarActionUM? = null,
|
||||
val endActions: ImmutableList<TangemTopBarActionUM> = persistentListOf(),
|
||||
)
|
||||
|
||||
private class PreviewProvider : PreviewParameterProvider<TangemTopBarPreviewData> {
|
||||
|
|
@ -238,11 +256,11 @@ private class PreviewProvider : PreviewParameterProvider<TangemTopBarPreviewData
|
|||
onClick = {},
|
||||
isActionable = false,
|
||||
),
|
||||
endActionUM = TangemTopBarActionUM(
|
||||
endActions = persistentListOf(TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_more_default_24,
|
||||
onClick = {},
|
||||
isActionable = false,
|
||||
),
|
||||
)),
|
||||
),
|
||||
TangemTopBarPreviewData(
|
||||
title = stringReference("Title"),
|
||||
|
|
@ -253,12 +271,12 @@ private class PreviewProvider : PreviewParameterProvider<TangemTopBarPreviewData
|
|||
isActionable = true,
|
||||
ghostModeProgress = 1f,
|
||||
),
|
||||
endActionUM = TangemTopBarActionUM(
|
||||
endActions = persistentListOf(TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_more_default_24,
|
||||
onClick = {},
|
||||
isActionable = true,
|
||||
ghostModeProgress = 1f,
|
||||
),
|
||||
)),
|
||||
),
|
||||
TangemTopBarPreviewData(
|
||||
title = stringReference("Title"),
|
||||
|
|
@ -269,12 +287,12 @@ private class PreviewProvider : PreviewParameterProvider<TangemTopBarPreviewData
|
|||
onClick = {},
|
||||
isActionable = false,
|
||||
),
|
||||
endActionUM = TangemTopBarActionUM(
|
||||
endActions = persistentListOf(TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_more_default_24,
|
||||
onClick = {},
|
||||
isActionable = true,
|
||||
ghostModeProgress = 1f,
|
||||
),
|
||||
)),
|
||||
),
|
||||
TangemTopBarPreviewData(
|
||||
subtitle = stringReference("Subtitle"),
|
||||
|
|
@ -284,19 +302,19 @@ private class PreviewProvider : PreviewParameterProvider<TangemTopBarPreviewData
|
|||
onClick = {},
|
||||
isActionable = true,
|
||||
),
|
||||
endActionUM = TangemTopBarActionUM(
|
||||
endActions = persistentListOf(TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_more_default_24,
|
||||
onClick = {},
|
||||
isActionable = false,
|
||||
),
|
||||
)),
|
||||
),
|
||||
TangemTopBarPreviewData(
|
||||
title = stringReference("Title"),
|
||||
endActionUM = TangemTopBarActionUM(
|
||||
endActions = persistentListOf(TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_more_default_24,
|
||||
onClick = {},
|
||||
isActionable = false,
|
||||
),
|
||||
)),
|
||||
),
|
||||
TangemTopBarPreviewData(
|
||||
title = stringReference("Title"),
|
||||
|
|
@ -335,11 +353,11 @@ private class PreviewProvider : PreviewParameterProvider<TangemTopBarPreviewData
|
|||
onClick = {},
|
||||
isActionable = true,
|
||||
),
|
||||
endActionUM = TangemTopBarActionUM(
|
||||
endActions = persistentListOf(TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_more_default_24,
|
||||
onClick = {},
|
||||
isActionable = false,
|
||||
),
|
||||
)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import com.tangem.feature.wallet.presentation.wallet.utils.ScreenLifecycleProvid
|
|||
import com.tangem.features.biometry.AskBiometryComponent
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks
|
||||
import com.tangem.features.wallet.deeplink.WalletDeepLinkActionListener
|
||||
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.*
|
||||
import kotlinx.coroutines.*
|
||||
|
|
@ -102,6 +103,7 @@ internal class WalletModel @Inject constructor(
|
|||
private val appsFlyerStore: AppsFlyerStore,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getWalletIconUseCase: GetWalletIconUseCase,
|
||||
private val walletFeatureToggles: WalletFeatureToggles,
|
||||
val screenLifecycleProvider: ScreenLifecycleProvider,
|
||||
val innerWalletRouter: InnerWalletRouter,
|
||||
) : Model() {
|
||||
|
|
@ -522,6 +524,7 @@ internal class WalletModel @Inject constructor(
|
|||
wallets = action.wallets,
|
||||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
isMainScreenQrScanningEnabled = walletFeatureToggles.isMainScreenQrScanningEnabled,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -82,9 +82,11 @@ internal interface WalletContentClickIntents {
|
|||
fun onDisposeExpressStatus()
|
||||
|
||||
fun onNFTClick(userWallet: UserWallet)
|
||||
|
||||
fun onScanQrClick()
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
@Suppress("LongParameterList", "LargeClass", "TooManyFunctions")
|
||||
@ModelScoped
|
||||
internal class WalletContentClickIntentsImplementor @Inject constructor(
|
||||
private val stateHolder: WalletStateController,
|
||||
|
|
@ -369,4 +371,8 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
|
||||
router.openNFT(userWallet)
|
||||
}
|
||||
|
||||
override fun onScanQrClick() {
|
||||
router.openQrScanner()
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
@Suppress("LargeClass")
|
||||
internal object WalletPreviewDataLegacy {
|
||||
|
||||
val topBarConfig by lazy { WalletTopBarConfig(onDetailsClick = {}) }
|
||||
val topBarConfig by lazy { WalletTopBarConfig() }
|
||||
|
||||
val walletCardContentState by lazy {
|
||||
WalletCardState.Content(
|
||||
|
|
|
|||
|
|
@ -161,4 +161,8 @@ internal class DefaultWalletRouter @Inject constructor(
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun openQrScanner() {
|
||||
router.push(AppRoute.QrScanning(source = AppRoute.QrScanning.Source.MainScreen))
|
||||
}
|
||||
}
|
||||
|
|
@ -86,4 +86,7 @@ internal interface InnerWalletRouter {
|
|||
|
||||
/** Open token action sheet */
|
||||
fun openTokenActionSheet(userWallet: UserWallet, tokenActionList: ImmutableList<TokenActionButtonUM>)
|
||||
|
||||
/** Open QR scanner screen */
|
||||
fun openQrScanner()
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ internal class WalletStateController @Inject constructor(
|
|||
|
||||
private fun getInitialState(): WalletScreenState {
|
||||
return WalletScreenState(
|
||||
topBarConfig = WalletTopBarConfig(onDetailsClick = {}),
|
||||
topBarConfig = WalletTopBarConfig(),
|
||||
selectedWalletIndex = NOT_INITIALIZED_WALLET_INDEX,
|
||||
wallets = persistentListOf(),
|
||||
wallets2 = persistentListOf(),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.model
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.ds.topbar.TangemTopBarActionUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
/**
|
||||
* Wallet screen top bar config
|
||||
*
|
||||
* @property onDetailsClick lambda be invoked when details button is clicked
|
||||
* @property endActions list of top bar end action buttons (e.g. QR scan, More)
|
||||
*/
|
||||
internal data class WalletTopBarConfig(val onDetailsClick: () -> Unit)
|
||||
@Immutable
|
||||
internal data class WalletTopBarConfig(
|
||||
val endActions: ImmutableList<TangemTopBarActionUM> = persistentListOf(),
|
||||
)
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.core.ui.R as CoreUiR
|
||||
import com.tangem.common.ui.userwallet.converter.WalletIconUMConverter
|
||||
import com.tangem.core.ui.ds.button.TangemButtonUM
|
||||
import com.tangem.core.ui.ds.topbar.TangemTopBarActionUM
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.isLocked
|
||||
|
|
@ -25,6 +27,7 @@ internal class InitializeWalletsTransformer(
|
|||
private val clickIntents: WalletClickIntents,
|
||||
private val walletImageResolver: WalletImageResolver,
|
||||
private val getWalletIconUseCase: GetWalletIconUseCase,
|
||||
private val isMainScreenQrScanningEnabled: Boolean = false,
|
||||
) : WalletScreenStateTransformer {
|
||||
|
||||
private val walletLoadingStateFactory by lazy {
|
||||
|
|
@ -60,7 +63,20 @@ internal class InitializeWalletsTransformer(
|
|||
|
||||
private fun createTopBarConfig(): WalletTopBarConfig {
|
||||
return WalletTopBarConfig(
|
||||
onDetailsClick = clickIntents::onDetailsClick,
|
||||
endActions = listOfNotNull(
|
||||
if (isMainScreenQrScanningEnabled) {
|
||||
TangemTopBarActionUM(
|
||||
iconRes = CoreUiR.drawable.ic_qrcode_scaner_24,
|
||||
onClick = clickIntents::onScanQrClick,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
TangemTopBarActionUM(
|
||||
iconRes = CoreUiR.drawable.ic_more_default_24,
|
||||
onClick = clickIntents::onDetailsClick,
|
||||
),
|
||||
).toPersistentList(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import com.tangem.feature.wallet.impl.R
|
|||
import com.tangem.feature.wallet.presentation.common.WalletPreviewDataLegacy
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTopBarConfig
|
||||
import dev.chrisbanes.haze.HazeProgressive
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
private const val VISIBILITY_THRESHOLD = 0.5f
|
||||
|
||||
|
|
@ -54,16 +55,11 @@ internal fun WalletTopBar(
|
|||
|
||||
TangemTopBar(
|
||||
title = wrappedBalance,
|
||||
startActionUM = TangemTopBarActionUM(
|
||||
startAction = TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_tangem_24,
|
||||
isActionable = false,
|
||||
),
|
||||
endActionUM = TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_more_default_24,
|
||||
isActionable = true,
|
||||
onClick = topBarConfig.onDetailsClick,
|
||||
ghostModeProgress = behavior.state.collapsedFraction,
|
||||
),
|
||||
endActions = topBarConfig.endActions,
|
||||
modifier = Modifier
|
||||
.statusBarsPadding()
|
||||
.testTag(MainScreenTestTags.TOP_BAR),
|
||||
|
|
@ -85,8 +81,15 @@ internal fun WalletTopBar(config: WalletTopBarConfig) {
|
|||
Icon(painter = painterResource(id = R.drawable.img_tangem_logo_90_24), contentDescription = null)
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = config.onDetailsClick, modifier = Modifier.testTag(MainScreenTestTags.MORE_BUTTON)) {
|
||||
Icon(painter = painterResource(id = R.drawable.ic_more_vertical_24), contentDescription = null)
|
||||
config.endActions.forEach { action ->
|
||||
if (action.onClick != null) {
|
||||
IconButton(onClick = action.onClick!!) {
|
||||
Icon(
|
||||
painter = painterResource(id = action.iconRes),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
|
|
@ -115,7 +118,31 @@ private fun Preview_WalletTopBar() {
|
|||
private fun WalletTopBar_Preview() {
|
||||
TangemThemePreviewRedesign {
|
||||
WalletTopBar(
|
||||
topBarConfig = WalletTopBarConfig(onDetailsClick = {}),
|
||||
topBarConfig = WalletTopBarConfig(),
|
||||
walletBalance = stringReference("$ 8923,05"),
|
||||
behavior = rememberTangemExitUntilCollapsedScrollBehavior(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun WalletTopBar_WithQrButton_Preview() {
|
||||
TangemThemePreviewRedesign {
|
||||
WalletTopBar(
|
||||
topBarConfig = WalletTopBarConfig(
|
||||
endActions = persistentListOf(
|
||||
TangemTopBarActionUM(
|
||||
iconRes = com.tangem.core.ui.R.drawable.ic_qrcode_scaner_24,
|
||||
onClick = {},
|
||||
),
|
||||
TangemTopBarActionUM(
|
||||
iconRes = R.drawable.ic_more_default_24,
|
||||
onClick = {},
|
||||
),
|
||||
),
|
||||
),
|
||||
walletBalance = stringReference("$ 8923,05"),
|
||||
behavior = rememberTangemExitUntilCollapsedScrollBehavior(),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue