Updated on 2026-08-14
This commit is contained in:
parent
7a5933253b
commit
2f5ed09224
41 changed files with 414 additions and 320 deletions
|
|
@ -12,15 +12,18 @@ import android.nfc.NfcAdapter
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.activity.SystemBarStyle
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
|
import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import androidx.core.view.WindowCompat
|
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.flowWithLifecycle
|
import androidx.lifecycle.flowWithLifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
|
@ -195,6 +198,13 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
|
||||||
|
|
||||||
installAppTheme() // We need to call it before onCreate to prevent unnecessary activity recreation
|
installAppTheme() // We need to call it before onCreate to prevent unnecessary activity recreation
|
||||||
|
|
||||||
|
enableEdgeToEdge(
|
||||||
|
navigationBarStyle = SystemBarStyle.auto(
|
||||||
|
Color.Transparent.toArgb(),
|
||||||
|
Color.Transparent.toArgb(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
splashScreen.setKeepOnScreenCondition { viewModel.isSplashScreenShown }
|
splashScreen.setKeepOnScreenCondition { viewModel.isSplashScreenShown }
|
||||||
|
|
@ -307,8 +317,6 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
|
||||||
|
|
||||||
@SuppressLint("SourceLockedOrientationActivity")
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
private fun initContent() {
|
private fun initContent() {
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
||||||
|
|
||||||
supportFragmentManager.registerFragmentLifecycleCallbacks(
|
supportFragmentManager.registerFragmentLifecycleCallbacks(
|
||||||
NavBarInsetsFragmentLifecycleCallback(),
|
NavBarInsetsFragmentLifecycleCallback(),
|
||||||
true,
|
true,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package com.tangem.tap.features.customtoken.impl.presentation
|
package com.tangem.tap.features.customtoken.impl.presentation
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.systemBarsPadding
|
import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.screen.ComposeFragment
|
import com.tangem.core.ui.screen.ComposeFragment
|
||||||
import com.tangem.tap.features.customtoken.impl.presentation.ui.AddCustomTokenScreen
|
import com.tangem.tap.features.customtoken.impl.presentation.ui.AddCustomTokenScreen
|
||||||
|
|
@ -30,12 +30,10 @@ internal class AddCustomTokenFragment : ComposeFragment() {
|
||||||
val viewModel = hiltViewModel<AddCustomTokenViewModel>().apply {
|
val viewModel = hiltViewModel<AddCustomTokenViewModel>().apply {
|
||||||
LocalLifecycleOwner.current.lifecycle.addObserver(this)
|
LocalLifecycleOwner.current.lifecycle.addObserver(this)
|
||||||
}
|
}
|
||||||
val statusBarColor = TangemTheme.colors.background.secondary
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(color = statusBarColor)
|
|
||||||
}
|
|
||||||
AddCustomTokenScreen(
|
AddCustomTokenScreen(
|
||||||
modifier = Modifier.systemBarsPadding(),
|
modifier = Modifier
|
||||||
|
.background(TangemTheme.colors.background.primary)
|
||||||
|
.systemBarsPadding(),
|
||||||
stateHolder = viewModel.uiState,
|
stateHolder = viewModel.uiState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.screen.ComposeFragment
|
import com.tangem.core.ui.screen.ComposeFragment
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -22,12 +21,8 @@ internal class AppCurrencySelectorFragment : ComposeFragment() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(systemBarsColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
NavigationBar3ButtonsScrim()
|
||||||
AppCurrencySelectorScreen(
|
AppCurrencySelectorScreen(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
state = uiState,
|
state = uiState,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
@ -40,7 +41,9 @@ internal fun AppCurrencySelectorScreen(state: AppCurrencySelectorState, modifier
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = modifier
|
||||||
|
.imePadding()
|
||||||
|
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
containerColor = TangemTheme.colors.background.secondary,
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBar(
|
TopBar(
|
||||||
|
|
@ -49,6 +52,7 @@ internal fun AppCurrencySelectorScreen(state: AppCurrencySelectorState, modifier
|
||||||
state = state,
|
state = state,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
|
||||||
content = { paddingValues ->
|
content = { paddingValues ->
|
||||||
val contentModifier = Modifier
|
val contentModifier = Modifier
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
|
|
@ -62,7 +66,7 @@ internal fun AppCurrencySelectorScreen(state: AppCurrencySelectorState, modifier
|
||||||
modifier = contentModifier,
|
modifier = contentModifier,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
currencies = state.items,
|
currencies = state.items,
|
||||||
selectedId = state.selectedId.orEmpty(),
|
selectedId = state.selectedId,
|
||||||
onCurrencyClick = state.onCurrencyClick,
|
onCurrencyClick = state.onCurrencyClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -175,6 +179,7 @@ private fun SearchBar(onInputChange: (String) -> Unit, modifier: Modifier = Modi
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun LoadingList(modifier: Modifier = Modifier) {
|
private fun LoadingList(modifier: Modifier = Modifier) {
|
||||||
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
Column(modifier = modifier) {
|
Column(modifier = modifier) {
|
||||||
repeat(times = 10) {
|
repeat(times = 10) {
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -199,6 +204,7 @@ private fun LoadingList(modifier: Modifier = Modifier) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Spacer(Modifier.height(bottomBarHeight))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,9 +216,11 @@ private fun CurrenciesList(
|
||||||
onCurrencyClick: (Currency) -> Unit,
|
onCurrencyClick: (Currency) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
state = listState,
|
state = listState,
|
||||||
|
contentPadding = PaddingValues(bottom = bottomBarHeight),
|
||||||
) {
|
) {
|
||||||
items(
|
items(
|
||||||
items = currencies,
|
items = currencies,
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
package com.tangem.tap.features.details.ui.appsettings
|
package com.tangem.tap.features.details.ui.appsettings
|
||||||
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.systemBars
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||||
|
|
@ -32,6 +36,7 @@ internal fun AppSettingsScreen(state: AppSettingsScreenState, onBackClick: () ->
|
||||||
},
|
},
|
||||||
titleRes = R.string.app_settings_title,
|
titleRes = R.string.app_settings_title,
|
||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
|
addBottomInsets = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,7 +49,11 @@ private fun AppSettings(state: AppSettingsScreenState.Content) {
|
||||||
null -> Unit
|
null -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyColumn {
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
contentPadding = PaddingValues(bottom = bottomBarHeight),
|
||||||
|
) {
|
||||||
items(
|
items(
|
||||||
items = state.items,
|
items = state.items,
|
||||||
key = Item::id,
|
key = Item::id,
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
import com.tangem.wallet.R
|
import com.tangem.wallet.R
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -24,31 +24,42 @@ internal fun SettingsScreensScaffold(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
@StringRes titleRes: Int? = null,
|
@StringRes titleRes: Int? = null,
|
||||||
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
|
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
|
||||||
|
addBottomInsets: Boolean = true,
|
||||||
fab: @Composable () -> Unit = {},
|
fab: @Composable () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val state = rememberScaffoldState(snackbarHostState = snackbarHostState)
|
val state = rememberScaffoldState(snackbarHostState = snackbarHostState)
|
||||||
val backgroundColor = TangemTheme.colors.background.secondary
|
val backgroundColor = TangemTheme.colors.background.secondary
|
||||||
|
|
||||||
BackHandler(onBack = onBackClick)
|
BackHandler(onBack = onBackClick)
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(backgroundColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
scaffoldState = state,
|
scaffoldState = state,
|
||||||
topBar = {
|
topBar = {
|
||||||
EmptyTopBarWithNavigation(
|
EmptyTopBarWithNavigation(
|
||||||
|
modifier = Modifier.statusBarsPadding(),
|
||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = modifier.systemBarsPadding(),
|
modifier = modifier,
|
||||||
|
contentWindowInsets = WindowInsetsZero,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
floatingActionButton = fab,
|
floatingActionButton = {
|
||||||
content = { paddings ->
|
Box(modifier = Modifier.navigationBarsPadding()) {
|
||||||
|
fab()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = { paddingValues ->
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(paddings)
|
.run {
|
||||||
|
if (addBottomInsets) {
|
||||||
|
navigationBarsPadding()
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(paddingValues)
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
) {
|
) {
|
||||||
if (titleRes != null) {
|
if (titleRes != null) {
|
||||||
|
|
@ -81,9 +92,11 @@ internal fun ScreenTitle(titleRes: Int, modifier: Modifier = Modifier) {
|
||||||
@Composable
|
@Composable
|
||||||
internal fun EmptyTopBarWithNavigation(
|
internal fun EmptyTopBarWithNavigation(
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
backgroundColor: Color = TangemTheme.colors.background.primary,
|
backgroundColor: Color = TangemTheme.colors.background.primary,
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
|
modifier = modifier,
|
||||||
title = { },
|
title = { },
|
||||||
navigationIcon =
|
navigationIcon =
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,12 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.core.view.WindowCompat
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.tangem.common.routing.AppRoute
|
import com.tangem.common.routing.AppRoute
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
|
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
import com.tangem.core.ui.components.SystemBarsIconsDisposable
|
||||||
import com.tangem.core.ui.screen.ComposeFragment
|
import com.tangem.core.ui.screen.ComposeFragment
|
||||||
import com.tangem.domain.tokens.TokensAction
|
import com.tangem.domain.tokens.TokensAction
|
||||||
import com.tangem.tap.common.analytics.events.IntroductionProcess
|
import com.tangem.tap.common.analytics.events.IntroductionProcess
|
||||||
|
|
@ -44,15 +42,12 @@ class HomeFragment : ComposeFragment(), StoreSubscriber<HomeState> {
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
BackHandler(onBack = requireActivity()::finish)
|
BackHandler(onBack = requireActivity()::finish)
|
||||||
SystemBarsEffect {
|
SystemBarsIconsDisposable(darkIcons = false)
|
||||||
setSystemBarsColor(color = Color.Transparent, darkIcons = false)
|
|
||||||
}
|
|
||||||
ScreenContent()
|
ScreenContent()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
activity?.window?.let { WindowCompat.setDecorFitsSystemWindows(it, false) }
|
|
||||||
|
|
||||||
store.subscribe(subscriber = this) { state ->
|
store.subscribe(subscriber = this) { state ->
|
||||||
state
|
state
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
package com.tangem.tap.features.tokens.impl.presentation
|
package com.tangem.tap.features.tokens.impl.presentation
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.systemBarsPadding
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
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.screen.ComposeFragment
|
||||||
import com.tangem.tap.features.tokens.impl.presentation.ui.TokensListScreen
|
import com.tangem.tap.features.tokens.impl.presentation.ui.TokensListScreen
|
||||||
import com.tangem.tap.features.tokens.impl.presentation.viewmodels.TokensListViewModel
|
import com.tangem.tap.features.tokens.impl.presentation.viewmodels.TokensListViewModel
|
||||||
|
|
@ -30,12 +27,7 @@ internal class TokensListFragment : ComposeFragment() {
|
||||||
val viewModel = hiltViewModel<TokensListViewModel>().apply {
|
val viewModel = hiltViewModel<TokensListViewModel>().apply {
|
||||||
LocalLifecycleOwner.current.lifecycle.addObserver(this)
|
LocalLifecycleOwner.current.lifecycle.addObserver(this)
|
||||||
}
|
}
|
||||||
val statusBarColor = TangemTheme.colors.background.secondary
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(color = statusBarColor)
|
|
||||||
}
|
|
||||||
TokensListScreen(
|
TokensListScreen(
|
||||||
modifier = Modifier.systemBarsPadding(),
|
|
||||||
stateHolder = viewModel.uiState,
|
stateHolder = viewModel.uiState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import androidx.compose.material.Scaffold
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
|
@ -34,6 +33,8 @@ import androidx.paging.compose.LazyPagingItems
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import androidx.paging.compose.itemContentType
|
import androidx.paging.compose.itemContentType
|
||||||
import androidx.paging.compose.itemKey
|
import androidx.paging.compose.itemKey
|
||||||
|
import com.tangem.core.ui.components.BottomFade
|
||||||
|
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
import com.tangem.core.ui.components.PrimaryButton
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
|
@ -61,32 +62,45 @@ internal fun TokensListScreen(stateHolder: TokensListStateHolder, modifier: Modi
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
topBar = { TokensListToolbar(state = stateHolder.toolbarState) },
|
topBar = {
|
||||||
|
TokensListToolbar(state = stateHolder.toolbarState)
|
||||||
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
if (stateHolder is TokensListStateHolder.ManageContent) {
|
if (stateHolder is TokensListStateHolder.ManageContent) {
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val verticalPadding = TangemTheme.dimens.spacing32
|
val verticalPadding = TangemTheme.dimens.spacing32
|
||||||
|
|
||||||
SaveChangesButton(
|
SaveChangesButton(
|
||||||
modifier = Modifier.onSizeChanged {
|
modifier = Modifier
|
||||||
with(density) { floatingButtonHeight = it.height.toDp() + verticalPadding }
|
.navigationBarsPadding()
|
||||||
},
|
.onSizeChanged {
|
||||||
|
with(density) { floatingButtonHeight = it.height.toDp() + verticalPadding }
|
||||||
|
},
|
||||||
showProgress = stateHolder.isSavingInProgress,
|
showProgress = stateHolder.isSavingInProgress,
|
||||||
onClick = stateHolder.onSaveButtonClick,
|
onClick = stateHolder.onSaveButtonClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
floatingActionButtonPosition = FabPosition.Center,
|
floatingActionButtonPosition = FabPosition.Center,
|
||||||
backgroundColor = TangemTheme.colors.background.primary,
|
backgroundColor = TangemTheme.colors.background.secondary,
|
||||||
) { scaffoldPadding ->
|
) { _ ->
|
||||||
val tokens = stateHolder.tokens.collectAsLazyPagingItems()
|
val tokens = stateHolder.tokens.collectAsLazyPagingItems()
|
||||||
|
|
||||||
TokensListContent(
|
if (stateHolder !is TokensListStateHolder.ManageContent) {
|
||||||
isDifferentAddressesBlockVisible = stateHolder.isDifferentAddressesBlockVisible,
|
NavigationBar3ButtonsScrim()
|
||||||
tokens = tokens,
|
}
|
||||||
scaffoldPadding = scaffoldPadding,
|
|
||||||
bottomMarginDp = floatingButtonHeight,
|
Box {
|
||||||
)
|
TokensListContent(
|
||||||
|
isDifferentAddressesBlockVisible = stateHolder.isDifferentAddressesBlockVisible,
|
||||||
|
tokens = tokens,
|
||||||
|
bottomMarginDp = floatingButtonHeight,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (stateHolder is TokensListStateHolder.ManageContent) {
|
||||||
|
BottomFade(Modifier.align(Alignment.BottomCenter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Crossfade(targetState = stateHolder.isLoading, label = "Update progress bar visibility") {
|
Crossfade(targetState = stateHolder.isLoading, label = "Update progress bar visibility") {
|
||||||
if (it) {
|
if (it) {
|
||||||
|
|
@ -112,23 +126,24 @@ private fun LoadingContent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun TokensListContent(
|
private fun TokensListContent(
|
||||||
isDifferentAddressesBlockVisible: Boolean,
|
isDifferentAddressesBlockVisible: Boolean,
|
||||||
tokens: LazyPagingItems<TokenItemState>,
|
tokens: LazyPagingItems<TokenItemState>,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
bottomMarginDp: Dp,
|
bottomMarginDp: Dp,
|
||||||
) {
|
) {
|
||||||
val state = rememberLazyListState()
|
val state = rememberLazyListState()
|
||||||
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.background(color = TangemTheme.colors.background.primary)
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.fillMaxSize()
|
.fillMaxSize(),
|
||||||
.padding(scaffoldPadding),
|
|
||||||
state = state,
|
state = state,
|
||||||
contentPadding = PaddingValues(bottom = bottomMarginDp),
|
contentPadding = PaddingValues(
|
||||||
|
bottom = bottomMarginDp + bottomBarHeight,
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
item(
|
item(
|
||||||
key = "DifferentAddressesWarning$isDifferentAddressesBlockVisible",
|
key = "DifferentAddressesWarning$isDifferentAddressesBlockVisible",
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
package com.tangem.tap.features.tokens.impl.presentation.ui
|
package com.tangem.tap.features.tokens.impl.presentation.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
|
@ -16,6 +13,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
|
@ -42,8 +40,15 @@ internal fun TokensListToolbar(state: TokensListToolbarState) {
|
||||||
} else {
|
} else {
|
||||||
AppBarDefaults.TopAppBarElevation
|
AppBarDefaults.TopAppBarElevation
|
||||||
}
|
}
|
||||||
|
val statusBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getTop(this).toDp() }
|
||||||
|
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
backgroundColor = TangemTheme.colors.background.secondary,
|
backgroundColor = TangemTheme.colors.background.secondary,
|
||||||
|
contentPadding = PaddingValues(
|
||||||
|
start = TangemTheme.dimens.spacing4,
|
||||||
|
end = TangemTheme.dimens.spacing4,
|
||||||
|
top = statusBarHeight,
|
||||||
|
),
|
||||||
elevation = toolbarElevation,
|
elevation = toolbarElevation,
|
||||||
) {
|
) {
|
||||||
IconButton(onClick = state.onBackButtonClick) {
|
IconButton(onClick = state.onBackButtonClick) {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.screen.ComposeFragment
|
import com.tangem.core.ui.screen.ComposeFragment
|
||||||
import com.tangem.tap.common.analytics.events.SignIn
|
import com.tangem.tap.common.analytics.events.SignIn
|
||||||
|
|
@ -49,19 +48,14 @@ internal class WelcomeFragment : ComposeFragment() {
|
||||||
val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference())
|
val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference())
|
||||||
val warning by rememberUpdatedState(newValue = state.warning)
|
val warning by rememberUpdatedState(newValue = state.warning)
|
||||||
|
|
||||||
val backgroundColor = TangemTheme.colors.background.primary
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(backgroundColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.systemBarsPadding()
|
.background(TangemTheme.colors.background.primary)
|
||||||
.background(backgroundColor),
|
.systemBarsPadding(),
|
||||||
) {
|
) {
|
||||||
WelcomeScreenContent(
|
WelcomeScreenContent(
|
||||||
showUnlockProgress = state.showUnlockWithBiometricsProgress,
|
showUnlockProgress = state.showUnlockWithBiometricsProgress,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.tangem.core.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A composable that draws a fade effect at the bottom of the screen. Used on screens with a list of repeating
|
||||||
|
* elements and floating button at the bottom of the screen.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun BottomFade(modifier: Modifier = Modifier, backgroundColor: Color = TangemTheme.colors.background.secondary) {
|
||||||
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(TangemTheme.dimens.size100 + bottomBarHeight)
|
||||||
|
.background(
|
||||||
|
brush = Brush.verticalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.Transparent,
|
||||||
|
backgroundColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package com.tangem.core.ui.components
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.SideEffect
|
|
||||||
import com.google.accompanist.systemuicontroller.SystemUiController
|
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SystemBarsEffect(block: SystemUiController.() -> Unit) {
|
|
||||||
val systemUiController = rememberSystemUiController()
|
|
||||||
SideEffect { block(systemUiController) }
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.tangem.core.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.SideEffect
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
|
import com.tangem.core.ui.res.LocalIsInDarkTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the ability to set a scrim for 3-button navigation
|
||||||
|
*
|
||||||
|
* Automatically makes navigation bar transparent when the composable is disposed.
|
||||||
|
*
|
||||||
|
* Usage example: [com.tangem.feature.tokendetails.presentation.TokenDetailsFragment]
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun NavigationBar3ButtonsScrim() {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
val isDarkTheme = LocalIsInDarkTheme.current
|
||||||
|
SideEffect {
|
||||||
|
systemUiController.isNavigationBarContrastEnforced = true
|
||||||
|
}
|
||||||
|
LaunchedEffect(systemUiController.isNavigationBarContrastEnforced) {
|
||||||
|
if (systemUiController.isNavigationBarContrastEnforced.not()) {
|
||||||
|
systemUiController.isNavigationBarContrastEnforced = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DisposableEffect(isDarkTheme) {
|
||||||
|
onDispose {
|
||||||
|
systemUiController.isNavigationBarContrastEnforced = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the ability to set dark/light icons in cases where the darkness of the screen differs from that
|
||||||
|
* provided in [TangemTheme].
|
||||||
|
*
|
||||||
|
* Automatically returns the icon colors to their original state when the composable is disposed.
|
||||||
|
*
|
||||||
|
* Usage example: [com.tangem.feature.qrscanning.QrScanningFragment]
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun SystemBarsIconsDisposable(darkIcons: Boolean, isNavigationBarContrastEnforced: Boolean = false) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
|
||||||
|
SideEffect {
|
||||||
|
systemUiController.systemBarsDarkContentEnabled = darkIcons
|
||||||
|
systemUiController.isNavigationBarContrastEnforced = isNavigationBarContrastEnforced
|
||||||
|
}
|
||||||
|
|
||||||
|
val isDarkTheme = LocalIsInDarkTheme.current
|
||||||
|
|
||||||
|
DisposableEffect(isDarkTheme) {
|
||||||
|
onDispose {
|
||||||
|
systemUiController.systemBarsDarkContentEnabled = !isDarkTheme
|
||||||
|
systemUiController.isNavigationBarContrastEnforced = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
package com.tangem.core.ui.components.bottomsheets
|
package com.tangem.core.ui.components.bottomsheets
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material3.ModalBottomSheet
|
|
||||||
import androidx.compose.material3.SheetState
|
|
||||||
import androidx.compose.material3.rememberModalBottomSheetState
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import com.tangem.core.ui.res.LocalWindowSize
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
@ -15,6 +16,7 @@ import kotlinx.coroutines.launch
|
||||||
* Tangem bottom sheet with custom draggable header and config
|
* Tangem bottom sheet with custom draggable header and config
|
||||||
*
|
*
|
||||||
* @param config data model containing logic and ui models
|
* @param config data model containing logic and ui models
|
||||||
|
* @param
|
||||||
* @param content custom bottom sheet content
|
* @param content custom bottom sheet content
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
|
@ -22,20 +24,33 @@ import kotlinx.coroutines.launch
|
||||||
inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
|
inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
|
||||||
config: TangemBottomSheetConfig,
|
config: TangemBottomSheetConfig,
|
||||||
containerColor: Color = TangemTheme.colors.background.primary,
|
containerColor: Color = TangemTheme.colors.background.primary,
|
||||||
|
addBottomInsets: Boolean = true,
|
||||||
crossinline content: @Composable ColumnScope.(T) -> Unit,
|
crossinline content: @Composable ColumnScope.(T) -> Unit,
|
||||||
) {
|
) {
|
||||||
var isVisible by remember { mutableStateOf(value = config.isShow) }
|
var isVisible by remember { mutableStateOf(value = config.isShow) }
|
||||||
|
val statusBarHeight = with(LocalDensity.current) { WindowInsets.statusBars.getTop(this).toDp() }
|
||||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
if (isVisible && config.content is T) {
|
if (isVisible && config.content is T) {
|
||||||
ModalBottomSheet(
|
ModalBottomSheet(
|
||||||
|
// FIXME temporary solution to fix height of the bottom sheet
|
||||||
|
modifier = Modifier.sizeIn(maxHeight = LocalWindowSize.current.height - statusBarHeight),
|
||||||
onDismissRequest = config.onDismissRequest,
|
onDismissRequest = config.onDismissRequest,
|
||||||
sheetState = sheetState,
|
sheetState = sheetState,
|
||||||
containerColor = containerColor,
|
containerColor = containerColor,
|
||||||
shape = TangemTheme.shapes.bottomSheetLarge,
|
shape = TangemTheme.shapes.bottomSheetLarge,
|
||||||
|
windowInsets = WindowInsetsZero,
|
||||||
dragHandle = { TangemBottomSheetDraggableHeader(color = containerColor) },
|
dragHandle = { TangemBottomSheetDraggableHeader(color = containerColor) },
|
||||||
) {
|
) {
|
||||||
content(config.content)
|
if (addBottomInsets) {
|
||||||
|
Column(
|
||||||
|
// FIXME temporary solution to fix height of the bottom sheet
|
||||||
|
modifier = Modifier.navigationBarsPadding(),
|
||||||
|
) {
|
||||||
|
content(config.content)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content(config.content)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ data class TangemDimens internal constructor(
|
||||||
val size90: Dp = 90.dp,
|
val size90: Dp = 90.dp,
|
||||||
val size93: Dp = 93.dp,
|
val size93: Dp = 93.dp,
|
||||||
val size96: Dp = 96.dp,
|
val size96: Dp = 96.dp,
|
||||||
|
val size100: Dp = 100.dp,
|
||||||
val size102: Dp = 102.dp,
|
val size102: Dp = 102.dp,
|
||||||
val size108: Dp = 108.dp,
|
val size108: Dp = 108.dp,
|
||||||
val size110: Dp = 110.dp,
|
val size110: Dp = 110.dp,
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@ import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.ProvideTextStyle
|
import androidx.compose.material.ProvideTextStyle
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.tangem.core.ui.haptic.HapticManager
|
import com.tangem.core.ui.haptic.HapticManager
|
||||||
import com.tangem.core.ui.haptic.MockHapticManager
|
import com.tangem.core.ui.haptic.MockHapticManager
|
||||||
|
|
||||||
import com.tangem.core.ui.windowsize.WindowSize
|
import com.tangem.core.ui.windowsize.WindowSize
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -25,6 +26,16 @@ fun TangemTheme(
|
||||||
.also { it.update(themeColors) }
|
.also { it.update(themeColors) }
|
||||||
|
|
||||||
val shapes = remember { TangemShapes(dimens) }
|
val shapes = remember { TangemShapes(dimens) }
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
|
||||||
|
SideEffect {
|
||||||
|
systemUiController.setSystemBarsColor(
|
||||||
|
color = Color.Transparent,
|
||||||
|
darkIcons = !isDark,
|
||||||
|
isNavigationBarContrastEnforced = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colors = materialThemeColors(colors = themeColors, isDark = isDark),
|
colors = materialThemeColors(colors = themeColors, isDark = isDark),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.tangem.core.ui.utils
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.ui.unit.Density
|
||||||
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
|
|
||||||
|
object WindowInsetsZero : WindowInsets {
|
||||||
|
override fun getBottom(density: Density): Int = 0
|
||||||
|
override fun getLeft(density: Density, layoutDirection: LayoutDirection): Int = 0
|
||||||
|
override fun getRight(density: Density, layoutDirection: LayoutDirection): Int = 0
|
||||||
|
override fun getTop(density: Density): Int = 0
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,6 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import com.tangem.core.ui.ComposableContentComponent
|
import com.tangem.core.ui.ComposableContentComponent
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
|
||||||
import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
|
import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
|
||||||
import com.tangem.core.ui.res.LocalSnackbarHostState
|
import com.tangem.core.ui.res.LocalSnackbarHostState
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
|
@ -42,10 +41,6 @@ internal fun DetailsScreen(
|
||||||
val backgroundColor = TangemTheme.colors.background.secondary
|
val backgroundColor = TangemTheme.colors.background.secondary
|
||||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||||
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(backgroundColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
BackHandler(onBack = state.popBack)
|
BackHandler(onBack = state.popBack)
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
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.screen.ComposeFragment
|
||||||
import com.tangem.features.disclaimer.api.DisclaimerRouter
|
import com.tangem.features.disclaimer.api.DisclaimerRouter
|
||||||
import com.tangem.features.disclaimer.impl.presentation.ui.DisclaimerScreen
|
import com.tangem.features.disclaimer.impl.presentation.ui.DisclaimerScreen
|
||||||
|
|
@ -37,7 +35,6 @@ internal class DisclaimerFragment : ComposeFragment() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
val systemBarsColor = TangemTheme.colors.background.primary
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
if (isTosAccepted) {
|
if (isTosAccepted) {
|
||||||
appRouter.pop()
|
appRouter.pop()
|
||||||
|
|
@ -45,9 +42,6 @@ internal class DisclaimerFragment : ComposeFragment() {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(systemBarsColor)
|
|
||||||
}
|
|
||||||
DisclaimerScreen(viewModel.state, appRouter::pop)
|
DisclaimerScreen(viewModel.state, appRouter::pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,16 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Brush
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.isGranted
|
import com.google.accompanist.permissions.isGranted
|
||||||
import com.google.accompanist.permissions.rememberPermissionState
|
import com.google.accompanist.permissions.rememberPermissionState
|
||||||
|
import com.tangem.core.ui.components.BottomFade
|
||||||
|
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
import com.tangem.core.ui.components.PrimaryButton
|
||||||
import com.tangem.core.ui.components.appbar.AppBarWithAdditionalButtons
|
import com.tangem.core.ui.components.appbar.AppBarWithAdditionalButtons
|
||||||
import com.tangem.core.ui.components.appbar.models.AdditionalButton
|
import com.tangem.core.ui.components.appbar.models.AdditionalButton
|
||||||
|
|
@ -39,17 +38,14 @@ import com.tangem.features.disclaimer.impl.presentation.state.DummyDisclaimer
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun DisclaimerScreen(state: DisclaimerState, onBackClick: () -> Unit) {
|
internal fun DisclaimerScreen(state: DisclaimerState, onBackClick: () -> Unit) {
|
||||||
val bottomPadding = if (state.isTosAccepted) TangemTheme.dimens.spacing16 else TangemTheme.dimens.size64
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.statusBarsPadding()
|
.background(TangemColorPalette.Dark6)
|
||||||
.background(TangemColorPalette.Dark6),
|
.statusBarsPadding(),
|
||||||
) {
|
) {
|
||||||
Column(
|
Column {
|
||||||
modifier = Modifier
|
|
||||||
.navigationBarsPadding()
|
|
||||||
.padding(bottom = bottomPadding),
|
|
||||||
) {
|
|
||||||
AppBarWithAdditionalButtons(
|
AppBarWithAdditionalButtons(
|
||||||
text = resourceReference(R.string.disclaimer_title),
|
text = resourceReference(R.string.disclaimer_title),
|
||||||
startButton = AdditionalButton(
|
startButton = AdditionalButton(
|
||||||
|
|
@ -58,23 +54,34 @@ internal fun DisclaimerScreen(state: DisclaimerState, onBackClick: () -> Unit) {
|
||||||
).takeIf { state.isTosAccepted },
|
).takeIf { state.isTosAccepted },
|
||||||
)
|
)
|
||||||
DisclaimerContent(state.url)
|
DisclaimerContent(state.url)
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(TangemColorPalette.Dark6)
|
||||||
|
.height(
|
||||||
|
height = if (!state.isTosAccepted) {
|
||||||
|
bottomBarHeight
|
||||||
|
} else {
|
||||||
|
bottomBarHeight + TangemTheme.dimens.size64
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.isTosAccepted) {
|
if (!state.isTosAccepted) {
|
||||||
|
BottomFade(Modifier.align(Alignment.BottomCenter), backgroundColor = TangemColorPalette.Dark6)
|
||||||
DisclaimerButton(state.onAccept)
|
DisclaimerButton(state.onAccept)
|
||||||
|
} else {
|
||||||
|
NavigationBar3ButtonsScrim()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.DisclaimerContent(url: String) {
|
private fun ColumnScope.DisclaimerContent(url: String) {
|
||||||
val transparent = Color.Transparent
|
|
||||||
|
|
||||||
val progressState = remember { mutableStateOf(ProgressState.Loading) }
|
val progressState = remember { mutableStateOf(ProgressState.Loading) }
|
||||||
val webClient = remember { DisclaimerWebViewClient(progressState) }
|
val webClient = remember { DisclaimerWebViewClient(progressState) }
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier,
|
||||||
.fillMaxWidth()
|
|
||||||
.weight(1f),
|
|
||||||
) {
|
) {
|
||||||
AndroidView(
|
AndroidView(
|
||||||
factory = {
|
factory = {
|
||||||
|
|
@ -83,9 +90,10 @@ private fun ColumnScope.DisclaimerContent(url: String) {
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
)
|
)
|
||||||
setBackgroundColor(transparent.toArgb())
|
setBackgroundColor(TangemColorPalette.Dark6.toArgb())
|
||||||
settings.allowFileAccess = false
|
settings.allowFileAccess = false
|
||||||
settings.javaScriptEnabled = false
|
settings.javaScriptEnabled = false
|
||||||
|
|
||||||
overScrollMode = View.OVER_SCROLL_NEVER
|
overScrollMode = View.OVER_SCROLL_NEVER
|
||||||
webViewClient = webClient
|
webViewClient = webClient
|
||||||
loadUrl(url)
|
loadUrl(url)
|
||||||
|
|
@ -94,28 +102,34 @@ private fun ColumnScope.DisclaimerContent(url: String) {
|
||||||
)
|
)
|
||||||
|
|
||||||
when (progressState.value) {
|
when (progressState.value) {
|
||||||
ProgressState.Loading -> CircularProgressIndicator(
|
ProgressState.Loading -> {
|
||||||
color = TangemTheme.colors.icon.informative,
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
modifier = Modifier
|
CircularProgressIndicator(
|
||||||
.align(Alignment.Center)
|
color = TangemTheme.colors.icon.informative,
|
||||||
.padding(TangemTheme.dimens.spacing8),
|
modifier = Modifier
|
||||||
)
|
.align(Alignment.Center)
|
||||||
ProgressState.Error -> Column(
|
.padding(TangemTheme.dimens.spacing8),
|
||||||
verticalArrangement = Arrangement.Center,
|
)
|
||||||
modifier = Modifier
|
}
|
||||||
.fillMaxWidth()
|
}
|
||||||
.padding(TangemTheme.dimens.spacing16)
|
ProgressState.Error -> Box(modifier = Modifier.fillMaxSize()) {
|
||||||
.align(Alignment.Center),
|
Column(
|
||||||
) {
|
verticalArrangement = Arrangement.Center,
|
||||||
Text(
|
modifier = Modifier
|
||||||
text = stringResource(id = R.string.disclaimer_error_loading),
|
.fillMaxWidth()
|
||||||
style = TangemTheme.typography.body1,
|
.padding(TangemTheme.dimens.spacing16)
|
||||||
color = TangemTheme.colors.text.constantWhite,
|
.align(Alignment.Center),
|
||||||
)
|
) {
|
||||||
PrimaryButton(
|
Text(
|
||||||
text = stringResource(R.string.common_retry),
|
text = stringResource(id = R.string.disclaimer_error_loading),
|
||||||
onClick = { webClient.reset() },
|
style = TangemTheme.typography.body1,
|
||||||
)
|
color = TangemTheme.colors.text.constantWhite,
|
||||||
|
)
|
||||||
|
PrimaryButton(
|
||||||
|
text = stringResource(R.string.common_retry),
|
||||||
|
onClick = { webClient.reset() },
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
@ -130,23 +144,6 @@ private fun BoxScope.DisclaimerButton(onAccept: (Boolean) -> Unit) {
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
val bottomInsetsPx = WindowInsets.navigationBars.getBottom(LocalDensity.current)
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomCenter)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(TangemTheme.dimens.size110 + bottomInsetsPx.dp)
|
|
||||||
.background(
|
|
||||||
Brush.verticalGradient(
|
|
||||||
colors = listOf(
|
|
||||||
TangemTheme.colors.background.primary.copy(alpha = 0f),
|
|
||||||
TangemTheme.colors.background.primary.copy(alpha = 0.75f),
|
|
||||||
TangemTheme.colors.background.primary.copy(alpha = 0.95f),
|
|
||||||
TangemTheme.colors.background.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
PrimaryButton(
|
PrimaryButton(
|
||||||
text = stringResource(id = R.string.common_accept),
|
text = stringResource(id = R.string.common_accept),
|
||||||
onClick = { onAccept(shouldAskPushPermission) },
|
onClick = { onAccept(shouldAskPushPermission) },
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,7 @@ import android.annotation.SuppressLint
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||||
import androidx.compose.foundation.focusable
|
import androidx.compose.foundation.focusable
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
|
||||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.only
|
|
||||||
import androidx.compose.foundation.layout.systemBars
|
|
||||||
import androidx.compose.material3.BottomSheetDefaults
|
import androidx.compose.material3.BottomSheetDefaults
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ModalBottomSheet
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
|
|
@ -36,6 +31,7 @@ import androidx.compose.ui.input.key.KeyEventType
|
||||||
import androidx.compose.ui.input.key.key
|
import androidx.compose.ui.input.key.key
|
||||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
import androidx.compose.ui.input.key.type
|
import androidx.compose.ui.input.key.type
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
|
|
@ -43,7 +39,9 @@ import androidx.navigation.compose.rememberNavController
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetDraggableHeader
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetDraggableHeader
|
||||||
import com.tangem.core.ui.components.bottomsheets.collapse
|
import com.tangem.core.ui.components.bottomsheets.collapse
|
||||||
|
import com.tangem.core.ui.res.LocalWindowSize
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
import com.tangem.managetokens.presentation.addcustomtoken.router.AddCustomTokenRoute
|
import com.tangem.managetokens.presentation.addcustomtoken.router.AddCustomTokenRoute
|
||||||
import com.tangem.managetokens.presentation.addcustomtoken.router.AddCustomTokenRouter
|
import com.tangem.managetokens.presentation.addcustomtoken.router.AddCustomTokenRouter
|
||||||
import com.tangem.managetokens.presentation.addcustomtoken.viewmodels.AddCustomTokenViewModel
|
import com.tangem.managetokens.presentation.addcustomtoken.viewmodels.AddCustomTokenViewModel
|
||||||
|
|
@ -57,6 +55,7 @@ fun AddCustomTokenBottomSheet(config: TangemBottomSheetConfig) {
|
||||||
|
|
||||||
var isVisible by remember { mutableStateOf(value = config.isShow) }
|
var isVisible by remember { mutableStateOf(value = config.isShow) }
|
||||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
|
val statusBarHeight = with(LocalDensity.current) { WindowInsets.statusBars.getTop(this).toDp() }
|
||||||
|
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
// ViewModel cannot be scoped to ModalBottomSheet's lifecycle,
|
// ViewModel cannot be scoped to ModalBottomSheet's lifecycle,
|
||||||
|
|
@ -67,11 +66,13 @@ fun AddCustomTokenBottomSheet(config: TangemBottomSheetConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ModalBottomSheetWithBackHandling(
|
ModalBottomSheetWithBackHandling(
|
||||||
|
modifier = Modifier
|
||||||
|
.sizeIn(maxHeight = LocalWindowSize.current.height - statusBarHeight),
|
||||||
onDismissRequest = config.onDismissRequest,
|
onDismissRequest = config.onDismissRequest,
|
||||||
sheetState = sheetState,
|
sheetState = sheetState,
|
||||||
containerColor = TangemTheme.colors.background.tertiary,
|
containerColor = TangemTheme.colors.background.tertiary,
|
||||||
shape = TangemTheme.shapes.bottomSheetLarge,
|
shape = TangemTheme.shapes.bottomSheetLarge,
|
||||||
windowInsets = WindowInsets.systemBars.only(WindowInsetsSides.Top),
|
windowInsets = WindowInsetsZero,
|
||||||
dragHandle = { TangemBottomSheetDraggableHeader(color = TangemTheme.colors.background.tertiary) },
|
dragHandle = { TangemBottomSheetDraggableHeader(color = TangemTheme.colors.background.tertiary) },
|
||||||
properties = ModalBottomSheetDefaults.properties(shouldDismissOnBackPress = false),
|
properties = ModalBottomSheetDefaults.properties(shouldDismissOnBackPress = false),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@ private fun Content(state: ManageTokensState, onHeaderSizeChange: (Dp) -> Unit)
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.navigationBarsPadding()
|
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.background(color = TangemTheme.colors.background.primary),
|
.background(color = TangemTheme.colors.background.primary),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,16 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleEventObserver
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
|
||||||
import com.google.mlkit.vision.common.InputImage
|
import com.google.mlkit.vision.common.InputImage
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.components.SystemBarsIconsDisposable
|
||||||
import com.tangem.core.ui.screen.ComposeFragment
|
import com.tangem.core.ui.screen.ComposeFragment
|
||||||
import com.tangem.feature.qrscanning.inner.MLKitBarcodeAnalyzer
|
import com.tangem.feature.qrscanning.inner.MLKitBarcodeAnalyzer
|
||||||
import com.tangem.feature.qrscanning.navigation.QrScanningInnerRouter
|
import com.tangem.feature.qrscanning.navigation.QrScanningInnerRouter
|
||||||
|
|
@ -105,7 +100,8 @@ internal class QrScanningFragment : ComposeFragment() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
StatusBarTransparencyDisposable()
|
SystemBarsIconsDisposable(darkIcons = false)
|
||||||
|
|
||||||
QrScanningContent(
|
QrScanningContent(
|
||||||
executor = { cameraExecutor },
|
executor = { cameraExecutor },
|
||||||
analyzer = { cameraAnalyzer },
|
analyzer = { cameraAnalyzer },
|
||||||
|
|
@ -145,29 +141,4 @@ internal class QrScanningFragment : ComposeFragment() {
|
||||||
|
|
||||||
fun create() = QrScanningFragment()
|
fun create() = QrScanningFragment()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun StatusBarTransparencyDisposable() {
|
|
||||||
val systemUiController = rememberSystemUiController()
|
|
||||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
|
||||||
val lifecycleOwner = LocalLifecycleOwner.current
|
|
||||||
DisposableEffect(Unit) {
|
|
||||||
val observer = LifecycleEventObserver { _, event ->
|
|
||||||
if (event == Lifecycle.Event.ON_START) {
|
|
||||||
systemUiController.setSystemBarsColor(
|
|
||||||
color = Color.Transparent,
|
|
||||||
darkIcons = false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (event == Lifecycle.Event.ON_STOP) {
|
|
||||||
systemUiController.setSystemBarsColor(systemBarsColor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lifecycleOwner.lifecycle.addObserver(observer)
|
|
||||||
|
|
||||||
onDispose {
|
|
||||||
lifecycleOwner.lifecycle.removeObserver(observer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
package com.tangem.feature.referral
|
package com.tangem.feature.referral
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.compose.foundation.layout.systemBarsPadding
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
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.screen.ComposeFragment
|
||||||
import com.tangem.feature.referral.router.ReferralRouter
|
import com.tangem.feature.referral.router.ReferralRouter
|
||||||
import com.tangem.feature.referral.ui.ReferralScreen
|
import com.tangem.feature.referral.ui.ReferralScreen
|
||||||
|
|
@ -35,12 +32,6 @@ class ReferralFragment : ComposeFragment() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
val backgroundColor = TangemTheme.colors.background.secondary
|
ReferralScreen(stateHolder = viewModel.uiState)
|
||||||
SystemBarsEffect { setSystemBarsColor(backgroundColor) }
|
|
||||||
|
|
||||||
ReferralScreen(
|
|
||||||
modifier = Modifier.systemBarsPadding(),
|
|
||||||
stateHolder = viewModel.uiState,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,23 +2,20 @@ package com.tangem.feature.referral.ui
|
||||||
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalInspectionMode
|
import androidx.compose.ui.platform.LocalInspectionMode
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.google.accompanist.web.WebView
|
import com.google.accompanist.web.WebView
|
||||||
import com.google.accompanist.web.rememberWebViewState
|
import com.google.accompanist.web.rememberWebViewState
|
||||||
import com.tangem.core.ui.components.appbar.AppBarWithAdditionalButtons
|
import com.tangem.core.ui.components.appbar.AppBarWithAdditionalButtons
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
import com.tangem.feature.referral.presentation.R
|
import com.tangem.feature.referral.presentation.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,15 +25,16 @@ import com.tangem.feature.referral.presentation.R
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
internal fun AgreementBottomSheetContent(url: String) {
|
internal fun AgreementBottomSheetContent(url: String) {
|
||||||
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxSize()
|
||||||
.height(LocalConfiguration.current.screenHeightDp.dp - TangemTheme.dimens.spacing16),
|
.verticalScroll(rememberScrollState()),
|
||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
|
AppBarWithAdditionalButtons(text = stringResource(id = R.string.details_referral_title))
|
||||||
AppBarWithAdditionalButtons(text = stringResource(id = R.string.details_referral_title))
|
AgreementHtmlView(url = url)
|
||||||
AgreementHtmlView(url = url)
|
Spacer(modifier = Modifier.height(bottomBarHeight))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,7 +44,7 @@ private fun AgreementHtmlView(url: String) {
|
||||||
val isInPreviewMode = LocalInspectionMode.current
|
val isInPreviewMode = LocalInspectionMode.current
|
||||||
WebView(
|
WebView(
|
||||||
state = state,
|
state = state,
|
||||||
modifier = Modifier.background(TangemTheme.colors.background.secondary),
|
modifier = Modifier.background(TangemTheme.colors.background.primary),
|
||||||
captureBackPresses = false,
|
captureBackPresses = false,
|
||||||
onCreated = {
|
onCreated = {
|
||||||
if (!isInPreviewMode) {
|
if (!isInPreviewMode) {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
package com.tangem.feature.referral.ui
|
package com.tangem.feature.referral.ui
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.statusBars
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ModalBottomSheet
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
import androidx.compose.material3.SheetState
|
import androidx.compose.material3.SheetState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import com.tangem.core.ui.res.LocalWindowSize
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
import com.tangem.feature.referral.models.ReferralStateHolder
|
import com.tangem.feature.referral.models.ReferralStateHolder
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
|
@ -16,14 +23,18 @@ internal fun ReferralBottomSheet(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
config: ReferralStateHolder.ReferralInfoState,
|
config: ReferralStateHolder.ReferralInfoState,
|
||||||
) {
|
) {
|
||||||
|
val statusBarHeight = with(LocalDensity.current) { WindowInsets.statusBars.getTop(this).toDp() }
|
||||||
|
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
ModalBottomSheet(
|
ModalBottomSheet(
|
||||||
|
modifier = Modifier.height(LocalWindowSize.current.height - statusBarHeight),
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
sheetState = sheetState,
|
sheetState = sheetState,
|
||||||
shape = RoundedCornerShape(
|
shape = RoundedCornerShape(
|
||||||
topStart = TangemTheme.dimens.radius16,
|
topStart = TangemTheme.dimens.radius16,
|
||||||
topEnd = TangemTheme.dimens.radius16,
|
topEnd = TangemTheme.dimens.radius16,
|
||||||
),
|
),
|
||||||
|
windowInsets = WindowInsetsZero,
|
||||||
containerColor = TangemTheme.colors.background.primary,
|
containerColor = TangemTheme.colors.background.primary,
|
||||||
) {
|
) {
|
||||||
AgreementBottomSheetContent(
|
AgreementBottomSheetContent(
|
||||||
|
|
|
||||||
|
|
@ -46,16 +46,16 @@ import kotlinx.coroutines.launch
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ReferralScreen(stateHolder: ReferralStateHolder, modifier: Modifier = Modifier) {
|
internal fun ReferralScreen(stateHolder: ReferralStateHolder) {
|
||||||
var isBottomSheetVisible by remember { mutableStateOf(value = false) }
|
var isBottomSheetVisible by remember { mutableStateOf(value = false) }
|
||||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
|
|
||||||
val snackbarHostState = remember(::SnackbarHostState)
|
val snackbarHostState = remember(::SnackbarHostState)
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier,
|
|
||||||
topBar = {
|
topBar = {
|
||||||
AppBarWithBackButton(
|
AppBarWithBackButton(
|
||||||
|
modifier = Modifier.statusBarsPadding(),
|
||||||
text = stringResource(R.string.details_referral_title),
|
text = stringResource(R.string.details_referral_title),
|
||||||
onBackClick = stateHolder.headerState.onBackClicked,
|
onBackClick = stateHolder.headerState.onBackClicked,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import com.tangem.common.routing.AppRoute
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
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.screen.ComposeFragment
|
||||||
import com.tangem.features.send.api.navigation.SendRouter
|
import com.tangem.features.send.api.navigation.SendRouter
|
||||||
import com.tangem.features.send.impl.navigation.InnerSendRouter
|
import com.tangem.features.send.impl.navigation.InnerSendRouter
|
||||||
|
|
@ -61,10 +59,6 @@ internal class SendFragment : ComposeFragment() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
val systemBarsColor = TangemTheme.colors.background.tertiary
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(systemBarsColor)
|
|
||||||
}
|
|
||||||
val currentState = viewModel.stateRouter.currentState.collectAsStateWithLifecycle()
|
val currentState = viewModel.stateRouter.currentState.collectAsStateWithLifecycle()
|
||||||
SendScreen(viewModel.uiState, currentState.value)
|
SendScreen(viewModel.uiState, currentState.value)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,10 @@ internal fun SendScreen(uiState: SendUiState, currentState: SendUiCurrentScreen)
|
||||||
BackHandler(onBack = onBackClick)
|
BackHandler(onBack = onBackClick)
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.background(color = TangemTheme.colors.background.tertiary)
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.systemBarsPadding()
|
.systemBarsPadding(),
|
||||||
.background(color = TangemTheme.colors.background.tertiary),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
SendAppBar(
|
SendAppBar(
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
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.screen.ComposeFragment
|
||||||
import com.tangem.features.staking.api.navigation.StakingRouter
|
import com.tangem.features.staking.api.navigation.StakingRouter
|
||||||
import com.tangem.features.staking.impl.navigation.InnerStakingRouter
|
import com.tangem.features.staking.impl.navigation.InnerStakingRouter
|
||||||
|
|
@ -59,10 +57,6 @@ internal class StakingFragment : ComposeFragment() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
val systemBarsColor = TangemTheme.colors.background.tertiary
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(systemBarsColor)
|
|
||||||
}
|
|
||||||
val currentState = viewModel.uiState.collectAsStateWithLifecycle()
|
val currentState = viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
StakingScreen(currentState.value)
|
StakingScreen(currentState.value)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,10 @@ internal fun StakingScreen(uiState: StakingUiState) {
|
||||||
BackHandler(onBack = uiState.clickIntents::onBackClick)
|
BackHandler(onBack = uiState.clickIntents::onBackClick)
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.background(color = TangemTheme.colors.background.tertiary)
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.systemBarsPadding()
|
.systemBarsPadding(),
|
||||||
.background(color = TangemTheme.colors.background.tertiary),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
SendAppBar(
|
SendAppBar(
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ package com.tangem.feature.swap.presentation
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
|
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.screen.ComposeFragment
|
import com.tangem.core.ui.screen.ComposeFragment
|
||||||
import com.tangem.feature.swap.router.CustomTabsManager
|
import com.tangem.feature.swap.router.CustomTabsManager
|
||||||
|
|
@ -47,17 +47,17 @@ class SwapFragment : ComposeFragment() {
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
viewModel.onScreenOpened()
|
viewModel.onScreenOpened()
|
||||||
|
|
||||||
val backgroundColor = TangemTheme.colors.background.secondary
|
|
||||||
SystemBarsEffect { setSystemBarsColor(backgroundColor) }
|
|
||||||
|
|
||||||
ScreenContent(viewModel = viewModel)
|
ScreenContent(viewModel = viewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("TopLevelComposableFunctions")
|
@Suppress("TopLevelComposableFunctions")
|
||||||
@Composable
|
@Composable
|
||||||
private fun ScreenContent(viewModel: SwapViewModel) {
|
private fun ScreenContent(viewModel: SwapViewModel) {
|
||||||
Crossfade(targetState = viewModel.currentScreen, label = "") { screen ->
|
Crossfade(
|
||||||
|
modifier = Modifier.background(TangemTheme.colors.background.secondary),
|
||||||
|
targetState = viewModel.currentScreen,
|
||||||
|
label = "",
|
||||||
|
) { screen ->
|
||||||
when (screen) {
|
when (screen) {
|
||||||
SwapNavScreen.Main -> SwapScreen(stateHolder = viewModel.uiState)
|
SwapNavScreen.Main -> SwapScreen(stateHolder = viewModel.uiState)
|
||||||
SwapNavScreen.Success -> {
|
SwapNavScreen.Success -> {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
import com.tangem.feature.swap.models.SwapStateHolder
|
import com.tangem.feature.swap.models.SwapStateHolder
|
||||||
import com.tangem.feature.swap.models.states.ChooseFeeBottomSheetConfig
|
import com.tangem.feature.swap.models.states.ChooseFeeBottomSheetConfig
|
||||||
import com.tangem.feature.swap.models.states.ChooseProviderBottomSheetConfig
|
import com.tangem.feature.swap.models.states.ChooseProviderBottomSheetConfig
|
||||||
|
|
@ -28,7 +29,7 @@ internal fun SwapScreen(stateHolder: SwapStateHolder) {
|
||||||
iconRes = R.drawable.ic_close_24,
|
iconRes = R.drawable.ic_close_24,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentWindowInsets = WindowInsets(left = 0, top = 0, right = 0, bottom = 0),
|
contentWindowInsets = WindowInsetsZero,
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
containerColor = TangemTheme.colors.background.secondary,
|
||||||
) { scaffoldPaddings ->
|
) { scaffoldPaddings ->
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.tangem.core.navigation.finisher.AppFinisher
|
import com.tangem.core.navigation.finisher.AppFinisher
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.screen.ComposeActivity
|
import com.tangem.core.ui.screen.ComposeActivity
|
||||||
import com.tangem.feature.tester.presentation.actions.TesterActionsScreen
|
import com.tangem.feature.tester.presentation.actions.TesterActionsScreen
|
||||||
|
|
@ -45,9 +45,8 @@ internal class TesterActivity : ComposeActivity() {
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
val systemBarsColor = TangemTheme.colors.background.secondary
|
||||||
SystemBarsEffect {
|
val systemUiController = rememberSystemUiController()
|
||||||
setSystemBarsColor(systemBarsColor)
|
systemUiController.setSystemBarsColor(systemBarsColor)
|
||||||
}
|
|
||||||
|
|
||||||
TesterNavHost()
|
TesterNavHost()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.screen.ComposeFragment
|
import com.tangem.core.ui.screen.ComposeFragment
|
||||||
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
|
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.TokenDetailsScreen
|
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.TokenDetailsScreen
|
||||||
|
|
@ -33,14 +32,8 @@ internal class TokenDetailsFragment : ComposeFragment() {
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
val viewModel = hiltViewModel<TokenDetailsViewModel>()
|
val viewModel = hiltViewModel<TokenDetailsViewModel>()
|
||||||
viewModel.router = this@TokenDetailsFragment.internalTokenDetailsRouter
|
viewModel.router = this@TokenDetailsFragment.internalTokenDetailsRouter
|
||||||
|
|
||||||
LocalLifecycleOwner.current.lifecycle.addObserver(viewModel)
|
LocalLifecycleOwner.current.lifecycle.addObserver(viewModel)
|
||||||
|
NavigationBar3ButtonsScrim()
|
||||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(systemBarsColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenDetailsScreen(state = viewModel.uiState)
|
TokenDetailsScreen(state = viewModel.uiState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,10 +3,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.ui
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
|
|
@ -14,6 +11,7 @@ import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||||
import androidx.compose.material.pullrefresh.pullRefresh
|
import androidx.compose.material.pullrefresh.pullRefresh
|
||||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.ScaffoldDefaults
|
||||||
import androidx.compose.material3.SnackbarHost
|
import androidx.compose.material3.SnackbarHost
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
@ -21,6 +19,7 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||||
|
|
@ -60,11 +59,13 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.e
|
||||||
@Composable
|
@Composable
|
||||||
internal fun TokenDetailsScreen(state: TokenDetailsState) {
|
internal fun TokenDetailsScreen(state: TokenDetailsState) {
|
||||||
BackHandler(onBack = state.topAppBarConfig.onBackClick)
|
BackHandler(onBack = state.topAppBarConfig.onBackClick)
|
||||||
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
|
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = { TokenDetailsTopAppBar(config = state.topAppBarConfig) },
|
topBar = { TokenDetailsTopAppBar(config = state.topAppBarConfig) },
|
||||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||||
|
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
containerColor = TangemTheme.colors.background.secondary,
|
||||||
) { scaffoldPaddings ->
|
) { scaffoldPaddings ->
|
||||||
val pullRefreshState = rememberPullRefreshState(
|
val pullRefreshState = rememberPullRefreshState(
|
||||||
|
|
@ -90,7 +91,9 @@ internal fun TokenDetailsScreen(state: TokenDetailsState) {
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentPadding = PaddingValues(bottom = TangemTheme.dimens.spacing16),
|
contentPadding = PaddingValues(
|
||||||
|
bottom = TangemTheme.dimens.spacing16 + bottomBarHeight,
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
TokenInfoBlock(
|
TokenInfoBlock(
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ package com.tangem.feature.wallet.presentation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.tangem.core.ui.UiDependencies
|
import com.tangem.core.ui.UiDependencies
|
||||||
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.screen.ComposeFragment
|
||||||
import com.tangem.feature.wallet.presentation.router.InnerWalletRouter
|
import com.tangem.feature.wallet.presentation.router.InnerWalletRouter
|
||||||
import com.tangem.features.managetokens.navigation.ManageTokensUi
|
import com.tangem.features.managetokens.navigation.ManageTokensUi
|
||||||
|
|
@ -37,11 +35,6 @@ internal class WalletFragment : ComposeFragment() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent(modifier: Modifier) {
|
override fun ScreenContent(modifier: Modifier) {
|
||||||
val systemBarsColor = TangemTheme.colors.background.secondary
|
|
||||||
SystemBarsEffect {
|
|
||||||
setSystemBarsColor(systemBarsColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
_walletRouter.Initialize(
|
_walletRouter.Initialize(
|
||||||
onFinish = requireActivity()::finish,
|
onFinish = requireActivity()::finish,
|
||||||
manageTokensUi = manageTokensUi,
|
manageTokensUi = manageTokensUi,
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,10 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.composed
|
import androidx.compose.ui.composed
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Brush
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.RectangleShape
|
import androidx.compose.ui.graphics.RectangleShape
|
||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
@ -28,6 +27,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.tangem.core.ui.components.BottomFade
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
import com.tangem.core.ui.components.PrimaryButton
|
||||||
import com.tangem.core.ui.components.SecondaryButton
|
import com.tangem.core.ui.components.SecondaryButton
|
||||||
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
|
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
|
||||||
|
|
@ -36,6 +36,7 @@ import com.tangem.core.ui.event.EventEffect
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
import com.tangem.feature.wallet.impl.R
|
import com.tangem.feature.wallet.impl.R
|
||||||
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
||||||
import com.tangem.feature.wallet.presentation.common.component.DraggableNetworkGroupItem
|
import com.tangem.feature.wallet.presentation.common.component.DraggableNetworkGroupItem
|
||||||
|
|
@ -57,8 +58,12 @@ internal fun OrganizeTokensScreen(state: OrganizeTokensState, modifier: Modifier
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBar(state.header, tokensListState)
|
TopBar(
|
||||||
|
config = state.header,
|
||||||
|
tokensListState = tokensListState,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
contentWindowInsets = WindowInsetsZero,
|
||||||
content = { paddingValues ->
|
content = { paddingValues ->
|
||||||
TokenList(
|
TokenList(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -72,7 +77,9 @@ internal fun OrganizeTokensScreen(state: OrganizeTokensState, modifier: Modifier
|
||||||
},
|
},
|
||||||
floatingActionButtonPosition = FabPosition.Center,
|
floatingActionButtonPosition = FabPosition.Center,
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
Actions(state.actions)
|
Box(modifier = Modifier.navigationBarsPadding()) {
|
||||||
|
Actions(state.actions)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
containerColor = TangemTheme.colors.background.secondary,
|
||||||
)
|
)
|
||||||
|
|
@ -104,9 +111,11 @@ private fun TokenList(
|
||||||
onDragEnd = onDragEnd,
|
onDragEnd = onDragEnd,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
|
|
||||||
val listContentPadding = PaddingValues(
|
val listContentPadding = PaddingValues(
|
||||||
top = TangemTheme.dimens.spacing4,
|
top = TangemTheme.dimens.spacing4,
|
||||||
bottom = TangemTheme.dimens.spacing92,
|
bottom = TangemTheme.dimens.spacing92 + bottomBarHeight,
|
||||||
start = TangemTheme.dimens.spacing16,
|
start = TangemTheme.dimens.spacing16,
|
||||||
end = TangemTheme.dimens.spacing16,
|
end = TangemTheme.dimens.spacing16,
|
||||||
)
|
)
|
||||||
|
|
@ -140,7 +149,7 @@ private fun TokenList(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BottomGradient(modifier = Modifier.align(Alignment.BottomCenter))
|
BottomFade(modifier = Modifier.align(Alignment.BottomCenter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,23 +200,6 @@ private fun LazyItemScope.DraggableItem(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun BottomGradient(modifier: Modifier = Modifier) {
|
|
||||||
Box(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(TangemTheme.dimens.size116)
|
|
||||||
.background(
|
|
||||||
brush = Brush.verticalGradient(
|
|
||||||
colors = listOf(
|
|
||||||
Color.Transparent,
|
|
||||||
TangemTheme.colors.background.secondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun TopBar(
|
private fun TopBar(
|
||||||
config: OrganizeTokensState.HeaderConfig,
|
config: OrganizeTokensState.HeaderConfig,
|
||||||
|
|
@ -228,6 +220,7 @@ private fun TopBar(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.shadow(elevation)
|
.shadow(elevation)
|
||||||
.background(TangemTheme.colors.background.secondary)
|
.background(TangemTheme.colors.background.secondary)
|
||||||
|
.statusBarsPadding()
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
package com.tangem.feature.wallet.presentation.router
|
package com.tangem.feature.wallet.presentation.router
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
|
@ -86,7 +84,6 @@ internal class DefaultWalletRouter(
|
||||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
OrganizeTokensScreen(
|
OrganizeTokensScreen(
|
||||||
modifier = Modifier.statusBarsPadding(),
|
|
||||||
state = uiState,
|
state = uiState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.luminance
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
|
|
@ -33,16 +34,13 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.tangem.core.ui.components.Keyboard
|
import com.tangem.core.ui.components.*
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
|
||||||
import com.tangem.core.ui.components.SystemBarsEffect
|
|
||||||
import com.tangem.core.ui.components.atoms.Hand
|
import com.tangem.core.ui.components.atoms.Hand
|
||||||
import com.tangem.core.ui.components.atoms.handComposableComponentHeight
|
import com.tangem.core.ui.components.atoms.handComposableComponentHeight
|
||||||
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheet
|
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheet
|
||||||
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheet
|
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheet
|
||||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.keyboardAsState
|
|
||||||
import com.tangem.core.ui.components.snackbar.CopiedTextSnackbar
|
import com.tangem.core.ui.components.snackbar.CopiedTextSnackbar
|
||||||
import com.tangem.core.ui.components.snackbar.TangemSnackbar
|
import com.tangem.core.ui.components.snackbar.TangemSnackbar
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||||
|
|
@ -50,6 +48,7 @@ import com.tangem.core.ui.event.StateEvent
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
import com.tangem.core.ui.test.TestTags
|
import com.tangem.core.ui.test.TestTags
|
||||||
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
import com.tangem.feature.wallet.impl.R
|
import com.tangem.feature.wallet.impl.R
|
||||||
import com.tangem.feature.wallet.presentation.common.preview.WalletScreenPreviewData.walletScreenState
|
import com.tangem.feature.wallet.presentation.common.preview.WalletScreenPreviewData.walletScreenState
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
||||||
|
|
@ -112,7 +111,7 @@ internal fun WalletScreen(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongMethod", "LongParameterList")
|
@Suppress("LongMethod", "LongParameterList", "CyclomaticComplexMethod")
|
||||||
@Composable
|
@Composable
|
||||||
private fun WalletContent(
|
private fun WalletContent(
|
||||||
state: WalletScreenState,
|
state: WalletScreenState,
|
||||||
|
|
@ -144,12 +143,14 @@ private fun WalletContent(
|
||||||
.padding(top = betweenItemsPadding)
|
.padding(top = betweenItemsPadding)
|
||||||
.padding(horizontal = horizontalPadding)
|
.padding(horizontal = horizontalPadding)
|
||||||
|
|
||||||
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.testTag(TestTags.WALLET_SCREEN),
|
.testTag(TestTags.WALLET_SCREEN),
|
||||||
contentPadding = PaddingValues(
|
contentPadding = PaddingValues(
|
||||||
bottom = TangemTheme.dimens.spacing92,
|
bottom = TangemTheme.dimens.spacing92 + bottomBarHeight,
|
||||||
),
|
),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
|
|
@ -330,7 +331,7 @@ private fun BaseScaffoldManageTokenRedesign(
|
||||||
coroutineScope.launch { bottomSheetState.partialExpand() }
|
coroutineScope.launch { bottomSheetState.partialExpand() }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
content = { paddingValues ->
|
content = { _ ->
|
||||||
val pullRefreshState = rememberPullRefreshState(
|
val pullRefreshState = rememberPullRefreshState(
|
||||||
refreshing = selectedWallet.pullToRefreshConfig.isRefreshing,
|
refreshing = selectedWallet.pullToRefreshConfig.isRefreshing,
|
||||||
onRefresh = {
|
onRefresh = {
|
||||||
|
|
@ -338,9 +339,7 @@ private fun BaseScaffoldManageTokenRedesign(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
Column(
|
Column {
|
||||||
modifier = Modifier.padding(paddingValues),
|
|
||||||
) {
|
|
||||||
WalletTopBar(config = state.topBarConfig)
|
WalletTopBar(config = state.topBarConfig)
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.pullRefresh(pullRefreshState),
|
modifier = Modifier.pullRefresh(pullRefreshState),
|
||||||
|
|
@ -392,7 +391,7 @@ private fun BottomSheetScrim(color: Color, visible: Boolean, onDismissRequest: (
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Suppress("CyclomaticComplexMethod")
|
@Suppress("CyclomaticComplexMethod", "MagicNumber")
|
||||||
@Composable
|
@Composable
|
||||||
private fun BottomSheetStateEffects(
|
private fun BottomSheetStateEffects(
|
||||||
bottomSheetState: SheetState,
|
bottomSheetState: SheetState,
|
||||||
|
|
@ -425,19 +424,29 @@ private fun BottomSheetStateEffects(
|
||||||
|
|
||||||
val systemUiController = rememberSystemUiController()
|
val systemUiController = rememberSystemUiController()
|
||||||
val navigationBarColor = TangemTheme.colors.background.primary
|
val navigationBarColor = TangemTheme.colors.background.primary
|
||||||
val navigationBarColorWithout = TangemTheme.colors.background.secondary
|
|
||||||
|
|
||||||
SystemBarsEffect {
|
LaunchedEffect(key1 = bottomSheetState.targetValue, navigationBarColor) {
|
||||||
if (showManageTokensBottomSheet) {
|
when (bottomSheetState.targetValue) {
|
||||||
setNavigationBarColor(navigationBarColor)
|
SheetValue.Hidden,
|
||||||
|
SheetValue.Expanded,
|
||||||
|
-> systemUiController.setNavigationBarColor(
|
||||||
|
color = Color.Transparent,
|
||||||
|
darkIcons = navigationBarColor.luminance() > 0.5f,
|
||||||
|
navigationBarContrastEnforced = true,
|
||||||
|
)
|
||||||
|
SheetValue.PartiallyExpanded,
|
||||||
|
-> systemUiController.setNavigationBarColor(navigationBarColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DisposableEffect(
|
|
||||||
showManageTokensBottomSheet,
|
DisposableEffect(showManageTokensBottomSheet) {
|
||||||
) {
|
|
||||||
onDispose {
|
onDispose {
|
||||||
if (showManageTokensBottomSheet) {
|
if (showManageTokensBottomSheet) {
|
||||||
systemUiController.setNavigationBarColor(navigationBarColorWithout)
|
systemUiController.setNavigationBarColor(
|
||||||
|
color = Color.Transparent,
|
||||||
|
darkIcons = navigationBarColor.luminance() > 0.5f,
|
||||||
|
navigationBarContrastEnforced = false,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -506,6 +515,7 @@ private fun BaseScaffold(
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = { WalletTopBar(config = state.topBarConfig) },
|
topBar = { WalletTopBar(config = state.topBarConfig) },
|
||||||
|
contentWindowInsets = WindowInsetsZero,
|
||||||
snackbarHost = {
|
snackbarHost = {
|
||||||
WalletSnackbarHost(
|
WalletSnackbarHost(
|
||||||
snackbarHostState = snackbarHostState,
|
snackbarHostState = snackbarHostState,
|
||||||
|
|
@ -520,7 +530,12 @@ private fun BaseScaffold(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
manageTokensButtonConfig?.let { ManageTokensButton(onClick = it.onClick) }
|
manageTokensButtonConfig?.let {
|
||||||
|
ManageTokensButton(
|
||||||
|
modifier = Modifier.navigationBarsPadding(),
|
||||||
|
onClick = it.onClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
floatingActionButtonPosition = FabPosition.Center,
|
floatingActionButtonPosition = FabPosition.Center,
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
containerColor = TangemTheme.colors.background.secondary,
|
||||||
|
|
@ -544,6 +559,8 @@ private fun BaseScaffold(
|
||||||
state = pullRefreshState,
|
state = pullRefreshState,
|
||||||
modifier = Modifier.align(Alignment.TopCenter),
|
modifier = Modifier.align(Alignment.TopCenter),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BottomFade(Modifier.align(Alignment.BottomCenter))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -565,11 +582,11 @@ private fun WalletSnackbarHost(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ManageTokensButton(onClick: () -> Unit) {
|
private fun ManageTokensButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
PrimaryButton(
|
PrimaryButton(
|
||||||
text = stringResource(id = R.string.main_manage_tokens),
|
text = stringResource(id = R.string.main_manage_tokens),
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue