Updated on 2026-08-14
This commit is contained in:
parent
f34c9f8213
commit
b6ea8b264b
7 changed files with 505 additions and 441 deletions
|
|
@ -4,8 +4,6 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
|
|
@ -21,9 +19,6 @@ class DetailsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
|
||||
private val detailsViewModel = DetailsViewModel(store)
|
||||
|
||||
private var detailsScreenState: MutableState<DetailsScreenState> =
|
||||
mutableStateOf(detailsViewModel.updateState(store.state.detailsState))
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Analytics.send(Settings.ScreenOpened())
|
||||
|
|
@ -42,7 +37,7 @@ class DetailsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
isTransitionGroup = true
|
||||
TangemTheme {
|
||||
DetailsScreen(
|
||||
state = detailsScreenState.value,
|
||||
state = detailsViewModel.detailsScreenState.value,
|
||||
onBackClick = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
)
|
||||
}
|
||||
|
|
@ -66,6 +61,6 @@ class DetailsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
|
||||
override fun newState(state: DetailsState) {
|
||||
if (activity == null || view == null) return
|
||||
detailsScreenState.value = detailsViewModel.updateState(state)
|
||||
detailsViewModel.detailsScreenState.value = detailsViewModel.updateState(state)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ package com.tangem.tap.features.details.ui.details
|
|||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
|
|
@ -16,8 +18,13 @@ import androidx.compose.foundation.lazy.items
|
|||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.SnackbarHost
|
||||
import androidx.compose.material.SnackbarHostState
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
|
|
@ -27,10 +34,12 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.compose.TangemTypography
|
||||
import com.tangem.tap.features.details.ui.common.ScreenTitle
|
||||
import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun DetailsScreen(state: DetailsScreenState, onBackClick: () -> Unit) {
|
||||
|
|
@ -46,32 +55,35 @@ fun DetailsScreen(state: DetailsScreenState, onBackClick: () -> Unit) {
|
|||
|
||||
@Composable
|
||||
fun Content(state: DetailsScreenState) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
ScreenTitle(titleRes = R.string.details_title, Modifier.padding(bottom = 52.dp))
|
||||
state.elements.map { element ->
|
||||
if (element == SettingsElement.WalletConnect) {
|
||||
WalletConnectDetailsItem(onItemsClick = state.onItemsClick)
|
||||
} else {
|
||||
DetailsItem(
|
||||
item = element,
|
||||
appCurrency = state.appCurrency,
|
||||
onItemsClick = { state.onItemsClick(element) },
|
||||
)
|
||||
Box {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
ScreenTitle(titleRes = R.string.details_title, Modifier.padding(bottom = 52.dp))
|
||||
state.elements.map { element ->
|
||||
if (element == SettingsElement.WalletConnect) {
|
||||
WalletConnectDetailsItem(onItemsClick = state.onItemsClick)
|
||||
} else {
|
||||
DetailsItem(
|
||||
item = element,
|
||||
appCurrency = state.appCurrency,
|
||||
onItemsClick = { state.onItemsClick(element) },
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
TangemSocialAccounts(state.tangemLinks, state.onSocialNetworkClick)
|
||||
Spacer(modifier = Modifier.size(12.dp))
|
||||
Text(
|
||||
text = "${stringResource(id = state.appNameRes)} ${state.tangemVersion}",
|
||||
style = TangemTypography.caption,
|
||||
color = colorResource(id = R.color.text_tertiary),
|
||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 40.dp),
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
TangemSocialAccounts(state.tangemLinks, state.onSocialNetworkClick)
|
||||
Spacer(modifier = Modifier.size(12.dp))
|
||||
Text(
|
||||
text = "${stringResource(id = state.appNameRes)} ${state.tangemVersion}",
|
||||
style = TangemTypography.caption,
|
||||
color = colorResource(id = R.color.text_tertiary),
|
||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 40.dp),
|
||||
)
|
||||
ShowSnackbarIfNeeded(state.showErrorSnackbar.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,6 +177,36 @@ fun TangemSocialAccounts(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BoxScope.ShowSnackbarIfNeeded(snackbarErrorState: EventError) {
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
SnackbarHost(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(vertical = TangemTheme.dimens.spacing16)
|
||||
.fillMaxWidth(),
|
||||
hostState = snackbarHostState,
|
||||
)
|
||||
val errorTitle = when (snackbarErrorState) {
|
||||
is EventError.DemoReferralNotAvailable -> stringResource(id = R.string.alert_demo_feature_disabled)
|
||||
EventError.Empty -> ""
|
||||
}
|
||||
if (snackbarErrorState != EventError.Empty) {
|
||||
SideEffect {
|
||||
coroutineScope.launch {
|
||||
snackbarHostState.showSnackbar(errorTitle)
|
||||
}
|
||||
when (snackbarErrorState) {
|
||||
is EventError.DemoReferralNotAvailable -> snackbarErrorState.onErrorShow.invoke()
|
||||
else -> {
|
||||
/*no-op*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun Preview() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.tap.features.details.ui.details
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@Immutable
|
||||
|
|
@ -11,6 +13,7 @@ data class DetailsScreenState(
|
|||
val appCurrency: String,
|
||||
val onItemsClick: (SettingsElement) -> Unit,
|
||||
val onSocialNetworkClick: (SocialNetworkLink) -> Unit,
|
||||
val showErrorSnackbar: MutableState<EventError> = mutableStateOf(EventError.Empty),
|
||||
) {
|
||||
val appNameRes: Int = R.string.tangem_app_name
|
||||
}
|
||||
|
|
@ -39,6 +42,11 @@ data class SocialNetworkLink(
|
|||
val url: String,
|
||||
)
|
||||
|
||||
sealed class EventError {
|
||||
object Empty : EventError()
|
||||
data class DemoReferralNotAvailable(val onErrorShow: () -> Unit) : EventError()
|
||||
}
|
||||
|
||||
sealed class SocialNetwork(val id: String, val iconRes: Int) {
|
||||
object Telegram : SocialNetwork("Telegram", R.drawable.ic_telegram)
|
||||
object Twitter : SocialNetwork("Twitter", R.drawable.ic_twitter)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.tap.features.details.ui.details
|
||||
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.Settings
|
||||
import com.tangem.tap.common.feedback.FeedbackEmail
|
||||
|
|
@ -8,6 +10,7 @@ import com.tangem.tap.common.redux.AppState
|
|||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
|
||||
import com.tangem.tap.features.home.LocaleRegionProvider
|
||||
|
|
@ -18,6 +21,9 @@ import org.rekotlin.Store
|
|||
|
||||
class DetailsViewModel(private val store: Store<AppState>) {
|
||||
|
||||
var detailsScreenState: MutableState<DetailsScreenState> = mutableStateOf(updateState(store.state.detailsState))
|
||||
private set
|
||||
|
||||
@Suppress("ComplexMethod")
|
||||
fun updateState(state: DetailsState): DetailsScreenState {
|
||||
val cardTypesResolver = state.scanResponse?.cardTypesResolver
|
||||
|
|
@ -95,7 +101,15 @@ class DetailsViewModel(private val store: Store<AppState>) {
|
|||
// TODO: To be available later
|
||||
}
|
||||
SettingsElement.ReferralProgram -> {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.ReferralProgram))
|
||||
if (store.state.detailsState.scanResponse?.let { DemoHelper.isDemoCard(it) } == true) {
|
||||
detailsScreenState.value.showErrorSnackbar.value = EventError.DemoReferralNotAvailable(
|
||||
onErrorShow = {
|
||||
detailsScreenState.value.showErrorSnackbar.value = EventError.Empty
|
||||
},
|
||||
)
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.ReferralProgram))
|
||||
}
|
||||
}
|
||||
SettingsElement.TesterMenu -> {
|
||||
store.state.daggerGraphState.testerRouter?.startTesterScreen()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue