Updated on 2026-08-14
This commit is contained in:
parent
73b80b5ef9
commit
dad8ccb8da
27 changed files with 24 additions and 677 deletions
|
|
@ -32,7 +32,6 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
|||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
|
||||
import com.tangem.features.details.DetailsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
|
||||
import com.tangem.tap.common.log.TangemAppLoggerInitializer
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectSessionsRepository
|
||||
import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles
|
||||
|
|
@ -118,8 +117,6 @@ interface ApplicationEntryPoint {
|
|||
|
||||
fun getAppRouter(): AppRouter
|
||||
|
||||
fun getPushNotificationsFeatureToggles(): PushNotificationsFeatureToggles
|
||||
|
||||
fun getTangemAppLogger(): TangemAppLoggerInitializer
|
||||
|
||||
fun getHomeFeatureToggles(): HomeFeatureToggles
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ import com.tangem.tap.common.OnActivityResultCallback
|
|||
import com.tangem.tap.common.SnackbarHandler
|
||||
import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.common.extensions.showFragmentAllowingStateLoss
|
||||
import com.tangem.tap.common.redux.NotificationsHandler
|
||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
||||
|
|
@ -78,7 +77,6 @@ import com.tangem.tap.features.main.model.Toast
|
|||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction
|
||||
import com.tangem.tap.proxy.AppStateHolder
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphAction
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.routing.RoutingComponent
|
||||
import com.tangem.tap.routing.configurator.AppRouterConfig
|
||||
import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler
|
||||
|
|
@ -539,11 +537,8 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
|
|||
}
|
||||
} else {
|
||||
lifecycleScope.launch {
|
||||
val toggles = store.inject(getDependency = DaggerGraphState::pushNotificationsFeatureToggles)
|
||||
val isPushPermissionEnabled = toggles.isPushNotificationsEnabled
|
||||
val shouldShowTos = !cardRepository.isTangemTOSAccepted() && isPushPermissionEnabled
|
||||
val wasPushInitiallyAsked = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrElse { false }
|
||||
val shouldShowInitialPush = wasPushInitiallyAsked && isPushPermissionEnabled
|
||||
val shouldShowTos = !cardRepository.isTangemTOSAccepted()
|
||||
val shouldShowInitialPush = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrElse { false }
|
||||
|
||||
val route = when {
|
||||
shouldShowTos -> AppRoute.Disclaimer(isTosAccepted = false)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
|||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
|
||||
import com.tangem.features.details.DetailsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
|
||||
import com.tangem.tap.common.analytics.AnalyticsFactory
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler
|
||||
|
|
@ -188,9 +187,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
private val appRouter: AppRouter
|
||||
get() = entryPoint.getAppRouter()
|
||||
|
||||
private val pushNotificationsFeatureToggles: PushNotificationsFeatureToggles
|
||||
get() = entryPoint.getPushNotificationsFeatureToggles()
|
||||
|
||||
private val tangemAppLoggerInitializer: TangemAppLoggerInitializer
|
||||
get() = entryPoint.getTangemAppLogger()
|
||||
|
||||
|
|
@ -280,7 +276,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
urlOpener = urlOpener,
|
||||
shareManager = shareManager,
|
||||
appRouter = appRouter,
|
||||
pushNotificationsFeatureToggles = pushNotificationsFeatureToggles,
|
||||
homeFeatureToggles = homeFeatureToggles,
|
||||
getUserCountryUseCase = getUserCountryUseCase,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.tap.common.redux
|
|||
import com.tangem.tap.common.redux.global.globalReducer
|
||||
import com.tangem.tap.features.details.redux.DetailsReducer
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectReducer
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerReducer
|
||||
import com.tangem.tap.features.home.redux.HomeReducer
|
||||
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteReducer
|
||||
import com.tangem.tap.features.onboarding.products.otherCards.redux.OnboardingOtherCardsReducer
|
||||
|
|
@ -28,7 +27,6 @@ fun appReducer(action: Action, state: AppState?, appStateHolder: AppStateHolder)
|
|||
onboardingOtherCardsState = OnboardingOtherCardsReducer.reduce(action, state),
|
||||
twinCardsState = TwinCardsReducer.reduce(action, state),
|
||||
detailsState = DetailsReducer.reduce(action, state),
|
||||
disclaimerState = DisclaimerReducer.reduce(action, state),
|
||||
tokensState = TokensReducer.reduce(action, state),
|
||||
walletConnectState = WalletConnectReducer.reduce(action, state.walletConnectState),
|
||||
welcomeState = WelcomeReducer.reduce(action, state),
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import com.tangem.tap.features.details.redux.DetailsMiddleware
|
|||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectMiddleware
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerMiddleware
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerState
|
||||
import com.tangem.tap.features.home.redux.HomeMiddleware
|
||||
import com.tangem.tap.features.home.redux.HomeState
|
||||
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteMiddleware
|
||||
|
|
@ -43,7 +41,6 @@ data class AppState(
|
|||
val onboardingOtherCardsState: OnboardingOtherCardsState = OnboardingOtherCardsState(),
|
||||
val twinCardsState: TwinCardsState = TwinCardsState(),
|
||||
val detailsState: DetailsState = DetailsState(),
|
||||
val disclaimerState: DisclaimerState = DisclaimerState(),
|
||||
val tokensState: TokensState = TokensState(),
|
||||
val walletConnectState: WalletConnectState = WalletConnectState(),
|
||||
val welcomeState: WelcomeState = WelcomeState(),
|
||||
|
|
@ -75,7 +72,6 @@ data class AppState(
|
|||
OnboardingOtherCardsMiddleware.handler,
|
||||
TwinCardsMiddleware.handler,
|
||||
DetailsMiddleware().detailsMiddleware,
|
||||
DisclaimerMiddleware().disclaimerMiddleware,
|
||||
WalletConnectMiddleware().walletConnectMiddleware,
|
||||
BackupMiddleware().backupMiddleware,
|
||||
WelcomeMiddleware().middleware,
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ import com.tangem.operations.attestation.Attestation
|
|||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.disclaimer.createDisclaimer
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -62,7 +60,6 @@ class TapWalletManager(
|
|||
updateConfigManager(scanResponse)
|
||||
withMainContext {
|
||||
// Order is important
|
||||
store.dispatch(DisclaimerAction.SetDisclaimer(card.createDisclaimer()))
|
||||
store.dispatch(TwinCardsAction.IfTwinsPrepareState(scanResponse))
|
||||
store.dispatch(GlobalAction.SaveScanResponse(scanResponse))
|
||||
store.dispatch(GlobalAction.SetIfCardVerifiedOnline(!attestationFailed))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.tangem.tap.domain.scanCard
|
|||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.doOnFailure
|
||||
import com.tangem.common.doOnSuccess
|
||||
import com.tangem.common.routing.AppRoute
|
||||
|
|
@ -18,9 +17,6 @@ import com.tangem.tap.common.analytics.paramsInterceptor.CardContextInterceptor
|
|||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.disclaimer.createDisclaimer
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerCallback
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerSource
|
||||
import com.tangem.tap.features.onboarding.OnboardingHelper
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsStep
|
||||
|
|
@ -102,6 +98,8 @@ internal object LegacyScanProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private suspend inline fun showDisclaimerIfNeed(
|
||||
scanResponse: ScanResponse,
|
||||
crossinline disclaimerWillShow: () -> Unit = {},
|
||||
|
|
@ -109,7 +107,6 @@ internal object LegacyScanProcessor {
|
|||
crossinline onFailure: suspend (error: TangemError) -> Unit,
|
||||
) {
|
||||
val disclaimer = scanResponse.card.createDisclaimer()
|
||||
store.dispatchOnMain(DisclaimerAction.SetDisclaimer(disclaimer))
|
||||
|
||||
if (disclaimer.isAccepted()) {
|
||||
nextHandler(scanResponse)
|
||||
|
|
@ -120,23 +117,9 @@ internal object LegacyScanProcessor {
|
|||
withContext(Dispatchers.Main.immediate) {
|
||||
disclaimerWillShow()
|
||||
|
||||
store.dispatch(
|
||||
DisclaimerAction.Show(
|
||||
from = DisclaimerSource.Home,
|
||||
callback = DisclaimerCallback(
|
||||
onAccept = {
|
||||
scope.launch(Dispatchers.Main.immediate) {
|
||||
nextHandler(scanResponse)
|
||||
}
|
||||
},
|
||||
onDismiss = {
|
||||
scope.launch(Dispatchers.Main.immediate) {
|
||||
onFailure(TangemSdkError.UserCancelled())
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
store.dispatchNavigationAction {
|
||||
push(AppRoute.Disclaimer(isTosAccepted = false))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,11 +59,7 @@ internal object UseCaseScanProcessor {
|
|||
),
|
||||
)
|
||||
add(AnalyticsChain(Basic.CardWasScanned(analyticsSource)))
|
||||
val pushNotificationsToggles =
|
||||
store.inject(getDependency = DaggerGraphState::pushNotificationsFeatureToggles)
|
||||
if (pushNotificationsToggles.isPushNotificationsEnabled) {
|
||||
add(DisclaimerChain(store, disclaimerWillShow))
|
||||
}
|
||||
add(DisclaimerChain(store, disclaimerWillShow))
|
||||
add(CheckForOnboardingChain(store, store.state.globalState.tapWalletManager))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,15 @@
|
|||
package com.tangem.tap.domain.scanCard.chains
|
||||
|
||||
import arrow.core.left
|
||||
import arrow.core.right
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.domain.card.ScanCardException
|
||||
import com.tangem.domain.core.chain.Chain
|
||||
import com.tangem.domain.core.chain.ResultChain
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.disclaimer.Disclaimer
|
||||
import com.tangem.tap.features.disclaimer.createDisclaimer
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerCallback
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerSource
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import org.rekotlin.Store
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
/**
|
||||
* Handles disclaimer display after the card scanning operation.
|
||||
|
|
@ -40,31 +34,13 @@ internal class DisclaimerChain(
|
|||
previousChainResult.right()
|
||||
} else {
|
||||
disclaimerWillShow()
|
||||
showDisclaimer(disclaimer, previousChainResult)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun showDisclaimer(disclaimer: Disclaimer, response: ScanResponse): ScanChainResult {
|
||||
store.dispatchOnMain(DisclaimerAction.SetDisclaimer(disclaimer))
|
||||
// TODO: [REDACTED_JIRA]
|
||||
store.dispatchNavigationAction {
|
||||
push(route = AppRoute.Disclaimer(isTosAccepted = false))
|
||||
}
|
||||
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
store.dispatchOnMain(
|
||||
DisclaimerAction.Show(
|
||||
from = DisclaimerSource.Home,
|
||||
callback = DisclaimerCallback(
|
||||
onAccept = {
|
||||
if (continuation.isActive) {
|
||||
continuation.resume(response.right())
|
||||
}
|
||||
},
|
||||
onDismiss = {
|
||||
if (continuation.isActive) {
|
||||
continuation.resume(ScanChainException.DisclaimerWasCanceled.left())
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
previousChainResult.right()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ import com.tangem.common.routing.AppRoute
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
|
||||
import com.tangem.core.ui.event.StateEvent
|
||||
import com.tangem.core.ui.event.consumedEvent
|
||||
import com.tangem.core.ui.event.triggeredEvent
|
||||
|
|
@ -22,8 +21,6 @@ import com.tangem.tap.common.redux.AppState
|
|||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerSource
|
||||
import com.tangem.tap.features.home.LocaleRegionProvider
|
||||
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
|
||||
import com.tangem.tap.scope
|
||||
|
|
@ -128,7 +125,9 @@ internal class DetailsViewModel(
|
|||
}
|
||||
|
||||
private fun navigateToToS() {
|
||||
store.dispatchOnMain(DisclaimerAction.Show(DisclaimerSource.Details))
|
||||
store.dispatchNavigationAction {
|
||||
push(AppRoute.Disclaimer(isTosAccepted = true))
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToReferralProgram() {
|
||||
|
|
|
|||
|
|
@ -24,12 +24,6 @@ abstract class BaseDisclaimer(
|
|||
override suspend fun isAccepted(): Boolean = dataProvider.isAccepted()
|
||||
}
|
||||
|
||||
class DummyDisclaimer : Disclaimer {
|
||||
override fun getUri(): Uri = Uri.parse("https://tangem.com/tangem_tos.html")
|
||||
override suspend fun accept() {}
|
||||
override suspend fun isAccepted(): Boolean = false
|
||||
}
|
||||
|
||||
class TangemDisclaimer(dataProvider: DisclaimerDataProvider) : BaseDisclaimer(dataProvider) {
|
||||
override fun getUri(): Uri = Uri.parse("$baseUrl/tangem_tos.html")
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer.redux
|
||||
|
||||
import com.tangem.tap.common.entities.ProgressState
|
||||
import com.tangem.tap.features.disclaimer.Disclaimer
|
||||
import org.rekotlin.Action
|
||||
|
||||
sealed class DisclaimerAction : Action {
|
||||
|
||||
data class SetDisclaimer(val disclaimer: Disclaimer) : DisclaimerAction()
|
||||
|
||||
data class Show(
|
||||
val from: DisclaimerSource,
|
||||
val callback: DisclaimerCallback? = null,
|
||||
) : DisclaimerAction()
|
||||
|
||||
object AcceptDisclaimer : DisclaimerAction()
|
||||
object OnBackPressed : DisclaimerAction()
|
||||
|
||||
data class OnProgressStateChanged(val state: ProgressState?) : DisclaimerAction()
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer.redux
|
||||
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.mainScope
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
class DisclaimerMiddleware {
|
||||
val disclaimerMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
state()?.let { handleDisclaimerMiddleware(action, it) }
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDisclaimerMiddleware(action: Action, appState: AppState) {
|
||||
val state = appState.disclaimerState
|
||||
|
||||
when (action) {
|
||||
is DisclaimerAction.Show -> {
|
||||
store.dispatchNavigationAction {
|
||||
push(AppRoute.Disclaimer(isTosAccepted = action.from == DisclaimerSource.Details))
|
||||
}
|
||||
}
|
||||
is DisclaimerAction.AcceptDisclaimer -> {
|
||||
mainScope.launch {
|
||||
state.disclaimer.accept()
|
||||
store.dispatchNavigationAction(AppRouter::pop)
|
||||
state.callback?.onAccept?.invoke()
|
||||
}
|
||||
}
|
||||
is DisclaimerAction.OnBackPressed -> {
|
||||
store.dispatchNavigationAction(AppRouter::pop)
|
||||
state.callback?.onDismiss?.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import org.rekotlin.Action
|
||||
|
||||
object DisclaimerReducer {
|
||||
fun reduce(action: Action, state: AppState): DisclaimerState = internalReduce(action, state)
|
||||
}
|
||||
|
||||
private fun internalReduce(action: Action, state: AppState): DisclaimerState {
|
||||
if (action !is DisclaimerAction) return state.disclaimerState
|
||||
|
||||
val disclaimerState = state.disclaimerState
|
||||
|
||||
return when (action) {
|
||||
is DisclaimerAction.SetDisclaimer -> disclaimerState.copy(
|
||||
disclaimer = action.disclaimer,
|
||||
)
|
||||
is DisclaimerAction.Show -> disclaimerState.copy(
|
||||
showedFrom = action.from,
|
||||
callback = action.callback,
|
||||
)
|
||||
is DisclaimerAction.AcceptDisclaimer, is DisclaimerAction.OnBackPressed -> disclaimerState.copy(
|
||||
callback = null,
|
||||
progressState = null,
|
||||
)
|
||||
is DisclaimerAction.OnProgressStateChanged -> disclaimerState.copy(
|
||||
progressState = action.state,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer.redux
|
||||
|
||||
enum class DisclaimerSource {
|
||||
Home, Details
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer.redux
|
||||
|
||||
import com.tangem.common.extensions.VoidCallback
|
||||
|
||||
import com.tangem.tap.common.entities.ProgressState
|
||||
import com.tangem.tap.features.disclaimer.Disclaimer
|
||||
import com.tangem.tap.features.disclaimer.DummyDisclaimer
|
||||
import org.rekotlin.StateType
|
||||
|
||||
data class DisclaimerState(
|
||||
val disclaimer: Disclaimer = DummyDisclaimer(),
|
||||
val showedFrom: DisclaimerSource = DisclaimerSource.Home,
|
||||
val callback: DisclaimerCallback? = null,
|
||||
val progressState: ProgressState? = null,
|
||||
) : StateType
|
||||
|
||||
data class DisclaimerCallback(
|
||||
val onAccept: VoidCallback? = null,
|
||||
val onDismiss: VoidCallback? = null,
|
||||
)
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.View.OVER_SCROLL_NEVER
|
||||
import android.webkit.WebView
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.transition.TransitionInflater
|
||||
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||
|
||||
import com.tangem.core.ui.extensions.setStatusBarColor
|
||||
import com.tangem.tap.common.entities.ProgressState
|
||||
import com.tangem.tap.common.extensions.beginDelayedTransition
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.BaseFragment
|
||||
import com.tangem.tap.features.addBackPressHandler
|
||||
import com.tangem.tap.features.disclaimer.Disclaimer
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerSource
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerState
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import com.tangem.wallet.databinding.FragmentDisclaimerBinding
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
class DisclaimerFragment : BaseFragment(R.layout.fragment_disclaimer), StoreSubscriber<DisclaimerState> {
|
||||
|
||||
private val binding: FragmentDisclaimerBinding by viewBinding(FragmentDisclaimerBinding::bind)
|
||||
private val webViewClient = DisclaimerWebViewClient()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
addBackPressHandler(handler = this)
|
||||
|
||||
binding.apply {
|
||||
toolbar.setNavigationOnClickListener { handleOnBackPressed() }
|
||||
webView.apply {
|
||||
settings.allowFileAccess = false
|
||||
settings.javaScriptEnabled = false
|
||||
overScrollMode = OVER_SCROLL_NEVER
|
||||
webViewClient = this@DisclaimerFragment.webViewClient
|
||||
}
|
||||
webView.hide()
|
||||
groupError.hide()
|
||||
groupAccept.hide()
|
||||
groupLoading.hide()
|
||||
|
||||
btnAccept.setOnClickListener {
|
||||
store.dispatch(DisclaimerAction.AcceptDisclaimer)
|
||||
}
|
||||
btnRepeat.setOnClickListener {
|
||||
webViewClient.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
setStatusBarColor(R.color.background_secondary)
|
||||
|
||||
webViewClient.onProgressStateChanged = { store.dispatch(DisclaimerAction.OnProgressStateChanged(it)) }
|
||||
store.subscribe(subscriber = this) { state ->
|
||||
state
|
||||
.skipRepeats { oldState, newState -> oldState.disclaimerState == newState.disclaimerState }
|
||||
.select(AppState::disclaimerState)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
webViewClient.onProgressStateChanged = null
|
||||
store.unsubscribe(this)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun configureTransitions() {
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
when (store.state.disclaimerState.showedFrom) {
|
||||
DisclaimerSource.Home -> {
|
||||
enterTransition = inflater.inflateTransition(android.R.transition.slide_bottom)
|
||||
exitTransition = inflater.inflateTransition(android.R.transition.slide_top)
|
||||
}
|
||||
DisclaimerSource.Details -> {
|
||||
super.configureTransitions()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(DisclaimerAction.OnBackPressed)
|
||||
}
|
||||
|
||||
override fun newState(state: DisclaimerState) {
|
||||
return with(binding) {
|
||||
if (activity == null || view == null) return
|
||||
|
||||
updateUiVisibility(state.disclaimer, state.progressState)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateUiVisibility(disclaimer: Disclaimer, progressState: ProgressState?) = with(binding) {
|
||||
when (progressState) {
|
||||
ProgressState.Loading -> {
|
||||
root.beginDelayedTransition()
|
||||
webView.hide()
|
||||
groupError.hide()
|
||||
groupAccept.hide()
|
||||
groupLoading.show()
|
||||
}
|
||||
ProgressState.Done -> {
|
||||
root.beginDelayedTransition()
|
||||
groupError.hide()
|
||||
groupLoading.hide()
|
||||
webView.show()
|
||||
lifecycleScope.launch {
|
||||
groupAccept.show(!disclaimer.isAccepted())
|
||||
}
|
||||
}
|
||||
ProgressState.Error -> {
|
||||
root.beginDelayedTransition()
|
||||
webView.show()
|
||||
groupAccept.show()
|
||||
groupLoading.hide()
|
||||
groupError.hide()
|
||||
webView.loadLocalTermsOfServices()
|
||||
}
|
||||
else -> {
|
||||
webView.setBackgroundColor(resources.getColor(R.color.transparent, null))
|
||||
webView.loadUrl(disclaimer.getUri().toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun WebView.loadLocalTermsOfServices() {
|
||||
loadData(localTermsOfServices, "text/html", "UTF-8")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer.ui
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.webkit.*
|
||||
import com.tangem.common.extensions.ifNotNull
|
||||
import com.tangem.tap.common.entities.ProgressState
|
||||
|
||||
class DisclaimerWebViewClient : WebViewClient() {
|
||||
|
||||
var onProgressStateChanged: ((ProgressState) -> Unit)? = null
|
||||
|
||||
private var loadingUrl: String? = null
|
||||
private var loadedUrl: String? = null
|
||||
|
||||
private var progressState: ProgressState = ProgressState.Loading
|
||||
set(value) {
|
||||
field = value
|
||||
onProgressStateChanged?.invoke(value)
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
loadingUrl = null
|
||||
loadedUrl = null
|
||||
progressState = ProgressState.Loading
|
||||
}
|
||||
|
||||
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
||||
super.onPageStarted(view, url, favicon)
|
||||
|
||||
if (loadingUrl != url) progressState = ProgressState.Loading
|
||||
loadingUrl = url
|
||||
}
|
||||
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
|
||||
if (loadedUrl != url) progressState = ProgressState.Done
|
||||
loadedUrl = url
|
||||
}
|
||||
|
||||
override fun onReceivedError(view: WebView?, resourceRequest: WebResourceRequest?, error: WebResourceError?) {
|
||||
super.onReceivedError(view, resourceRequest, error)
|
||||
error?.let { progressState = ProgressState.Error }
|
||||
}
|
||||
|
||||
override fun onReceivedHttpError(
|
||||
view: WebView?,
|
||||
resourceRequest: WebResourceRequest?,
|
||||
errorResponse: WebResourceResponse?,
|
||||
) {
|
||||
super.onReceivedHttpError(view, resourceRequest, errorResponse)
|
||||
|
||||
ifNotNull(resourceRequest, errorResponse) { request, response ->
|
||||
if (request.url?.toString() != loadingUrl || response.statusCode < RESPONSE_USER_ERROR_STATUS_CODE) return
|
||||
if (progressState != ProgressState.Done) return
|
||||
|
||||
progressState = ProgressState.Error
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val RESPONSE_USER_ERROR_STATUS_CODE = 400
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer.ui
|
||||
|
||||
internal val localTermsOfServices = """
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Legal Disclaimer</title>
|
||||
<style>
|
||||
@font-face{font-family:"SF Pro Display";src:url(/fonts/sf-pro/SFProDisplay-Light.eot) format("embedded-opentype"),url(/fonts/sf-pro/SFProDisplay-Light.woff2) format("woff2"),url(/fonts/sf-pro/SFProDisplay-Light.woff) format("woff"),url(/fonts/sf-pro/SFProDisplay-Light.ttf) format("truetype");font-weight:300;font-style:normal;font-display:swap}@font-face{font-family:"SF Pro Display";src:url(/fonts/sf-pro/SFProDisplay-Regular.eot) format("embedded-opentype"),url(/fonts/sf-pro/SFProDisplay-Regular.woff2) format("woff2"),url(/fonts/sf-pro/SFProDisplay-Regular.woff) format("woff"),url(/fonts/sf-pro/SFProDisplay-Regular.ttf) format("truetype");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:"SF Pro Display";src:url(/fonts/sf-pro/SFProDisplay-Medium.eot) format("embedded-opentype"),url(/fonts/sf-pro/SFProDisplay-Medium.woff2) format("woff2"),url(/fonts/sf-pro/SFProDisplay-Medium.woff) format("woff"),url(/fonts/sf-pro/SFProDisplay-Medium.ttf) format("truetype");font-weight:500;font-style:normal;font-display:swap}@font-face{font-family:"SF Pro Display";src:url(/fonts/sf-pro/SFProDisplay-Semibold.eot) format("embedded-opentype"),url(/fonts/sf-pro/SFProDisplay-Semibold.woff2) format("woff2"),url(/fonts/sf-pro/SFProDisplay-Semibold.woff) format("woff"),url(/fonts/sf-pro/SFProDisplay-Semibold.ttf) format("truetype");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:"SF Pro Display";src:url(/fonts/sf-pro/SFProDisplay-Bold.eot) format("embedded-opentype"),url(/fonts/sf-pro/SFProDisplay-Bold.woff2) format("woff2"),url(/fonts/sf-pro/SFProDisplay-Bold.woff) format("woff"),url(/fonts/sf-pro/SFProDisplay-Bold.ttf) format("truetype");font-weight:700;font-style:normal;font-display:swap}*{margin:0;padding:0}body{padding:0;margin:1rem;color:rgb(0 0 0);font-family:'SF Pro Display',-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}h1{font-weight:700;font-size:30px;line-height:1.2;margin-bottom:1rem}p{font-size:16px;line-height:20px;letter-spacing:-.24px;margin-bottom:1rem}
|
||||
</style>
|
||||
</head>
|
||||
<body><h1>Legal Disclaimer</h1>
|
||||
<p> 1. Tangem application (Software)</p>
|
||||
<p> The Software is intended for usage only with Tangem hardware wallets (Cards) via NFC interface. The
|
||||
Software DOES NOT:</p>
|
||||
<p> a) Generate, store, transmit, or have access to private (secret) cryptographic keys to blockchain
|
||||
wallets holding digital assets, including crypto-currency.</p>
|
||||
<p> b) Generate, store, transmit, or have access to secret keys, passwords, passphrases, recovery phrases
|
||||
that can be used to restore or to copy private (secret) keys to blockchain wallets holding digital assets, including
|
||||
crypto-currency.</p>
|
||||
<p> c) Provide exchange, trading, investment services on behalf of Tangem AG.</p>
|
||||
<p> 2. Risks related to the use of Software</p>
|
||||
<p> Tangem will not be responsible for any losses, damages or claims arising from events falling within the
|
||||
scope of the following five categories:</p>
|
||||
<p> a) Mistakes made by the user of any cryptocurrency-related software or service, e.g., forgotten
|
||||
passwords, payments sent to wrong addresses, and accidental deletion of blockchain wallets on Cards.</p>
|
||||
<p> b) Problems of Software and/or any blockchain- or cryptocurrency- related software or service, e.g.,
|
||||
corrupted files, incorrectly constructed transactions, unsafe cryptographic libraries, malware.</p>
|
||||
<p> c) Technical failures in the hardware of the user, including Cards, of any cryptocurrency-related
|
||||
software or service, e.g., data loss due to a faulty or damaged storage device.</p>
|
||||
<p> d) Security problems experienced by the user of any cryptocurrency-related software or service, e.g.,
|
||||
unauthorized access to users' wallets and/or accounts.</p>
|
||||
<p> e) Actions or inactions of third parties and/or events experienced by third parties, e.g., bankruptcy
|
||||
of service providers, information security attacks on service providers, and fraud conducted by third parties.</p>
|
||||
<p> 3. Trading and Investment risks</p>
|
||||
<p> There is considerable exposure to risk in any crypto-currency or other digital asset exchange
|
||||
transaction. Any transaction involving currencies involves risks including, but not limited to, the potential for
|
||||
changing economic conditions that may substantially affect the price or liquidity of a currency. Investments in
|
||||
crypto-currency exchange speculation may also be susceptible to sharp rises and falls as the relevant market values
|
||||
fluctuate. It is for this reason that when speculating in such markets it is advisable to use only risk capital.</p>
|
||||
<p> 4. Electronic Trading Risks</p>
|
||||
<p> Before you engage in transactions using an electronic system, you should carefully review the rules and
|
||||
regulations of the exchanges offering the system and/or listing the instruments you intend to trade. Online trading
|
||||
has inherent risk due to system response and access times that may vary due to market conditions, system
|
||||
performance, and other factors. You should understand these and additional risks before trading.</p>
|
||||
<p> 5. Compliance with tax obligations </p>
|
||||
<p> The users of the Software are solely responsible to determinate what, if any, taxes apply to their
|
||||
crypto-currency transactions. The owners of, or contributors to, the Software are NOT responsible for determining
|
||||
the taxes that apply to crypto-currency transactions. </p>
|
||||
<p> 6. No warranties </p>
|
||||
<p> The Software is provided on an "as is" basis without any warranties of any kind regarding the
|
||||
Software and/or any content, data, materials and/or services provided on the Software.
|
||||
</p>
|
||||
<p> 7. Limitation of liability</p>
|
||||
<p> Unless otherwise required by law, in no event shall the owners of, or contributors to, the Software be
|
||||
liable for any damages of any kind, including, but not limited to, loss of use, loss of profits, or loss of data
|
||||
arising out of or in any way connected with the use of the Software. In no way are the owners of, or contributors
|
||||
to, the Software responsible for the actions, decisions, or other behavior taken or not taken by you in reliance
|
||||
upon the Software.</p>
|
||||
<p> 8. Last amendment</p>
|
||||
<p> This disclaimer was amended for the last time on October 1st, 2020.</p></body>
|
||||
</html>
|
||||
""".trimIndent()
|
||||
|
|
@ -31,7 +31,6 @@ import com.tangem.domain.wallets.repository.WalletsRepository
|
|||
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
|
||||
import com.tangem.feature.qrscanning.QrScanningRouter
|
||||
import com.tangem.features.details.DetailsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
|
||||
import com.tangem.features.send.api.navigation.SendRouter
|
||||
import com.tangem.features.staking.api.navigation.StakingRouter
|
||||
|
|
@ -87,7 +86,6 @@ data class DaggerGraphState(
|
|||
val urlOpener: UrlOpener? = null,
|
||||
val shareManager: ShareManager? = null,
|
||||
val appRouter: AppRouter? = null,
|
||||
val pushNotificationsFeatureToggles: PushNotificationsFeatureToggles? = null,
|
||||
val pushNotificationsRouter: PushNotificationsRouter? = null,
|
||||
val homeFeatureToggles: HomeFeatureToggles? = null,
|
||||
val getUserCountryUseCase: GetUserCountryUseCase? = null,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.features.disclaimer.api.components.DisclaimerComponent
|
|||
import com.tangem.features.managetokens.ManageTokensToggles
|
||||
import com.tangem.features.managetokens.component.ManageTokensComponent
|
||||
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
|
||||
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
|
||||
import com.tangem.features.send.api.navigation.SendRouter
|
||||
import com.tangem.features.staking.api.navigation.StakingRouter
|
||||
|
|
@ -28,7 +27,6 @@ import com.tangem.tap.features.details.ui.details.DetailsFragment
|
|||
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.disclaimer.ui.DisclaimerFragment
|
||||
import com.tangem.tap.features.home.HomeFragment
|
||||
import com.tangem.tap.features.main.ui.ModalNotificationBottomSheetFragment
|
||||
import com.tangem.tap.features.onboarding.products.note.OnboardingNoteFragment
|
||||
|
|
@ -59,7 +57,6 @@ internal class ChildFactory @Inject constructor(
|
|||
private val stakingRouter: StakingRouter,
|
||||
private val testerRouter: TesterRouter,
|
||||
private val detailsFeatureToggles: DetailsFeatureToggles,
|
||||
private val pushNotificationsFeatureToggles: PushNotificationsFeatureToggles,
|
||||
private val manageTokensToggles: ManageTokensToggles,
|
||||
private val pushNotificationRouter: PushNotificationsRouter,
|
||||
) {
|
||||
|
|
@ -111,15 +108,11 @@ internal class ChildFactory @Inject constructor(
|
|||
route.asFragmentChild(Provider { SecurityModeFragment() })
|
||||
}
|
||||
is AppRoute.Disclaimer -> {
|
||||
if (pushNotificationsFeatureToggles.isPushNotificationsEnabled) {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = DisclaimerComponent.Params(route.isTosAccepted),
|
||||
componentFactory = disclaimerComponentFactory,
|
||||
)
|
||||
} else {
|
||||
route.asFragmentChild(Provider { DisclaimerFragment() })
|
||||
}
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = DisclaimerComponent.Params(route.isTosAccepted),
|
||||
componentFactory = disclaimerComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.Home -> {
|
||||
route.asFragmentChild(Provider { HomeFragment() })
|
||||
|
|
|
|||
|
|
@ -1,129 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/coordinator_details_confirm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/background_secondary"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
style="@style/Widget.MaterialComponents.Toolbar.Surface"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/background_secondary"
|
||||
android:fitsSystemWindows="true"
|
||||
app:liftOnScroll="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:navigationIcon="@drawable/ic_baseline_arrow_back_24"
|
||||
app:navigationIconTint="@color/icon_primary_1"
|
||||
app:titleTextColor="@color/text_primary_1"
|
||||
app:title="@string/disclaimer_title" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_details_confirm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/background_secondary"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<WebView
|
||||
android:id="@+id/web_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="74dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/btn_accept"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/half_transparent_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="110dp"
|
||||
android:background="@drawable/bg_half_transparent_overlay"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_error"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:lineSpacingExtra="5sp"
|
||||
android:text="@string/disclaimer_error_loading"
|
||||
android:textAlignment="center"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_repeat"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_repeat"
|
||||
style="@style/TapSecondaryButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/common_retry"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_error" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_accept"
|
||||
style="@style/TapPrimaryButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/common_accept"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_error"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="btn_repeat, tv_error" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_loading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="progress" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_accept"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="btn_accept, half_transparent_overlay" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -19,10 +19,6 @@
|
|||
"name": "DETAILS_REDESIGN_ENABLED",
|
||||
"version": "5.13.0"
|
||||
},
|
||||
{
|
||||
"name": "PUSH_NOTIFICATIONS_ENABLED",
|
||||
"version": "5.13.0"
|
||||
},
|
||||
{
|
||||
"name": "MARKETS_ENABLED",
|
||||
"version": "5.15.0"
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
package com.tangem.features.pushnotifications.api.featuretoggles
|
||||
|
||||
/**
|
||||
* Push notifications feature toggles
|
||||
*/
|
||||
interface PushNotificationsFeatureToggles {
|
||||
/** Availability of push notifications */
|
||||
val isPushNotificationsEnabled: Boolean
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package com.tangem.features.pushnotifications.impl.di
|
||||
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.impl.featuretoggles.DefaultPushNotificationsFeatureToggles
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* DI module provides implementation of [PushNotificationsFeatureToggles]
|
||||
*/
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object PushNotificationsFeatureTogglesModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSendFeatureToggles(featureTogglesManager: FeatureTogglesManager): PushNotificationsFeatureToggles {
|
||||
return DefaultPushNotificationsFeatureToggles(featureTogglesManager = featureTogglesManager)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package com.tangem.features.pushnotifications.impl.featuretoggles
|
||||
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
|
||||
|
||||
internal class DefaultPushNotificationsFeatureToggles(
|
||||
private val featureTogglesManager: FeatureTogglesManager,
|
||||
) : PushNotificationsFeatureToggles {
|
||||
override val isPushNotificationsEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled("PUSH_NOTIFICATIONS_ENABLED")
|
||||
}
|
||||
|
|
@ -28,7 +28,6 @@ import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSend
|
|||
import com.tangem.feature.wallet.presentation.wallet.utils.ScreenLifecycleProvider
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
|
||||
import com.tangem.features.markets.MarketsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
||||
import com.tangem.features.pushnotifications.api.utils.getPushPermissionOrNull
|
||||
import com.tangem.utils.Provider
|
||||
|
|
@ -67,7 +66,6 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val walletNameMigrationUseCase: WalletNameMigrationUseCase,
|
||||
private val refreshMultiCurrencyWalletQuotesUseCase: RefreshMultiCurrencyWalletQuotesUseCase,
|
||||
private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase,
|
||||
private val pushNotificationsFeatureToggles: PushNotificationsFeatureToggles,
|
||||
private val marketsFeatureToggles: MarketsFeatureToggles,
|
||||
analyticsEventsHandler: AnalyticsEventHandler,
|
||||
) : ViewModel() {
|
||||
|
|
@ -166,10 +164,9 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
private fun subscribeOnPushNotificationsPermission() {
|
||||
viewModelScope.launch {
|
||||
val isPushToggled = pushNotificationsFeatureToggles.isPushNotificationsEnabled
|
||||
val shouldRequestPush = shouldAskPermissionUseCase(PUSH_PERMISSION)
|
||||
val isPushPermissionAvailable = getPushPermissionOrNull() != null
|
||||
if (!isPushToggled || !shouldRequestPush || !isPushPermissionAvailable) return@launch
|
||||
if (!shouldRequestPush || !isPushPermissionAvailable) return@launch
|
||||
|
||||
delay(timeMillis = 1_800)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue