Updated on 2026-08-14
This commit is contained in:
parent
8ceec04254
commit
6948168b9c
1 changed files with 88 additions and 2 deletions
|
|
@ -1,13 +1,22 @@
|
|||
package com.tangem.managetokens.presentation.addcustomtoken.ui
|
||||
|
||||
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.material3.BottomSheetDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.ModalBottomSheetDefaults
|
||||
import androidx.compose.material3.ModalBottomSheetProperties
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.SheetValue
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
|
|
@ -15,8 +24,18 @@ import androidx.compose.runtime.LaunchedEffect
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.input.key.Key
|
||||
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.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
|
|
@ -29,6 +48,7 @@ import com.tangem.managetokens.presentation.addcustomtoken.router.AddCustomToken
|
|||
import com.tangem.managetokens.presentation.addcustomtoken.router.AddCustomTokenRouter
|
||||
import com.tangem.managetokens.presentation.addcustomtoken.viewmodels.AddCustomTokenViewModel
|
||||
import com.tangem.managetokens.presentation.common.state.ChooseWalletState
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -46,14 +66,14 @@ fun AddCustomTokenBottomSheet(config: TangemBottomSheetConfig) {
|
|||
onDispose { viewModel.onDispose() }
|
||||
}
|
||||
|
||||
// FIXME: handle back presses after updating material3 to 1.2.0
|
||||
ModalBottomSheet(
|
||||
ModalBottomSheetWithBackHandling(
|
||||
onDismissRequest = config.onDismissRequest,
|
||||
sheetState = sheetState,
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
shape = TangemTheme.shapes.bottomSheetLarge,
|
||||
windowInsets = WindowInsets.systemBars.only(WindowInsetsSides.Top),
|
||||
dragHandle = { TangemBottomSheetDraggableHeader(color = TangemTheme.colors.background.tertiary) },
|
||||
properties = ModalBottomSheetDefaults.properties(shouldDismissOnBackPress = false),
|
||||
) {
|
||||
Content(onDismissRequest = config.onDismissRequest, viewModel = viewModel)
|
||||
}
|
||||
|
|
@ -68,6 +88,68 @@ fun AddCustomTokenBottomSheet(config: TangemBottomSheetConfig) {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun ModalBottomSheetWithBackHandling(
|
||||
onDismissRequest: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
containerColor: Color = BottomSheetDefaults.ContainerColor,
|
||||
shape: Shape = BottomSheetDefaults.ExpandedShape,
|
||||
windowInsets: WindowInsets = BottomSheetDefaults.windowInsets,
|
||||
dragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults.DragHandle() },
|
||||
sheetState: SheetState = rememberModalBottomSheetState(),
|
||||
properties: ModalBottomSheetProperties = ModalBottomSheetDefaults.properties(),
|
||||
content: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
BackHandler(enabled = sheetState.targetValue != SheetValue.Hidden) {
|
||||
// Always catch back here, but only let it dismiss if shouldDismissOnBackPress.
|
||||
// If not, it will have no effect.
|
||||
if (properties.shouldDismissOnBackPress) {
|
||||
scope.launch { sheetState.hide() }.invokeOnCompletion {
|
||||
if (!sheetState.isVisible) {
|
||||
onDismissRequest()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val requester = remember { FocusRequester() }
|
||||
val backPressedDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
|
||||
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = onDismissRequest,
|
||||
containerColor = containerColor,
|
||||
shape = shape,
|
||||
windowInsets = windowInsets,
|
||||
dragHandle = dragHandle,
|
||||
sheetState = sheetState,
|
||||
modifier = modifier
|
||||
.focusRequester(requester)
|
||||
.focusable()
|
||||
.onPreviewKeyEvent {
|
||||
if (it.key == Key.Back && it.type == KeyEventType.KeyUp && !it.nativeKeyEvent.isCanceled) {
|
||||
backPressedDispatcherOwner?.onBackPressedDispatcher?.onBackPressed()
|
||||
return@onPreviewKeyEvent true
|
||||
}
|
||||
return@onPreviewKeyEvent false
|
||||
},
|
||||
properties = ModalBottomSheetDefaults.properties(
|
||||
securePolicy = properties.securePolicy,
|
||||
isFocusable = properties.isFocusable,
|
||||
// Set false otherwise the onPreviewKeyEvent doesn't work at all.
|
||||
// The functionality of shouldDismissOnBackPress is achieved by the BackHandler.
|
||||
shouldDismissOnBackPress = false,
|
||||
),
|
||||
content = content,
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
requester.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Composable
|
||||
private fun Content(viewModel: AddCustomTokenViewModel, onDismissRequest: () -> Unit) {
|
||||
|
|
@ -82,6 +164,10 @@ private fun Content(viewModel: AddCustomTokenViewModel, onDismissRequest: () ->
|
|||
}
|
||||
}
|
||||
|
||||
BackHandler(true) {
|
||||
navController.popBackStack()
|
||||
}
|
||||
|
||||
val router = remember(navController) { AddCustomTokenRouter(navController) }
|
||||
|
||||
viewModel.router = router
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue