Updated on 2026-08-14
This commit is contained in:
parent
0dd5b23b64
commit
e1f5d41f27
13 changed files with 447 additions and 76 deletions
|
|
@ -145,8 +145,6 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicModalBottomSheet(
|
|||
) {
|
||||
val model = config.content as? T ?: return
|
||||
|
||||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||
|
||||
val bsContent: @Composable ColumnScope.() -> Unit = {
|
||||
val maxHeight = LocalConfiguration.current.screenHeightDp * MODAL_SHEET_MAX_HEIGHT
|
||||
|
||||
|
|
@ -157,7 +155,6 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicModalBottomSheet(
|
|||
.clip(TangemTheme.shapes.roundedCornersLarge)
|
||||
.background(containerColor)
|
||||
.heightIn(max = maxHeight.dp)
|
||||
.padding(bottom = bottomBarHeight)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
|
|
|
|||
|
|
@ -4,10 +4,18 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.slot.childSlot
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.walletconnect.usecase.pair.WcPairUseCase
|
||||
import com.tangem.features.walletconnect.connections.model.WcConnectionsModel
|
||||
import com.tangem.features.walletconnect.connections.routes.WcConnectionsBottomSheetRoutes
|
||||
import com.tangem.features.walletconnect.connections.ui.WcConnectionsContent
|
||||
|
||||
internal class ConnectionsComponent(
|
||||
|
|
@ -15,10 +23,35 @@ internal class ConnectionsComponent(
|
|||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: WcConnectionsModel = getOrCreateModel()
|
||||
private val bottomSheetSlot = childSlot(
|
||||
source = model.bottomSheetNavigation,
|
||||
serializer = null,
|
||||
handleBackButton = false,
|
||||
childFactory = ::bottomSheetChild,
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
val bottomSheet by bottomSheetSlot.subscribeAsState()
|
||||
WcConnectionsContent(modifier = modifier, state = state)
|
||||
|
||||
bottomSheet.child?.instance?.BottomSheet()
|
||||
}
|
||||
|
||||
private fun bottomSheetChild(
|
||||
config: WcConnectionsBottomSheetRoutes,
|
||||
componentContext: ComponentContext,
|
||||
): ComposableBottomSheetComponent {
|
||||
return when (config) {
|
||||
is WcConnectionsBottomSheetRoutes.AppInfo -> WcAppInfoContainerComponent(
|
||||
appComponentContext = childByContext(componentContext),
|
||||
params = WcAppInfoContainerComponent.Params(
|
||||
wcUrl = config.wcUrl,
|
||||
source = WcPairUseCase.Source.QR,
|
||||
onDismiss = model.bottomSheetNavigation::dismiss,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +1,27 @@
|
|||
package com.tangem.features.walletconnect.connections.components
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.walletconnect.connections.model.WcAppInfoModel
|
||||
import com.tangem.features.walletconnect.connections.ui.WcAppInfoModalBottomSheet
|
||||
|
||||
internal class WcAppInfoComponent(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
private val params: Params,
|
||||
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
|
||||
|
||||
override fun dismiss() {
|
||||
params.onDismiss()
|
||||
}
|
||||
private val model: WcAppInfoModel,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
@Composable
|
||||
override fun BottomSheet() {
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.appInfoUiState.collectAsStateWithLifecycle()
|
||||
WcAppInfoModalBottomSheet(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = ::dismiss,
|
||||
content = TangemBottomSheetConfigContent.Empty, // todo(wc) will be fixed in next PR's
|
||||
),
|
||||
modifier = modifier.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
state = state,
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(val onDismiss: () -> Unit)
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
package com.tangem.features.walletconnect.connections.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.extensions.compose.stack.Children
|
||||
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.childStack
|
||||
import com.arkivanov.decompose.router.stack.pop
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.domain.walletconnect.usecase.pair.WcPairUseCase
|
||||
import com.tangem.features.walletconnect.connections.model.WcAppInfoModel
|
||||
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
|
||||
internal class WcAppInfoContainerComponent(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
params: Params,
|
||||
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
|
||||
|
||||
private val model: WcAppInfoModel = getOrCreateModel(params = params)
|
||||
private val contentNavigation = StackNavigation<WcAppInfoRoutes>()
|
||||
private val contentStack = childStack(
|
||||
source = contentNavigation,
|
||||
serializer = WcAppInfoRoutes.serializer(),
|
||||
initialConfiguration = WcAppInfoRoutes.AppInfo,
|
||||
childFactory = ::screenChild,
|
||||
)
|
||||
|
||||
override fun dismiss() {
|
||||
model.dismiss()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun BottomSheet() {
|
||||
val content by contentStack.subscribeAsState()
|
||||
TangemModalBottomSheet<WcAppInfoRoutes>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = ::dismiss,
|
||||
content = content.active.configuration,
|
||||
),
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
title = { config -> Title(route = config) },
|
||||
content = {
|
||||
Children(stack = content, animation = stackAnimation()) { child ->
|
||||
child.instance.Content(modifier = Modifier)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Title(route: WcAppInfoRoutes) {
|
||||
TangemModalBottomSheetTitle(
|
||||
title = resourceReference(R.string.wc_wallet_connect),
|
||||
startIconRes = when (route) {
|
||||
is WcAppInfoRoutes.AppInfo, is WcAppInfoRoutes.Alert -> null
|
||||
is WcAppInfoRoutes.SelectNetworks, is WcAppInfoRoutes.SelectWallet -> R.drawable.ic_back_24
|
||||
},
|
||||
onStartClick = when (route) {
|
||||
is WcAppInfoRoutes.AppInfo, is WcAppInfoRoutes.Alert -> null
|
||||
is WcAppInfoRoutes.SelectNetworks, is WcAppInfoRoutes.SelectWallet -> ::contentBack
|
||||
},
|
||||
endIconRes = when (route) {
|
||||
is WcAppInfoRoutes.AppInfo, is WcAppInfoRoutes.Alert -> R.drawable.ic_close_24
|
||||
is WcAppInfoRoutes.SelectNetworks, is WcAppInfoRoutes.SelectWallet -> null
|
||||
},
|
||||
onEndClick = when (route) {
|
||||
is WcAppInfoRoutes.AppInfo -> ::dismiss
|
||||
is WcAppInfoRoutes.Alert -> ::contentBack
|
||||
is WcAppInfoRoutes.SelectNetworks,
|
||||
is WcAppInfoRoutes.SelectWallet,
|
||||
-> null
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun contentBack() {
|
||||
contentNavigation.pop()
|
||||
}
|
||||
|
||||
private fun screenChild(config: WcAppInfoRoutes, componentContext: ComponentContext): ComposableContentComponent =
|
||||
when (config) {
|
||||
is WcAppInfoRoutes.AppInfo -> WcAppInfoComponent(
|
||||
appComponentContext = childByContext(componentContext),
|
||||
model = model,
|
||||
)
|
||||
is WcAppInfoRoutes.Alert -> TODO()
|
||||
WcAppInfoRoutes.SelectNetworks -> TODO()
|
||||
WcAppInfoRoutes.SelectWallet -> TODO()
|
||||
}
|
||||
|
||||
data class Params(val wcUrl: String, val source: WcPairUseCase.Source, val onDismiss: () -> Unit)
|
||||
}
|
||||
|
|
@ -6,20 +6,31 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Immutable
|
||||
internal data class WcAppInfoUM(
|
||||
val appName: String,
|
||||
val appIcon: String,
|
||||
val isVerified: Boolean,
|
||||
val appSubtitle: String,
|
||||
val notificationUM: NotificationUM?,
|
||||
val walletName: String,
|
||||
val networksInfo: WcNetworksInfo,
|
||||
val onDismiss: () -> Unit,
|
||||
val onConnect: () -> Unit,
|
||||
) : TangemBottomSheetConfigContent
|
||||
internal sealed class WcAppInfoUM : TangemBottomSheetConfigContent {
|
||||
|
||||
abstract val onDismiss: () -> Unit
|
||||
abstract val connectButtonConfig: WcPrimaryButtonConfig
|
||||
|
||||
data class Loading(
|
||||
override val onDismiss: () -> Unit,
|
||||
override val connectButtonConfig: WcPrimaryButtonConfig,
|
||||
) : WcAppInfoUM()
|
||||
|
||||
data class Content(
|
||||
val appName: String,
|
||||
val appIcon: String,
|
||||
val isVerified: Boolean,
|
||||
val appSubtitle: String,
|
||||
val notificationUM: NotificationUM?,
|
||||
val walletName: String,
|
||||
val networksInfo: WcNetworksInfo,
|
||||
override val connectButtonConfig: WcPrimaryButtonConfig,
|
||||
override val onDismiss: () -> Unit,
|
||||
) : WcAppInfoUM()
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal sealed class WcNetworksInfo {
|
||||
data class MissingRequiredNetworkInfo(val network: String) : WcNetworksInfo()
|
||||
data class MissingRequiredNetworkInfo(val networks: String) : WcNetworksInfo()
|
||||
data class ContainsAllRequiredNetworks(val icons: ImmutableList<Int>) : WcNetworksInfo()
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.tangem.features.walletconnect.connections.entity
|
||||
|
||||
data class WcPrimaryButtonConfig(val showProgress: Boolean, val enabled: Boolean, val onClick: () -> Unit)
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.features.walletconnect.connections.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.features.walletconnect.connections.components.WcAppInfoContainerComponent
|
||||
import com.tangem.features.walletconnect.connections.entity.WcAppInfoUM
|
||||
import com.tangem.features.walletconnect.connections.entity.WcPrimaryButtonConfig
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class WcAppInfoModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
private val params: WcAppInfoContainerComponent.Params = paramsContainer.require()
|
||||
val appInfoUiState: StateFlow<WcAppInfoUM>
|
||||
field = MutableStateFlow<WcAppInfoUM>(createLoadingState())
|
||||
|
||||
fun dismiss() {
|
||||
params.onDismiss()
|
||||
}
|
||||
|
||||
private fun onConnect() {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
}
|
||||
|
||||
private fun createLoadingState(): WcAppInfoUM.Loading {
|
||||
return WcAppInfoUM.Loading(
|
||||
onDismiss = ::dismiss,
|
||||
connectButtonConfig = WcPrimaryButtonConfig(showProgress = false, enabled = false, onClick = ::onConnect),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.features.walletconnect.connections.model
|
||||
|
||||
import arrow.core.getOrElse
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
|
|
@ -18,6 +20,7 @@ import com.tangem.domain.walletconnect.usecase.WcSessionsUseCase
|
|||
import com.tangem.features.walletconnect.connections.entity.WcConnectionsState
|
||||
import com.tangem.features.walletconnect.connections.entity.WcConnectionsTopAppBarConfig
|
||||
import com.tangem.features.walletconnect.connections.model.transformers.WcSessionsTransformer
|
||||
import com.tangem.features.walletconnect.connections.routes.WcConnectionsBottomSheetRoutes
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.transformer.update
|
||||
|
|
@ -37,6 +40,7 @@ internal class WcConnectionsModel @Inject constructor(
|
|||
|
||||
val uiState: StateFlow<WcConnectionsState>
|
||||
field = MutableStateFlow<WcConnectionsState>(getInitialState())
|
||||
val bottomSheetNavigation: SlotNavigation<WcConnectionsBottomSheetRoutes> = SlotNavigation()
|
||||
|
||||
init {
|
||||
listenQrUpdates()
|
||||
|
|
@ -46,10 +50,7 @@ internal class WcConnectionsModel @Inject constructor(
|
|||
private fun listenQrUpdates() {
|
||||
listenToQrScanningUseCase(SourceType.WALLET_CONNECT)
|
||||
.getOrElse { emptyFlow() }
|
||||
.onEach {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
Timber.d(it)
|
||||
}
|
||||
.onEach { wcUrl -> bottomSheetNavigation.activate(WcConnectionsBottomSheetRoutes.AppInfo(wcUrl)) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.features.walletconnect.connections.routes
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.features.walletconnect.connections.components.AlertsComponent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@Immutable
|
||||
internal sealed class WcAppInfoRoutes : TangemBottomSheetConfigContent {
|
||||
data object AppInfo : WcAppInfoRoutes()
|
||||
data object SelectWallet : WcAppInfoRoutes()
|
||||
data object SelectNetworks : WcAppInfoRoutes()
|
||||
data class Alert(val alertType: AlertsComponent.AlertType) : WcAppInfoRoutes()
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.features.walletconnect.connections.routes
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal sealed class WcConnectionsBottomSheetRoutes {
|
||||
@Serializable
|
||||
data class AppInfo(val wcUrl: String) : WcConnectionsBottomSheetRoutes()
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.walletconnect.connections.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
|
|
@ -31,8 +30,7 @@ internal fun WcAppInfoItem(
|
|||
AsyncImage(
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size48)
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius8))
|
||||
.background(Color.Black),
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius8)),
|
||||
model = iconUrl,
|
||||
contentDescription = title,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.clickable
|
|||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
|
|
@ -17,6 +18,7 @@ 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.StrokeCap
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
|
@ -27,11 +29,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
|
|
@ -41,29 +39,23 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.walletconnect.connections.entity.WcAppInfoUM
|
||||
import com.tangem.features.walletconnect.connections.entity.WcNetworksInfo
|
||||
import com.tangem.features.walletconnect.connections.entity.WcPrimaryButtonConfig
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
internal fun WcAppInfoModalBottomSheet(config: TangemBottomSheetConfig) {
|
||||
TangemModalBottomSheet<WcAppInfoUM>(
|
||||
config = config,
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
title = { state ->
|
||||
TangemModalBottomSheetTitle(
|
||||
title = resourceReference(R.string.wc_wallet_connect),
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = state.onDismiss,
|
||||
)
|
||||
},
|
||||
content = { state -> WcAppInfoModalBottomSheetContent(state) },
|
||||
)
|
||||
internal fun WcAppInfoModalBottomSheet(state: WcAppInfoUM, modifier: Modifier = Modifier) {
|
||||
when (state) {
|
||||
is WcAppInfoUM.Content -> WcAppInfoModalBottomSheetContent(state, modifier)
|
||||
is WcAppInfoUM.Loading -> WcAppInfoModalBottomSheetLoading(state, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
// region Content state
|
||||
@Composable
|
||||
private fun WcAppInfoModalBottomSheetContent(state: WcAppInfoUM) {
|
||||
Column(modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16)) {
|
||||
private fun WcAppInfoModalBottomSheetContent(state: WcAppInfoUM.Content, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
val blocksModifier = Modifier
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
||||
.background(color = TangemTheme.colors.background.action)
|
||||
|
|
@ -85,13 +77,13 @@ private fun WcAppInfoModalBottomSheetContent(state: WcAppInfoUM) {
|
|||
WcAppInfoButtons(
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing16),
|
||||
onDismiss = state.onDismiss,
|
||||
onConnect = state.onConnect,
|
||||
connectButtonConfig = state.connectButtonConfig,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WcAppInfoFirstBlock(state: WcAppInfoUM, modifier: Modifier = Modifier) {
|
||||
private fun WcAppInfoFirstBlock(state: WcAppInfoUM.Content, modifier: Modifier = Modifier) {
|
||||
var connectionRequestExpanded by remember { mutableStateOf(false) }
|
||||
Column(modifier = modifier.animateContentSize()) {
|
||||
WcAppInfoItem(
|
||||
|
|
@ -213,7 +205,7 @@ private fun ConnectionRequestDescriptionRow(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun WcAppInfoSecondBlock(state: WcAppInfoUM, modifier: Modifier = Modifier) {
|
||||
private fun WcAppInfoSecondBlock(state: WcAppInfoUM.Content, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
val itemsModifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -234,7 +226,7 @@ private fun WcAppInfoSecondBlock(state: WcAppInfoUM, modifier: Modifier = Modifi
|
|||
title = resourceReference(R.string.wc_missing_required_network_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.wc_missing_required_network_description,
|
||||
wrappedList(state.networksInfo.network),
|
||||
wrappedList(state.networksInfo.networks),
|
||||
),
|
||||
),
|
||||
iconTint = TangemTheme.colors.icon.attention,
|
||||
|
|
@ -374,7 +366,11 @@ private fun NetworkIcons(icons: ImmutableList<Int>, modifier: Modifier = Modifie
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun WcAppInfoButtons(onDismiss: () -> Unit, onConnect: () -> Unit, modifier: Modifier = Modifier) {
|
||||
private fun WcAppInfoButtons(
|
||||
onDismiss: () -> Unit,
|
||||
connectButtonConfig: WcPrimaryButtonConfig,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8)) {
|
||||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
|
|
@ -388,7 +384,166 @@ private fun WcAppInfoButtons(onDismiss: () -> Unit, onConnect: () -> Unit, modif
|
|||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.wc_common_connect),
|
||||
onClick = onConnect,
|
||||
onClick = connectButtonConfig.onClick,
|
||||
showProgress = connectButtonConfig.showProgress,
|
||||
enabled = connectButtonConfig.enabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Loading state
|
||||
@Composable
|
||||
private fun WcAppInfoModalBottomSheetLoading(state: WcAppInfoUM.Loading, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
val blocksModifier = Modifier
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
||||
.background(color = TangemTheme.colors.background.action)
|
||||
.fillMaxWidth()
|
||||
WcAppInfoFirstLoadingBlock(blocksModifier)
|
||||
WcAppInfoSecondLoadingBlock(
|
||||
modifier = Modifier
|
||||
.padding(top = 14.dp)
|
||||
.then(blocksModifier),
|
||||
)
|
||||
WcAppInfoButtons(
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing16),
|
||||
onDismiss = state.onDismiss,
|
||||
connectButtonConfig = state.connectButtonConfig,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WcAppInfoFirstLoadingBlock(modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
WcLoadingAppInfoItem()
|
||||
HorizontalDivider(thickness = 1.dp, color = TangemTheme.colors.stroke.primary)
|
||||
Row(
|
||||
modifier = Modifier.padding(all = 12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(24.dp),
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
strokeWidth = 2.dp,
|
||||
strokeCap = StrokeCap.Square,
|
||||
)
|
||||
Text(
|
||||
text = "Connecting...",
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WcAppInfoSecondLoadingBlock(modifier: Modifier = Modifier) {
|
||||
Column(modifier) {
|
||||
Row(modifier = Modifier.padding(all = 12.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
modifier = Modifier.size(24.dp),
|
||||
painter = painterResource(R.drawable.ic_wallet_new_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.wc_common_wallet),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
TextShimmer(style = TangemTheme.typography.body1, radius = 8.dp, text = "Wallet 2.0")
|
||||
}
|
||||
HorizontalDivider(thickness = 1.dp, color = TangemTheme.colors.stroke.primary)
|
||||
Row(modifier = Modifier.padding(all = 12.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
modifier = Modifier.size(24.dp),
|
||||
painter = painterResource(R.drawable.ic_network_new_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.wc_common_networks),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
WcAppInfoLoadingNetworkIcons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
private fun WcAppInfoLoadingNetworkIcons(modifier: Modifier = Modifier) {
|
||||
Box(modifier = modifier.wrapContentWidth()) {
|
||||
for (index in 0..3) {
|
||||
CircleShimmer(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing16.times(index))
|
||||
.border(
|
||||
width = 2.dp,
|
||||
color = TangemTheme.colors.background.action,
|
||||
shape = CircleShape,
|
||||
)
|
||||
.padding(2.dp)
|
||||
.clip(CircleShape)
|
||||
.size(20.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WcLoadingAppInfoItem(modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier.padding(TangemTheme.dimens.spacing12),
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
RectangleShimmer(modifier = Modifier.size(TangemTheme.dimens.size48), radius = 16.dp)
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4),
|
||||
) {
|
||||
TextShimmer(
|
||||
modifier = Modifier
|
||||
.width(106.dp)
|
||||
.height(24.dp),
|
||||
style = TangemTheme.typography.h3,
|
||||
radius = 8.dp,
|
||||
)
|
||||
TextShimmer(
|
||||
modifier = Modifier
|
||||
.width(168.dp)
|
||||
.height(20.dp),
|
||||
style = TangemTheme.typography.body2,
|
||||
radius = 8.dp,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun WcAppInfoBottomSheetPreview() {
|
||||
TangemThemePreview {
|
||||
WcAppInfoModalBottomSheetLoading(
|
||||
state = WcAppInfoUM.Loading(
|
||||
onDismiss = {},
|
||||
WcPrimaryButtonConfig(showProgress = false, enabled = false, onClick = {}),
|
||||
),
|
||||
modifier = Modifier
|
||||
.background(TangemTheme.colors.background.tertiary)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -396,21 +551,21 @@ private fun WcAppInfoButtons(onDismiss: () -> Unit, onConnect: () -> Unit, modif
|
|||
@Composable
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun WcAppInfoBottomSheetPreview(@PreviewParameter(WcAppInfoStateProvider::class) state: WcAppInfoUM) {
|
||||
private fun WcAppInfoBottomSheetPreview(@PreviewParameter(WcAppInfoStateProvider::class) state: WcAppInfoUM.Content) {
|
||||
TangemThemePreview {
|
||||
WcAppInfoModalBottomSheet(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = {},
|
||||
content = state,
|
||||
),
|
||||
state = state,
|
||||
modifier = Modifier
|
||||
.background(TangemTheme.colors.background.tertiary)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class WcAppInfoStateProvider : CollectionPreviewParameterProvider<WcAppInfoUM>(
|
||||
collection = listOf(
|
||||
WcAppInfoUM(
|
||||
WcAppInfoUM.Loading(onDismiss = {}, WcPrimaryButtonConfig(showProgress = false, enabled = false, onClick = {})),
|
||||
WcAppInfoUM.Content(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
|
|
@ -427,9 +582,9 @@ private class WcAppInfoStateProvider : CollectionPreviewParameterProvider<WcAppI
|
|||
),
|
||||
),
|
||||
onDismiss = {},
|
||||
onConnect = {},
|
||||
connectButtonConfig = WcPrimaryButtonConfig(showProgress = false, enabled = true, onClick = {}),
|
||||
),
|
||||
WcAppInfoUM(
|
||||
WcAppInfoUM.Content(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = false,
|
||||
|
|
@ -439,9 +594,9 @@ private class WcAppInfoStateProvider : CollectionPreviewParameterProvider<WcAppI
|
|||
subtitle = resourceReference(R.string.wc_alert_domain_issues_description),
|
||||
),
|
||||
walletName = "Tangem 2.0",
|
||||
networksInfo = WcNetworksInfo.MissingRequiredNetworkInfo(network = "Solana"),
|
||||
networksInfo = WcNetworksInfo.MissingRequiredNetworkInfo(networks = "Solana"),
|
||||
onDismiss = {},
|
||||
onConnect = {},
|
||||
connectButtonConfig = WcPrimaryButtonConfig(showProgress = false, enabled = true, onClick = {}),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.walletconnect.di
|
|||
|
||||
import com.tangem.core.decompose.di.ModelComponent
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.features.walletconnect.connections.model.WcAppInfoModel
|
||||
import com.tangem.features.walletconnect.connections.model.WcConnectionsModel
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
|
|
@ -17,4 +18,9 @@ internal interface WalletConnectModelModule {
|
|||
@IntoMap
|
||||
@ClassKey(WcConnectionsModel::class)
|
||||
fun bindWcConnectionsModel(model: WcConnectionsModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WcAppInfoModel::class)
|
||||
fun bindWcAppInfoModel(model: WcAppInfoModel): Model
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue