Updated on 2026-08-14
This commit is contained in:
parent
fb32e4d5da
commit
67503c6c1a
11 changed files with 82 additions and 15 deletions
|
|
@ -3,10 +3,7 @@ package com.tangem.core.ui.components.bottomsheets.modal
|
|||
import android.content.res.Configuration
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -20,6 +17,7 @@ import com.tangem.core.ui.components.buttons.small.TangemIconButton
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
||||
|
|
@ -30,6 +28,7 @@ import com.tangem.core.ui.res.TangemThemePreview
|
|||
fun TangemModalBottomSheetTitle(
|
||||
modifier: Modifier = Modifier,
|
||||
title: TextReference? = null,
|
||||
subtitle: TextReference? = null,
|
||||
@DrawableRes startIconRes: Int? = null,
|
||||
onStartClick: (() -> Unit)? = null,
|
||||
@DrawableRes endIconRes: Int? = null,
|
||||
|
|
@ -49,13 +48,23 @@ fun TangemModalBottomSheetTitle(
|
|||
.align(Alignment.CenterStart),
|
||||
)
|
||||
}
|
||||
if (title != null) {
|
||||
Text(
|
||||
text = title.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
)
|
||||
Column(modifier = Modifier.align(Alignment.Center)) {
|
||||
if (title != null) {
|
||||
Text(
|
||||
text = title.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
)
|
||||
}
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
text = subtitle.resolveReference(),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
)
|
||||
}
|
||||
}
|
||||
if (endIconRes != null && onEndClick != null) {
|
||||
TangemIconButton(
|
||||
|
|
@ -79,6 +88,7 @@ private fun Preview_TangemModalBottomSheetTitle(
|
|||
TangemThemePreview {
|
||||
TangemModalBottomSheetTitle(
|
||||
title = params.title,
|
||||
subtitle = params.subtitle,
|
||||
startIconRes = params.startIconRes,
|
||||
onStartClick = params.onStartClick,
|
||||
endIconRes = params.endIconRes,
|
||||
|
|
@ -90,6 +100,7 @@ private fun Preview_TangemModalBottomSheetTitle(
|
|||
|
||||
private data class TangemModalBottomSheetTitleData(
|
||||
val title: TextReference?,
|
||||
val subtitle: TextReference?,
|
||||
val startIconRes: Int?,
|
||||
val onStartClick: (() -> Unit)?,
|
||||
val endIconRes: Int?,
|
||||
|
|
@ -104,6 +115,7 @@ private class TangemModalBottomSheetTitleProvider : PreviewParameterProvider<Tan
|
|||
onStartClick = {},
|
||||
endIconRes = null,
|
||||
onEndClick = null,
|
||||
subtitle = null,
|
||||
),
|
||||
TangemModalBottomSheetTitleData(
|
||||
title = resourceReference(R.string.wallet_title),
|
||||
|
|
@ -111,6 +123,7 @@ private class TangemModalBottomSheetTitleProvider : PreviewParameterProvider<Tan
|
|||
onStartClick = null,
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = {},
|
||||
subtitle = null,
|
||||
),
|
||||
TangemModalBottomSheetTitleData(
|
||||
title = resourceReference(R.string.wallet_title),
|
||||
|
|
@ -118,6 +131,23 @@ private class TangemModalBottomSheetTitleProvider : PreviewParameterProvider<Tan
|
|||
onStartClick = {},
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = {},
|
||||
subtitle = null,
|
||||
),
|
||||
TangemModalBottomSheetTitleData(
|
||||
title = resourceReference(R.string.wallet_title),
|
||||
subtitle = stringReference("Today • 2:37 PM"),
|
||||
startIconRes = R.drawable.ic_back_24,
|
||||
onStartClick = {},
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = {},
|
||||
),
|
||||
TangemModalBottomSheetTitleData(
|
||||
title = null,
|
||||
subtitle = stringReference("Today • 2:37 PM"),
|
||||
startIconRes = R.drawable.ic_back_24,
|
||||
onStartClick = {},
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = {},
|
||||
),
|
||||
TangemModalBottomSheetTitleData(
|
||||
title = null,
|
||||
|
|
@ -125,6 +155,7 @@ private class TangemModalBottomSheetTitleProvider : PreviewParameterProvider<Tan
|
|||
onStartClick = {},
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = {},
|
||||
subtitle = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ dependencies {
|
|||
/* Other */
|
||||
implementation(deps.kotlin.coroutines)
|
||||
implementation(deps.arrow.core)
|
||||
implementation(deps.jodatime)
|
||||
implementation(projects.domain.blockaid)
|
||||
implementation(projects.domain.blockaid.models)
|
||||
implementation(projects.libs.crypto)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import dagger.assisted.AssistedFactory
|
|||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.*
|
||||
import org.joda.time.DateTime
|
||||
import timber.log.Timber
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -94,6 +95,7 @@ internal class DefaultWcPairUseCase @AssistedInject constructor(
|
|||
sdkModel = WcSdkSessionConverter.convert(settledSession.session),
|
||||
securityStatus = proposalState.dAppSession.securityStatus,
|
||||
networks = sessionForApprove.network.toSet(),
|
||||
connectingTime = DateTime.now().millis,
|
||||
)
|
||||
sessionsManager.saveSession(newSession)
|
||||
analytics.send(
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.*
|
||||
import org.joda.time.DateTime
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
|
|
@ -65,7 +66,14 @@ internal class DefaultWcSessionsManager(
|
|||
}
|
||||
|
||||
override suspend fun saveSession(session: WcSession) {
|
||||
store.saveSession(WcSessionDTO(session.sdkModel.topic, session.wallet.walletId, session.securityStatus))
|
||||
store.saveSession(
|
||||
WcSessionDTO(
|
||||
topic = session.sdkModel.topic,
|
||||
walletId = session.wallet.walletId,
|
||||
securityStatus = session.securityStatus,
|
||||
connectingTime = session.connectingTime ?: DateTime.now().millis,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun removeSession(session: WcSession): Either<Throwable, Unit> {
|
||||
|
|
@ -89,6 +97,7 @@ internal class DefaultWcSessionsManager(
|
|||
sdkModel = WcSdkSessionConverter.convert(sdkSession),
|
||||
securityStatus = storedSession.securityStatus,
|
||||
networks = networks,
|
||||
connectingTime = storedSession.connectingTime,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +146,7 @@ internal class DefaultWcSessionsManager(
|
|||
sdkModel = WcSdkSessionConverter.convert(sdkSession),
|
||||
securityStatus = session.securityStatus,
|
||||
networks = networks,
|
||||
connectingTime = session.connectingTime,
|
||||
)
|
||||
}
|
||||
return wcSessions
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ internal class DefaultWcPairUseCaseTest {
|
|||
sdkModel = WcSdkSessionConverter.convert(this),
|
||||
securityStatus = CheckDAppResult.SAFE,
|
||||
networks = setOf(),
|
||||
connectingTime = null,
|
||||
)
|
||||
|
||||
private fun useCaseFactory() = DefaultWcPairUseCase(
|
||||
|
|
@ -144,7 +145,7 @@ internal class DefaultWcPairUseCaseTest {
|
|||
|
||||
coEvery { sdkDelegate.pair(url) } returns sdkProposal.right()
|
||||
coEvery { sdkDelegate.approve(sdkApprove) } returns sdkApproveSuccess.right()
|
||||
coEvery { sessionsManager.saveSession(sessionForSave) } returns Unit
|
||||
coEvery { sessionsManager.saveSession(any()) } returns Unit
|
||||
coEvery { blockAidVerifier.verifyDApp(any()) } returns Either.catch { CheckDAppResult.SAFE }
|
||||
|
||||
val useCase = useCaseFactory()
|
||||
|
|
@ -162,9 +163,12 @@ internal class DefaultWcPairUseCaseTest {
|
|||
assertEquals(approveLoading, awaitItem())
|
||||
coVerifyOrder {
|
||||
sdkDelegate.approve(sdkApprove)
|
||||
sessionsManager.saveSession(sessionForSave)
|
||||
sessionsManager.saveSession(any())
|
||||
}
|
||||
assertEquals(result, awaitItem())
|
||||
val actual: WcPairState = awaitItem()
|
||||
assert(actual is WcPairState.Approving.Result)
|
||||
actual as WcPairState.Approving.Result
|
||||
assertEquals(result.session, actual.session)
|
||||
awaitComplete()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ internal class WcSignUseCaseDelegateTest {
|
|||
wallet = MockUserWalletFactory.create(),
|
||||
networks = setOf(),
|
||||
securityStatus = CheckDAppResult.FAILED_TO_VERIFY,
|
||||
connectingTime = 0L,
|
||||
sdkModel = WcSdkSession(
|
||||
topic = "",
|
||||
appMetaData = WcAppMetaData(
|
||||
|
|
|
|||
|
|
@ -10,4 +10,5 @@ data class WcSession(
|
|||
val networks: Set<Network>,
|
||||
val sdkModel: WcSdkSession,
|
||||
val securityStatus: CheckDAppResult,
|
||||
val connectingTime: Long?,
|
||||
)
|
||||
|
|
@ -9,4 +9,5 @@ data class WcSessionDTO(
|
|||
val topic: String,
|
||||
val walletId: UserWalletId,
|
||||
val securityStatus: CheckDAppResult = CheckDAppResult.FAILED_TO_VERIFY,
|
||||
val connectingTime: Long? = null,
|
||||
)
|
||||
|
|
@ -11,6 +11,7 @@ data class WcConnectedAppInfoUM(
|
|||
val notification: WcAppInfoSecurityNotification? = null,
|
||||
val appSubtitle: String,
|
||||
val walletName: String,
|
||||
val connectingTime: Long?,
|
||||
val networks: ImmutableList<WcNetworkInfoItem.Required>,
|
||||
val disconnectButtonConfig: WcPrimaryButtonConfig,
|
||||
val onDismiss: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ internal class WcConnectedAppInfoModel @Inject constructor(
|
|||
verifiedDAppState = extractVerifiedState(session),
|
||||
appSubtitle = WcAppSubtitleConverter.convert(session.sdkModel.appMetaData),
|
||||
walletName = session.wallet.name,
|
||||
connectingTime = session.connectingTime,
|
||||
networks = session.networks
|
||||
.map {
|
||||
WcNetworkInfoItem.Required(
|
||||
|
|
|
|||
|
|
@ -24,9 +24,13 @@ import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTi
|
|||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.utils.DateTimeFormatters
|
||||
import com.tangem.core.ui.utils.toDateFormatWithTodayYesterday
|
||||
import com.tangem.core.ui.utils.toTimeFormat
|
||||
import com.tangem.features.walletconnect.connections.entity.*
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -44,6 +48,15 @@ internal fun WcConnectedAppInfoBS(state: WcConnectedAppInfoUM) {
|
|||
title = {
|
||||
TangemModalBottomSheetTitle(
|
||||
title = resourceReference(R.string.wc_wallet_connect),
|
||||
subtitle = state.connectingTime?.let { timestamp ->
|
||||
resourceReference(
|
||||
R.string.send_date_format,
|
||||
wrappedList(
|
||||
timestamp.toDateFormatWithTodayYesterday(DateTimeFormatters.dateFormatter),
|
||||
timestamp.toTimeFormat(),
|
||||
),
|
||||
)
|
||||
},
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = state.onDismiss,
|
||||
)
|
||||
|
|
@ -185,6 +198,7 @@ private fun WcConnectedAppInfoBS_Preview() {
|
|||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
connectingTime = System.currentTimeMillis(),
|
||||
networks = persistentListOf(
|
||||
WcNetworkInfoItem.Required(
|
||||
id = "1",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue