Updated on 2026-08-14
This commit is contained in:
parent
776cb482ad
commit
d922493a76
4 changed files with 101 additions and 63 deletions
|
|
@ -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<DetailsState> {
|
||||
internal class CardSettingsFragment : ComposeFragment() {
|
||||
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
private val viewModel = CardSettingsViewModel(store)
|
||||
|
||||
private var screenState: MutableState<CardSettingsScreenState> =
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<AppState>) {
|
||||
@HiltViewModel
|
||||
internal class CardSettingsViewModel @Inject constructor(
|
||||
private val getSelectedWalletUseCase: GetSelectedWalletUseCase,
|
||||
) :
|
||||
ViewModel(), DefaultLifecycleObserver, StoreSubscriber<DetailsState> {
|
||||
|
||||
fun updateState(state: CardSettingsState?): CardSettingsScreenState {
|
||||
var screenState: MutableState<CardSettingsScreenState> =
|
||||
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<AppState>) {
|
|||
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<AppState>) {
|
|||
onElementClick = {
|
||||
handleClickingItem(it)
|
||||
},
|
||||
cardImage = store.state.walletState.cardImage,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue