Updated on 2026-08-14

This commit is contained in:
Tangem 2023-09-14 15:44:42 +04:00
parent f95a3b8fcc
commit bdfd2fc8ad
11 changed files with 80 additions and 11 deletions

View file

@ -1,11 +1,14 @@
package com.tangem.tap
import android.app.Application
import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope
@ -14,6 +17,7 @@ import com.google.android.material.snackbar.Snackbar
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.data.card.sdk.CardSdkLifecycleObserver
import com.tangem.domain.apptheme.model.AppThemeMode
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager
@ -127,9 +131,13 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
if (!isDarkThemeFeatureEnabled(application)) {
setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
super.onCreate(savedInstanceState)
bootstrapMainStateUpdates()
bootstrapMainStateUpdates(application)
splashScreen.setKeepOnScreenCondition { isInitializing }
@ -165,6 +173,11 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
)
}
private fun isDarkThemeFeatureEnabled(application: Application): Boolean {
val featureToggle = (application as TapApplication).darkThemeFeatureToggle
return featureToggle.isDarkThemeEnabled
}
override fun onStart() {
super.onStart()
dialogManager.onStart(this)
@ -216,14 +229,25 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
store.dispatch(GlobalAction.UpdateUserWalletsListManager(manager))
}
private fun bootstrapMainStateUpdates() {
private fun bootstrapMainStateUpdates(application: Application) {
viewModel.state
.onEach { state ->
isInitializing = state is GlobalSettingsState.Loading
when (state) {
is GlobalSettingsState.Content -> {
MutableAppThemeModeHolder.value = state.appThemeMode
if (isDarkThemeFeatureEnabled(application)) {
MutableAppThemeModeHolder.value = state.appThemeMode
val mode = when (state.appThemeMode) {
AppThemeMode.FORCE_DARK -> AppCompatDelegate.MODE_NIGHT_YES
AppThemeMode.FORCE_LIGHT -> AppCompatDelegate.MODE_NIGHT_NO
AppThemeMode.FOLLOW_SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
setDefaultNightMode(mode)
} else {
MutableAppThemeModeHolder.value = AppThemeMode.FORCE_LIGHT
}
}
is GlobalSettingsState.Loading -> Unit
}

View file

@ -62,6 +62,7 @@ import com.tangem.tap.domain.walletStores.repository.di.provideDefaultImplementa
import com.tangem.tap.domain.walletconnect.WalletConnectRepository
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectSessionsRepository
import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles
import com.tangem.tap.features.details.DarkThemeFeatureToggle
import com.tangem.tap.features.details.featuretoggles.DetailsFeatureToggles
import com.tangem.tap.proxy.AppStateHolder
import com.tangem.tap.proxy.redux.DaggerGraphState
@ -180,6 +181,9 @@ class TapApplication : Application(), ImageLoaderFactory {
@Inject
lateinit var detailsFeatureToggles: DetailsFeatureToggles
@Inject
lateinit var darkThemeFeatureToggle: DarkThemeFeatureToggle
override fun onCreate() {
super.onCreate()

View file

@ -0,0 +1,10 @@
package com.tangem.tap.features.details
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
class DarkThemeFeatureToggle(
private val featureTogglesManager: FeatureTogglesManager,
) {
val isDarkThemeEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = "DARK_THEME_ENABLED")
}

View file

@ -1,7 +1,7 @@
package com.tangem.tap.features.details.redux
import com.tangem.core.ui.extensions.TextReference
import androidx.lifecycle.LifecycleCoroutineScope
import com.tangem.core.ui.extensions.TextReference
import com.tangem.domain.apptheme.model.AppThemeMode
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.models.scan.CardDTO
@ -13,6 +13,7 @@ sealed class DetailsAction : Action {
data class PrepareScreen(
val scanResponse: ScanResponse,
val darkThemeSwitchEnabled: Boolean,
) : DetailsAction()
object ReCreateTwinsWallet : DetailsAction()

View file

@ -73,6 +73,7 @@ private fun handlePrepareScreen(action: DetailsAction.PrepareScreen): DetailsSta
saveAccessCodes = preferencesStorage.shouldSaveAccessCodes,
selectedFiatCurrency = store.state.globalState.appCurrency,
selectedThemeMode = store.state.globalState.appThemeMode,
darkThemeSwitchEnabled = action.darkThemeSwitchEnabled,
),
)
}

View file

@ -60,6 +60,7 @@ data class AppSettingsState(
val isInProgress: Boolean = false,
val selectedFiatCurrency: FiatCurrency = FiatCurrency.Default,
val selectedThemeMode: AppThemeMode = AppThemeMode.DEFAULT,
val darkThemeSwitchEnabled: Boolean = false,
)
enum class SecurityOption { LongTap, PassCode, AccessCode }

View file

@ -99,9 +99,11 @@ internal class AppSettingsViewModel(
).let(::add)
}
itemsFactory.createSelectThemeModeButton(state.selectedThemeMode) {
showThemeModeSelector(state.selectedThemeMode)
}.let(::add)
if (state.darkThemeSwitchEnabled) {
itemsFactory.createSelectThemeModeButton(state.selectedThemeMode) {
showThemeModeSelector(state.selectedThemeMode)
}.let(::add)
}
}
return items.toImmutableList()

View file

@ -9,6 +9,7 @@ import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.common.analytics.events.Settings
import com.tangem.tap.features.details.DarkThemeFeatureToggle
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.store
import com.tangem.wallet.R
@ -19,13 +20,17 @@ import javax.inject.Inject
@AndroidEntryPoint
internal class DetailsFragment : ComposeFragment(), StoreSubscriber<DetailsState> {
private val detailsViewModel = DetailsViewModel(store)
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
lateinit var darkThemeFeatureToggle: DarkThemeFeatureToggle
private lateinit var detailsViewModel: DetailsViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
detailsViewModel = DetailsViewModel(store, darkThemeFeatureToggle)
Analytics.send(Settings.ScreenOpened())
}

View file

@ -16,6 +16,7 @@ import com.tangem.tap.common.feedback.FeedbackEmail
import com.tangem.tap.common.feedback.SupportInfo
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.features.details.DarkThemeFeatureToggle
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
@ -35,7 +36,10 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.rekotlin.Store
internal class DetailsViewModel(private val store: Store<AppState>) {
internal class DetailsViewModel(
private val store: Store<AppState>,
private val darkThemeFeatureToggle: DarkThemeFeatureToggle,
) { // TODO: change to Android ViewModel
var detailsScreenState: MutableState<DetailsScreenState> = mutableStateOf(updateState(store.state.detailsState))
private set
@ -180,7 +184,12 @@ internal class DetailsViewModel(private val store: Store<AppState>) {
userWalletsListManager.selectedUserWallet
.distinctUntilChanged()
.onEach { selectedUserWallet ->
store.dispatchWithMain(DetailsAction.PrepareScreen(selectedUserWallet.scanResponse))
store.dispatchWithMain(
DetailsAction.PrepareScreen(
selectedUserWallet.scanResponse,
darkThemeFeatureToggle.isDarkThemeEnabled,
),
)
}
.flowOn(Dispatchers.IO)
.launchIn(scope)

View file

@ -2,6 +2,7 @@ package com.tangem.tap.proxy.di
import com.tangem.common.Provider
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.common.util.cardTypesResolver
@ -9,6 +10,7 @@ import com.tangem.feature.learn2earn.domain.api.Learn2earnDependencyProvider
import com.tangem.lib.crypto.DerivationManager
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.UserWalletManager
import com.tangem.tap.features.details.DarkThemeFeatureToggle
import com.tangem.tap.proxy.*
import dagger.Module
import dagger.Provides
@ -58,6 +60,12 @@ class ProxyModule {
)
}
@Provides
@Singleton
fun provideDarkThemeFeatureToggle(featureTogglesManager: FeatureTogglesManager): DarkThemeFeatureToggle {
return DarkThemeFeatureToggle(featureTogglesManager)
}
// regions FeatureConsumers
@Provides
@Singleton

View file

@ -26,5 +26,9 @@
{
"name": "REDESIGNED_APP_CURRENCY_SELECTOR_ENABLED",
"version": "undefined"
},
{
"name": "DARK_THEME_ENABLED",
"version": "undefined"
}
]