Updated on 2026-08-14
This commit is contained in:
parent
21b514caa1
commit
f3e8deb60a
24 changed files with 334 additions and 221 deletions
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.tap.common.apptheme
|
||||
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
|
||||
internal object MutableAppThemeModeHolder : AppThemeModeHolder {
|
||||
|
||||
override val appThemeMode: MutableState<AppThemeMode> = mutableStateOf(AppThemeMode.DEFAULT)
|
||||
|
||||
var value: AppThemeMode
|
||||
set(value) {
|
||||
appThemeMode.value = value
|
||||
}
|
||||
get() = appThemeMode.value
|
||||
}
|
||||
18
app/src/main/java/com/tangem/tap/di/ThemeModule.kt
Normal file
18
app/src/main/java/com/tangem/tap/di/ThemeModule.kt
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.tap.di
|
||||
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.components.ActivityComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(ActivityComponent::class)
|
||||
internal object ThemeModule {
|
||||
|
||||
@Provides
|
||||
fun provideAppThemeModeHolder(): AppThemeModeHolder {
|
||||
return MutableAppThemeModeHolder
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import android.webkit.WebView
|
|||
import androidx.transition.TransitionInflater
|
||||
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.ui.fragments.setStatusBarColor
|
||||
import com.tangem.core.ui.extensions.setStatusBarColor
|
||||
import com.tangem.tap.common.extensions.beginDelayedTransition
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
import com.tangem.tap.common.extensions.show
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.common.extensions.VoidCallback
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.navigation.ShareElement
|
||||
import com.tangem.core.ui.fragments.setStatusBarColor
|
||||
import com.tangem.core.ui.extensions.setStatusBarColor
|
||||
import com.tangem.datasource.asset.AssetReader
|
||||
import com.tangem.domain.common.TwinCardNumber
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
|
|
|
|||
|
|
@ -6,24 +6,27 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.SnackbarHost
|
||||
import androidx.compose.material.SnackbarHostState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.tangem.core.ui.fragments.ComposeBottomSheetFragment
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeBottomSheetFragment
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.tap.features.details.ui.cardsettings.resolveReference
|
||||
import com.tangem.tap.features.saveWallet.ui.components.EnrollBiometricsDialogContent
|
||||
import com.tangem.tap.features.saveWallet.ui.components.SaveWalletScreenContent
|
||||
import com.tangem.tap.features.saveWallet.ui.models.EnrollBiometricsDialog
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
internal class SaveWalletBottomSheetFragment : ComposeBottomSheetFragment() {
|
||||
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
internal class SaveWalletBottomSheetFragment : ComposeBottomSheetFragment<SaveWalletScreenState>() {
|
||||
override val expandedHeightFraction: Float = .98f
|
||||
|
||||
private val viewModel by viewModels<SaveWalletViewModel>()
|
||||
|
|
@ -34,12 +37,8 @@ internal class SaveWalletBottomSheetFragment : ComposeBottomSheetFragment<SaveWa
|
|||
}
|
||||
|
||||
@Composable
|
||||
override fun provideState(): State<SaveWalletScreenState> {
|
||||
return viewModel.state.collectAsState()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(state: SaveWalletScreenState, modifier: Modifier) {
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference())
|
||||
val enrollBiometricsDialog by rememberUpdatedState(newValue = state.enrollBiometricsDialog)
|
||||
|
|
|
|||
|
|
@ -6,14 +6,24 @@ import androidx.activity.viewModels
|
|||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.ui.fragments.ComposeActivity
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeActivity
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.tap.common.analytics.events.Chat
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
internal class SprinklrActivity : ComposeActivity() {
|
||||
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
internal class SprinklrActivity : ComposeActivity<SprinklrScreenState>() {
|
||||
private val viewModel by viewModels<SprinklrViewModel>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
@ -25,12 +35,14 @@ internal class SprinklrActivity : ComposeActivity<SprinklrScreenState>() {
|
|||
}
|
||||
|
||||
@Composable
|
||||
override fun provideState(): State<SprinklrScreenState> {
|
||||
return viewModel.state.collectAsState()
|
||||
}
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
|
||||
val systemBarsColor = TangemTheme.colors.background.primary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(systemBarsColor)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(state: SprinklrScreenState, modifier: Modifier) {
|
||||
BackHandler(onBack = state.onNavigateBack)
|
||||
SprinklrScreenContent(
|
||||
modifier = modifier
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import com.badoo.mvicore.modelWatcher
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.core.ui.fragments.setStatusBarColor
|
||||
import com.tangem.core.ui.extensions.setStatusBarColor
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.OneTouchClickListener
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
|
|
|
|||
|
|
@ -13,19 +13,26 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.ui.components.wallets.RenameWalletDialogContent
|
||||
import com.tangem.core.ui.fragments.ComposeBottomSheetFragment
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeBottomSheetFragment
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.tap.common.analytics.events.MyWallets
|
||||
import com.tangem.tap.features.details.ui.cardsettings.resolveReference
|
||||
import com.tangem.tap.features.walletSelector.ui.components.*
|
||||
import com.tangem.tap.features.walletSelector.ui.model.DialogModel
|
||||
import com.tangem.tap.features.walletSelector.ui.model.WarningModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
internal class WalletSelectorBottomSheetFragment : ComposeBottomSheetFragment<WalletSelectorScreenState>() {
|
||||
internal class WalletSelectorBottomSheetFragment : ComposeBottomSheetFragment() {
|
||||
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
private val viewModel by viewModels<WalletSelectorViewModel>()
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
|
|
@ -35,10 +42,8 @@ internal class WalletSelectorBottomSheetFragment : ComposeBottomSheetFragment<Wa
|
|||
}
|
||||
|
||||
@Composable
|
||||
override fun provideState(): State<WalletSelectorScreenState> = viewModel.state.collectAsState()
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(state: WalletSelectorScreenState, modifier: Modifier) {
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference())
|
||||
val dialog by rememberUpdatedState(newValue = state.dialog)
|
||||
|
|
|
|||
|
|
@ -1,35 +1,36 @@
|
|||
package com.tangem.tap.features.welcome.ui
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.material.SnackbarHost
|
||||
import androidx.compose.material.SnackbarHostState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.fragments.ComposeFragment
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeFragment
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.tap.common.analytics.events.SignIn
|
||||
import com.tangem.tap.common.extensions.eraseContext
|
||||
import com.tangem.tap.features.details.ui.cardsettings.resolveReference
|
||||
import com.tangem.tap.features.welcome.ui.components.WarningDialog
|
||||
import com.tangem.tap.features.welcome.ui.components.WelcomeScreenContent
|
||||
import com.tangem.wallet.R
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class WelcomeFragment : ComposeFragment<WelcomeScreenState>() {
|
||||
@AndroidEntryPoint
|
||||
internal class WelcomeFragment : ComposeFragment() {
|
||||
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
private val viewModel by viewModels<WelcomeViewModel>()
|
||||
|
||||
|
|
@ -40,19 +41,15 @@ internal class WelcomeFragment : ComposeFragment<WelcomeScreenState>() {
|
|||
}
|
||||
|
||||
@Composable
|
||||
override fun provideState(): State<WelcomeScreenState> {
|
||||
return viewModel.state.collectAsState()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(state: WelcomeScreenState, modifier: Modifier) {
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference())
|
||||
val warning by rememberUpdatedState(newValue = state.warning)
|
||||
|
||||
val backgroundColor = colorResource(id = R.color.background_primary)
|
||||
val backgroundColor = TangemTheme.colors.background.primary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(color = backgroundColor)
|
||||
setSystemBarsColor(backgroundColor)
|
||||
}
|
||||
|
||||
BackHandler {
|
||||
|
|
@ -61,7 +58,8 @@ internal class WelcomeFragment : ComposeFragment<WelcomeScreenState>() {
|
|||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.systemBarsPadding(),
|
||||
.systemBarsPadding()
|
||||
.background(backgroundColor),
|
||||
) {
|
||||
WelcomeScreenContent(
|
||||
showUnlockProgress = state.showUnlockWithBiometricsProgress,
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="AppTheme" parent="BaseAppTheme">
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="BaseAppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
|
||||
<style name="BaseAppTheme" parent="Theme.MaterialComponents.Light.NoActionBar" />
|
||||
|
||||
<style name="AppTheme" parent="BaseAppTheme">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="android:textColor">@color/darkGray6</item>
|
||||
|
|
@ -10,8 +11,6 @@
|
|||
<item name="materialCardViewStyle">@style/Widget.AppTheme.CardView</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme" parent="BaseAppTheme" />
|
||||
|
||||
<style name="SplashTheme" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/background_splash</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/inset_splash</item>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ plugins {
|
|||
dependencies {
|
||||
/** Project - Domain */
|
||||
implementation(projects.domain.tokens.models)
|
||||
implementation(projects.domain.appTheme.models)
|
||||
|
||||
/** Project - Core */
|
||||
implementation(projects.core.res)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.core.ui.fragments
|
||||
package com.tangem.core.ui.extensions
|
||||
|
||||
import android.view.WindowManager
|
||||
import androidx.annotation.ColorRes
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package com.tangem.core.ui.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
abstract class ComposeActivity<ScreenState> : AppCompatActivity(), ComposeScreen<ScreenState> {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(createComposeView(context = this))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
package com.tangem.core.ui.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
abstract class ComposeFragment<ScreenState> : Fragment(), ComposeScreen<ScreenState> {
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return createComposeView(inflater.context)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package com.tangem.core.ui.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
internal interface ComposeScreen<ScreenState> {
|
||||
fun createComposeView(context: Context): View {
|
||||
return ComposeView(context).apply {
|
||||
setContent {
|
||||
TangemTheme {
|
||||
val backgroundColor = TangemTheme.colors.background.primary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(
|
||||
color = backgroundColor,
|
||||
)
|
||||
}
|
||||
|
||||
ScreenContent(
|
||||
state = provideState().value,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(color = backgroundColor),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("TopLevelComposableFunctions")
|
||||
@Composable
|
||||
fun provideState(): State<ScreenState>
|
||||
|
||||
@Suppress("TopLevelComposableFunctions")
|
||||
@Composable
|
||||
fun ScreenContent(state: ScreenState, modifier: Modifier)
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.core.ui.screen
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
|
||||
/**
|
||||
* An abstract base class for activities that use Compose for UI rendering.
|
||||
* Extends [ComponentActivity] and implements [ComposeScreen] interface.
|
||||
*/
|
||||
abstract class ComposeActivity : ComponentActivity(), ComposeScreen {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(createComposeView(context = this))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.core.ui.fragments
|
||||
package com.tangem.core.ui.screen
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
|
@ -10,20 +9,46 @@ import androidx.annotation.FloatRange
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
abstract class ComposeBottomSheetFragment<ScreenState> : BottomSheetDialogFragment(), ComposeScreen<ScreenState> {
|
||||
/**
|
||||
* An abstract base class for bottom sheet dialogs that use Compose for UI rendering.
|
||||
* Extends [BottomSheetDialogFragment] and implements [ComposeScreen] interface.
|
||||
*/
|
||||
abstract class ComposeBottomSheetFragment : BottomSheetDialogFragment(), ComposeScreen {
|
||||
|
||||
/**
|
||||
* The initial state of the bottom sheet. Default is [BottomSheetBehavior.STATE_EXPANDED].
|
||||
*/
|
||||
open val initialBottomSheetState = BottomSheetBehavior.STATE_EXPANDED
|
||||
|
||||
/**
|
||||
* The fraction of the screen height that the bottom sheet should take when expanded.
|
||||
* Default is `null`, indicating that the height will be determined by the content.
|
||||
*/
|
||||
@FloatRange(from = 0.0, to = 1.0)
|
||||
open val expandedHeightFraction: Float? = null
|
||||
|
||||
override val screenModifier: Modifier
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = Modifier
|
||||
.fillMaxWidth()
|
||||
.let {
|
||||
if (expandedHeightFraction != null) it.fillMaxHeight(expandedHeightFraction!!) else it
|
||||
}
|
||||
.background(
|
||||
color = TangemTheme.colors.background.plain,
|
||||
shape = TangemTheme.shapes.bottomSheet,
|
||||
)
|
||||
|
||||
override fun getTheme(): Int = R.style.AppTheme_TransparentBottomSheetDialog
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
|
|
@ -40,25 +65,4 @@ abstract class ComposeBottomSheetFragment<ScreenState> : BottomSheetDialogFragme
|
|||
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun createComposeView(context: Context): View {
|
||||
return ComposeView(context).apply {
|
||||
setContent {
|
||||
TangemTheme {
|
||||
ScreenContent(
|
||||
state = provideState().value,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.let {
|
||||
if (expandedHeightFraction != null) it.fillMaxHeight(expandedHeightFraction!!) else it
|
||||
}
|
||||
.background(
|
||||
color = TangemTheme.colors.background.plain,
|
||||
shape = TangemTheme.shapes.bottomSheet,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.tangem.core.ui.screen
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.core.ui.R
|
||||
|
||||
/**
|
||||
* An abstract base class for fragments that use Compose for UI rendering.
|
||||
* Extends [Fragment] and implements [ComposeScreen] interface.
|
||||
*/
|
||||
abstract class ComposeFragment : Fragment(), ComposeScreen {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
val isTransitionsInflated = TransitionInflater.from(requireContext()).inflateTransitions()
|
||||
|
||||
return createComposeView(inflater.context).also {
|
||||
it.isTransitionGroup = isTransitionsInflated
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflates transitions for the fragment. Override this method to customize
|
||||
* enter and exit transitions for the fragment.
|
||||
*
|
||||
* @return `true` if transitions were inflated; `false` otherwise.
|
||||
*/
|
||||
protected open fun TransitionInflater.inflateTransitions(): Boolean {
|
||||
enterTransition = inflateTransition(R.transition.slide_right)
|
||||
exitTransition = inflateTransition(R.transition.fade)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.tangem.core.ui.screen
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
|
||||
/**
|
||||
* Interface representing a Compose screen with common theming and content composition properties.
|
||||
*
|
||||
* This interface defines properties and functions that allow a Compose screen to manage its theme,
|
||||
* background color, and screen modifier. It also provides a composable function to define the content
|
||||
* of the screen.
|
||||
*/
|
||||
internal interface ComposeScreen {
|
||||
|
||||
/**
|
||||
* The holder for managing the current application theme mode.
|
||||
*/
|
||||
val appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
/**
|
||||
* The screen modifier.
|
||||
*/
|
||||
val screenModifier: Modifier
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = Modifier.fillMaxSize()
|
||||
|
||||
/**
|
||||
* Composable function to define the content of the screen.
|
||||
*
|
||||
* @param modifier The modifier to apply to the screen content.
|
||||
*/
|
||||
@Suppress("TopLevelComposableFunctions")
|
||||
@Composable
|
||||
fun ScreenContent(modifier: Modifier)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [ComposeView] with the defined content for the Compose screen.
|
||||
*
|
||||
* @param context The context.
|
||||
* @return A [ComposeView] instance with the defined screen content.
|
||||
*/
|
||||
internal fun ComposeScreen.createComposeView(context: Context): ComposeView {
|
||||
return ComposeView(context).apply {
|
||||
setContent {
|
||||
val appThemeMode by appThemeModeHolder.appThemeMode
|
||||
|
||||
TangemTheme(isDark = shouldUseDarkTheme(appThemeMode)) {
|
||||
ScreenContent(modifier = screenModifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the dark theme should be used based on the given [AppThemeMode].
|
||||
*
|
||||
* @param appThemeMode The application theme mode.
|
||||
* @return `true` if the dark theme should be used, `false` otherwise.
|
||||
*/
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun shouldUseDarkTheme(appThemeMode: AppThemeMode): Boolean {
|
||||
return when (appThemeMode) {
|
||||
AppThemeMode.FORCE_DARK -> true
|
||||
AppThemeMode.FORCE_LIGHT -> false
|
||||
AppThemeMode.FOLLOW_SYSTEM -> isSystemInDarkTheme()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.core.ui.theme
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
|
||||
/**
|
||||
* Representing a holder for the application theme mode.
|
||||
*/
|
||||
@Stable
|
||||
interface AppThemeModeHolder {
|
||||
|
||||
/**
|
||||
* A [State] representing the current application theme mode.
|
||||
*/
|
||||
val appThemeMode: State<AppThemeMode>
|
||||
}
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
package com.tangem.feature.tester.presentation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeActivity
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.feature.tester.presentation.actions.TesterActionsScreen
|
||||
import com.tangem.feature.tester.presentation.actions.TesterActionsViewModel
|
||||
import com.tangem.feature.tester.presentation.featuretoggles.ui.FeatureTogglesScreen
|
||||
|
|
@ -24,7 +24,10 @@ import javax.inject.Inject
|
|||
|
||||
/** Activity for testers */
|
||||
@AndroidEntryPoint
|
||||
internal class TesterActivity : ComponentActivity() {
|
||||
internal class TesterActivity : ComposeActivity() {
|
||||
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
/** Router for inner feature navigation */
|
||||
@Inject
|
||||
|
|
@ -35,19 +38,14 @@ internal class TesterActivity : ComponentActivity() {
|
|||
"TesterRouter must be InnerTesterRouter for tester feature"
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContent {
|
||||
TangemTheme {
|
||||
val statusBarColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setStatusBarColor(color = statusBarColor)
|
||||
}
|
||||
|
||||
TesterNavHost()
|
||||
}
|
||||
@Composable
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(systemBarsColor)
|
||||
}
|
||||
|
||||
TesterNavHost()
|
||||
}
|
||||
|
||||
@Suppress("TopLevelComposableFunctions")
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
package com.tangem.feature.tokendetails.presentation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeFragment
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.TokenDetailsScreen
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsViewModel
|
||||
|
|
@ -18,7 +16,10 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
internal class TokenDetailsFragment : Fragment() {
|
||||
internal class TokenDetailsFragment : ComposeFragment() {
|
||||
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
@Inject
|
||||
lateinit var tokenDetailsRouter: TokenDetailsRouter
|
||||
|
|
@ -28,21 +29,18 @@ internal class TokenDetailsFragment : Fragment() {
|
|||
"internalTokenDetailsRouter should be instance of InnerTokenDetailsRouter"
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return ComposeView(inflater.context).apply {
|
||||
setContent {
|
||||
TangemTheme {
|
||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(systemBarsColor)
|
||||
}
|
||||
@Composable
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val viewModel = hiltViewModel<TokenDetailsViewModel>()
|
||||
viewModel.router = this@TokenDetailsFragment.internalTokenDetailsRouter
|
||||
|
||||
val viewModel = hiltViewModel<TokenDetailsViewModel>()
|
||||
viewModel.router = this@TokenDetailsFragment.internalTokenDetailsRouter
|
||||
LocalLifecycleOwner.current.lifecycle.addObserver(viewModel)
|
||||
TokenDetailsScreen(state = viewModel.uiState)
|
||||
}
|
||||
}
|
||||
LocalLifecycleOwner.current.lifecycle.addObserver(viewModel)
|
||||
|
||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(systemBarsColor)
|
||||
}
|
||||
|
||||
TokenDetailsScreen(state = viewModel.uiState)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,11 @@
|
|||
package com.tangem.feature.wallet.presentation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.core.ui.screen.ComposeFragment
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.feature.wallet.presentation.router.InnerWalletRouter
|
||||
import com.tangem.features.wallet.navigation.WalletRouter
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
|
@ -21,7 +17,10 @@ import javax.inject.Inject
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
internal class WalletFragment : Fragment() {
|
||||
internal class WalletFragment : ComposeFragment() {
|
||||
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
/** Feature router */
|
||||
@Inject
|
||||
|
|
@ -32,25 +31,14 @@ internal class WalletFragment : Fragment() {
|
|||
"_walletRouter should be instance of InnerWalletRouter"
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
with(TransitionInflater.from(requireContext())) {
|
||||
enterTransition = inflateTransition(R.transition.slide_right)
|
||||
exitTransition = inflateTransition(R.transition.fade)
|
||||
@Composable
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(systemBarsColor)
|
||||
}
|
||||
|
||||
return ComposeView(inflater.context).apply {
|
||||
setContent {
|
||||
TangemTheme {
|
||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(systemBarsColor)
|
||||
}
|
||||
|
||||
isTransitionGroup = true
|
||||
_walletRouter.Initialize(fragmentManager = requireActivity().supportFragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
_walletRouter.Initialize(fragmentManager = requireActivity().supportFragmentManager)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue