Updated on 2026-08-14
This commit is contained in:
parent
84570a8406
commit
06e132ba04
6 changed files with 129 additions and 79 deletions
|
|
@ -0,0 +1,71 @@
|
|||
package com.tangem.tap.features.details.ui.walletconnect
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.arkivanov.essenty.lifecycle.subscribe
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.tap.common.analytics.events.WalletConnect
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
|
||||
import com.tangem.tap.features.details.ui.walletconnect.api.WalletConnectComponent
|
||||
import com.tangem.tap.store
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
internal class DefaultWalletConnectComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted params: Unit,
|
||||
) : WalletConnectComponent, AppComponentContext by appComponentContext, StoreSubscriber<WalletConnectState> {
|
||||
|
||||
private val model: WalletConnectModel = getOrCreateModel()
|
||||
|
||||
private var screenState: MutableState<WalletConnectScreenState>? = null
|
||||
|
||||
init {
|
||||
lifecycle.subscribe(
|
||||
onCreate = {
|
||||
Analytics.send(WalletConnect.ScreenOpened())
|
||||
screenState = mutableStateOf(model.updateState(store.state.walletConnectState))
|
||||
},
|
||||
onStart = {
|
||||
store.subscribe(this) { state ->
|
||||
state.skipRepeats { oldState, newState ->
|
||||
oldState.walletConnectState == newState.walletConnectState
|
||||
}.select { it.walletConnectState }
|
||||
}
|
||||
},
|
||||
onStop = {
|
||||
store.unsubscribe(this)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
override fun newState(state: WalletConnectState) {
|
||||
screenState?.value = model.updateState(state)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state = screenState?.value ?: return
|
||||
WalletConnectScreen(
|
||||
modifier = modifier,
|
||||
state = state,
|
||||
onBackClick = {
|
||||
store.dispatchNavigationAction(AppRouter::pop)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : WalletConnectComponent.Factory {
|
||||
override fun create(context: AppComponentContext, params: Unit): DefaultWalletConnectComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
package com.tangem.tap.features.details.ui.walletconnect
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.ui.UiDependencies
|
||||
import com.tangem.core.ui.screen.ComposeFragment
|
||||
import com.tangem.tap.common.analytics.events.WalletConnect
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
|
||||
import com.tangem.tap.store
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.rekotlin.StoreSubscriber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
internal class WalletConnectFragment : ComposeFragment(), StoreSubscriber<WalletConnectState> {
|
||||
|
||||
@Inject
|
||||
override lateinit var uiDependencies: UiDependencies
|
||||
|
||||
private val viewModel: WalletConnectViewModel by viewModels()
|
||||
|
||||
private var screenState: MutableState<WalletConnectScreenState>? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Analytics.send(WalletConnect.ScreenOpened())
|
||||
lifecycle.addObserver(viewModel)
|
||||
screenState = mutableStateOf(viewModel.updateState(store.state.walletConnectState))
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val state = screenState?.value ?: return
|
||||
WalletConnectScreen(
|
||||
modifier = modifier,
|
||||
state = state,
|
||||
onBackClick = {
|
||||
store.dispatchNavigationAction(AppRouter::pop)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
store.subscribe(this) { state ->
|
||||
state.skipRepeats { oldState, newState ->
|
||||
oldState.walletConnectState == newState.walletConnectState
|
||||
}.select { it.walletConnectState }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
store.unsubscribe(this)
|
||||
}
|
||||
|
||||
override fun newState(state: WalletConnectState) {
|
||||
if (activity == null || view == null) return
|
||||
screenState?.value = viewModel.updateState(state)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +1,34 @@
|
|||
package com.tangem.tap.features.details.ui.walletconnect
|
||||
|
||||
import androidx.lifecycle.*
|
||||
import androidx.compose.runtime.Stable
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.core.decompose.di.ComponentScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
|
||||
import com.tangem.tap.store
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
internal class WalletConnectViewModel @Inject constructor(
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
internal class WalletConnectModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val listenToQrScanningUseCase: ListenToQrScanningUseCase,
|
||||
private val clipboardManager: ClipboardManager,
|
||||
) : ViewModel(), DefaultLifecycleObserver {
|
||||
) : Model() {
|
||||
|
||||
override fun onCreate(owner: LifecycleOwner) {
|
||||
viewModelScope.launch {
|
||||
init {
|
||||
modelScope.launch {
|
||||
listenToQrScanningUseCase(SourceType.WALLET_CONNECT)
|
||||
.getOrElse { emptyFlow() }
|
||||
.flowWithLifecycle(owner.lifecycle, minActiveState = Lifecycle.State.CREATED)
|
||||
.collect { store.dispatch(WalletConnectAction.OpenSession(it)) }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.tap.features.details.ui.walletconnect.api
|
||||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
|
||||
interface WalletConnectComponent : ComposableContentComponent {
|
||||
interface Factory : ComponentFactory<Unit, WalletConnectComponent>
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.tap.features.details.ui.walletconnect.di
|
||||
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.tap.features.details.ui.walletconnect.DefaultWalletConnectComponent
|
||||
import com.tangem.tap.features.details.ui.walletconnect.WalletConnectModel
|
||||
import com.tangem.tap.features.details.ui.walletconnect.api.WalletConnectComponent
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import dagger.multibindings.ClassKey
|
||||
import dagger.multibindings.IntoMap
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface WalletConnectFeatureModule {
|
||||
|
||||
@Binds
|
||||
fun bindFactory(impl: DefaultWalletConnectComponent.Factory): WalletConnectComponent.Factory
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WalletConnectModel::class)
|
||||
fun bindModel(model: WalletConnectModel): Model
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ import com.tangem.tap.features.details.ui.cardsettings.CardSettingsFragment
|
|||
import com.tangem.tap.features.details.ui.cardsettings.coderecovery.AccessCodeRecoveryFragment
|
||||
import com.tangem.tap.features.details.ui.resetcard.ResetCardFragment
|
||||
import com.tangem.tap.features.details.ui.securitymode.SecurityModeFragment
|
||||
import com.tangem.tap.features.details.ui.walletconnect.WalletConnectFragment
|
||||
import com.tangem.tap.features.details.ui.walletconnect.api.WalletConnectComponent
|
||||
import com.tangem.tap.features.home.api.HomeComponent
|
||||
import com.tangem.tap.features.onboarding.products.note.OnboardingNoteFragment
|
||||
import com.tangem.tap.features.onboarding.products.otherCards.OnboardingOtherCardsFragment
|
||||
|
|
@ -63,6 +63,7 @@ internal class ChildFactory @Inject constructor(
|
|||
private val swapComponentFactory: SwapComponent.Factory,
|
||||
private val homeComponentFactory: HomeComponent.Factory,
|
||||
private val tokenDetailsComponentFactory: TokenDetailsComponent.Factory,
|
||||
private val walletConnectComponentFactory: WalletConnectComponent.Factory,
|
||||
private val walletRouter: WalletRouter,
|
||||
private val qrScanningRouter: QrScanningRouter,
|
||||
private val testerRouter: TesterRouter,
|
||||
|
|
@ -267,6 +268,13 @@ internal class ChildFactory @Inject constructor(
|
|||
componentFactory = homeComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.WalletConnectSessions -> {
|
||||
createComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = Unit,
|
||||
componentFactory = walletConnectComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.AccessCodeRecovery,
|
||||
is AppRoute.AppCurrencySelector,
|
||||
is AppRoute.SaveWallet,
|
||||
|
|
@ -281,7 +289,6 @@ internal class ChildFactory @Inject constructor(
|
|||
is AppRoute.ReferralProgram,
|
||||
is AppRoute.ResetToFactory,
|
||||
is AppRoute.Wallet,
|
||||
is AppRoute.WalletConnectSessions,
|
||||
is AppRoute.PushNotification,
|
||||
-> error("Unsupported route: $route")
|
||||
}
|
||||
|
|
@ -400,7 +407,11 @@ internal class ChildFactory @Inject constructor(
|
|||
route.asFragmentChild(Provider { walletRouter.getEntryFragment() })
|
||||
}
|
||||
is AppRoute.WalletConnectSessions -> {
|
||||
route.asFragmentChild(Provider { WalletConnectFragment() })
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = Unit,
|
||||
componentFactory = walletConnectComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.CurrencyDetails -> {
|
||||
route.asComponentChild(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue