From d922493a761e5ce05884a618ad383caf320292c9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 26 Sep 2023 13:58:15 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../ui/cardsettings/CardSettingsFragment.kt | 36 ++-------- .../ui/cardsettings/CardSettingsScreen.kt | 70 +++++++++++-------- .../cardsettings/CardSettingsScreenState.kt | 2 + .../ui/cardsettings/CardSettingsViewModel.kt | 56 +++++++++++++-- 4 files changed, 101 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsFragment.kt index c9d70c6d00..82431ec211 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsFragment.kt @@ -1,58 +1,36 @@ package com.tangem.tap.features.details.ui.cardsettings import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalLifecycleOwner +import androidx.fragment.app.viewModels import com.tangem.core.navigation.NavigationAction import com.tangem.core.ui.screen.ComposeFragment import com.tangem.core.ui.theme.AppThemeModeHolder import com.tangem.tap.features.details.redux.DetailsAction -import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.store import dagger.hilt.android.AndroidEntryPoint -import org.rekotlin.StoreSubscriber import javax.inject.Inject @AndroidEntryPoint -internal class CardSettingsFragment : ComposeFragment(), StoreSubscriber { +internal class CardSettingsFragment : ComposeFragment() { @Inject override lateinit var appThemeModeHolder: AppThemeModeHolder - private val viewModel = CardSettingsViewModel(store) - - private var screenState: MutableState = - mutableStateOf(viewModel.updateState(store.state.detailsState.cardSettingsState)) + private val viewModel: CardSettingsViewModel by viewModels() @Composable override fun ScreenContent(modifier: Modifier) { + LocalLifecycleOwner.current.lifecycle.addObserver(viewModel) + CardSettingsScreen( modifier = modifier, - state = screenState.value, + state = viewModel.screenState.value, onBackClick = { store.dispatch(DetailsAction.ResetCardSettingsData) store.dispatch(NavigationAction.PopBackTo()) }, ) } - - override fun onStart() { - super.onStart() - store.subscribe(this) { state -> - state.skipRepeats { oldState, newState -> - oldState.detailsState == newState.detailsState - }.select { it.detailsState } - } - } - - override fun onStop() { - super.onStop() - store.unsubscribe(this) - } - - override fun newState(state: DetailsState) { - if (activity == null || view == null) return - screenState.value = viewModel.updateState(state.cardSettingsState) - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsScreen.kt index 87c845a602..759e966ed5 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsScreen.kt @@ -1,22 +1,21 @@ package com.tangem.tap.features.details.ui.cardsettings -import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable +import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.rotate -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import coil.compose.SubcomposeAsyncImage +import coil.request.ImageRequest import com.tangem.core.ui.res.TangemTheme +import com.tangem.domain.userwallets.Artwork import com.tangem.tap.features.details.ui.common.DetailsMainButton import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold import com.tangem.wallet.R @@ -33,7 +32,7 @@ internal fun CardSettingsScreen( modifier = modifier, content = { if (needReadCard) { - CardSettingsReadCard(state.onScanCardClick) + CardSettingsReadCard(state.onScanCardClick, state.cardImage) } else { CardSettings(state = state) } @@ -45,46 +44,57 @@ internal fun CardSettingsScreen( @Suppress("MagicNumber") @Composable -private fun CardSettingsReadCard(onScanCardClick: () -> Unit) { +private fun CardSettingsReadCard(onScanCardClick: () -> Unit, cardArtwork: Artwork?) { Column( - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxSize() + .padding(top = TangemTheme.dimens.size70), ) { Box( modifier = Modifier .fillMaxWidth() - .padding(bottom = 40.dp), + .padding(start = TangemTheme.dimens.size16, end = TangemTheme.dimens.size16), ) { - Image( + val circleColor = TangemTheme.colors.stroke.primary + Canvas( modifier = Modifier - .fillMaxWidth() - .padding(start = 80.dp, end = 80.dp, top = 70.dp) - .rotate(-15f), - painter = painterResource(id = R.drawable.card_placeholder_secondary), - contentDescription = "", - contentScale = ContentScale.FillWidth, - ) - Image( + .size(300.dp) + .align(Alignment.Center), + ) { + drawCircle( + color = circleColor, + radius = size.minDimension / 2.0f, + ) + } + SubcomposeAsyncImage( + model = ImageRequest.Builder(context = LocalContext.current) + .data(cardArtwork?.artworkId) + .crossfade(enable = true) + .build(), modifier = Modifier - .fillMaxWidth() - .padding(start = 60.dp, end = 60.dp) - .rotate(-1f), - painter = painterResource(id = R.drawable.card_placeholder_black), - contentDescription = "", - contentScale = ContentScale.FillWidth, + .align(Alignment.Center) + .fillMaxWidth(), + loading = { /* no-op */ }, + error = { /* no-op */ }, + contentDescription = null, ) } Spacer(modifier = Modifier.weight(1f)) Column( modifier = Modifier .fillMaxWidth() - .padding(start = 16.dp, end = 16.dp, bottom = 32.dp), + .padding( + start = TangemTheme.dimens.size16, + end = TangemTheme.dimens.size16, + bottom = TangemTheme.dimens.size32, + ), ) { Text( text = stringResource(id = R.string.scan_card_settings_title), color = TangemTheme.colors.text.primary1, style = TangemTheme.typography.h3, ) - Spacer(modifier = Modifier.size(20.dp)) + Spacer(modifier = Modifier.size(TangemTheme.dimens.size20)) Text( text = stringResource(id = R.string.scan_card_settings_message), color = TangemTheme.colors.text.secondary, @@ -93,7 +103,7 @@ private fun CardSettingsReadCard(onScanCardClick: () -> Unit) { .verticalScroll(rememberScrollState()) .weight(weight = 1f, fill = false), ) - Spacer(modifier = Modifier.size(29.dp)) + Spacer(modifier = Modifier.size(TangemTheme.dimens.size28)) DetailsMainButton( title = stringResource(id = R.string.scan_card_settings_button), onClick = onScanCardClick, @@ -166,7 +176,7 @@ private fun CardSettings(state: CardSettingsScreenState) { // region Preview @Composable private fun CardSettingsScreenStateSample() { - CardSettingsScreen(state = CardSettingsScreenState(onScanCardClick = {}) {}, {}) + CardSettingsScreen(state = CardSettingsScreenState(onScanCardClick = {}, onElementClick = {}), {}) } @Preview(showBackground = true, widthDp = 360) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsScreenState.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsScreenState.kt index 4cf5e68186..1cf79ec5e4 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsScreenState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsScreenState.kt @@ -4,6 +4,7 @@ import androidx.annotation.StringRes import androidx.compose.runtime.Composable import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.res.stringResource +import com.tangem.domain.userwallets.Artwork import com.tangem.tap.features.details.redux.AccessCodeRecoveryState import com.tangem.tap.features.details.redux.SecurityOption import com.tangem.tap.features.details.ui.securitymode.toTitleRes @@ -16,6 +17,7 @@ internal data class CardSettingsScreenState( val accessCodeRecoveryState: AccessCodeRecoveryState? = null, val onScanCardClick: () -> Unit, val onElementClick: (CardInfo) -> Unit, + val cardImage: Artwork? = null, ) internal sealed class CardInfo( diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsViewModel.kt index d40ed17ec9..2fb7ba4d56 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsViewModel.kt @@ -1,18 +1,64 @@ package com.tangem.tap.features.details.ui.cardsettings +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import arrow.core.Either import com.tangem.core.analytics.Analytics import com.tangem.domain.common.TapWorkarounds.isTangemTwins import com.tangem.domain.common.getTwinCardIdForUser +import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Settings -import com.tangem.tap.common.redux.AppState +import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.features.details.redux.CardSettingsState import com.tangem.tap.features.details.redux.DetailsAction -import org.rekotlin.Store +import com.tangem.tap.features.details.redux.DetailsState +import com.tangem.tap.features.wallet.redux.WalletAction +import dagger.hilt.android.lifecycle.HiltViewModel +import org.rekotlin.StoreSubscriber +import com.tangem.tap.store +import timber.log.Timber +import javax.inject.Inject -internal class CardSettingsViewModel(private val store: Store) { +@HiltViewModel +internal class CardSettingsViewModel @Inject constructor( + private val getSelectedWalletUseCase: GetSelectedWalletUseCase, +) : + ViewModel(), DefaultLifecycleObserver, StoreSubscriber { - fun updateState(state: CardSettingsState?): CardSettingsScreenState { + var screenState: MutableState = + mutableStateOf(updateState(store.state.detailsState.cardSettingsState)) + + override fun onStart(owner: LifecycleOwner) { + when (val selectedWalletEither = getSelectedWalletUseCase()) { + is Either.Left -> { + Timber.e(selectedWalletEither.value.toString()) + } + is Either.Right -> { + store.dispatchOnMain(WalletAction.UpdateUserWalletArtwork(selectedWalletEither.value.walletId)) + } + } + + store.subscribe(this) { state -> + state.skipRepeats { oldState, newState -> + oldState.detailsState == newState.detailsState && + oldState.walletState == newState.walletState + }.select { it.detailsState } + } + } + + override fun onStop(owner: LifecycleOwner) { + store.unsubscribe(this) + } + + override fun newState(state: DetailsState) { + screenState.value = updateState(state.cardSettingsState) + } + + private fun updateState(state: CardSettingsState?): CardSettingsScreenState { return if (state?.manageSecurityState == null) { CardSettingsScreenState( cardDetails = null, @@ -21,6 +67,7 @@ internal class CardSettingsViewModel(private val store: Store) { onScanCardClick = { store.dispatch(DetailsAction.ScanCard) }, + cardImage = store.state.walletState.cardImage, ) } else { val cardId = if (state.card.isTangemTwins) { @@ -58,6 +105,7 @@ internal class CardSettingsViewModel(private val store: Store) { onElementClick = { handleClickingItem(it) }, + cardImage = store.state.walletState.cardImage, ) } }