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