Bottom sheet code cleanup

This commit is contained in:
Milan Cerovsky 2025-04-01 13:29:41 +02:00
parent 0209bec72b
commit 2281a8e60f
25 changed files with 227 additions and 301 deletions

View File

@ -90,7 +90,7 @@ fun rememberModalBottomSheetState(
@Composable
@ExperimentalMaterial3Api
private fun rememberSheetState(
fun rememberSheetState(
skipPartiallyExpanded: Boolean,
confirmValueChange: (SheetValue) -> Boolean,
initialValue: SheetValue,

View File

@ -0,0 +1,59 @@
package co.electriccoin.zcash.ui.design.component
import androidx.activity.compose.BackHandler
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SheetState
import androidx.compose.material3.SheetValue
import androidx.compose.material3.SheetValue.Hidden
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import co.electriccoin.zcash.ui.design.LocalSheetStateManager
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun <T : ModalBottomSheetState> ZashiScreenModalBottomSheet(
state: T?,
sheetState: SheetState = rememberScreenModalBottomSheetState(),
content: @Composable () -> Unit = {},
) {
ZashiModalBottomSheet(
sheetState = sheetState,
content = {
BackHandler(state != null) {
state?.onBack?.invoke()
}
content()
},
onDismissRequest = { state?.onBack?.invoke() }
)
LaunchedEffect(Unit) {
sheetState.show()
}
}
@Composable
@ExperimentalMaterial3Api
fun rememberScreenModalBottomSheetState(
initialValue: SheetValue = Hidden,
skipHiddenState: Boolean = false,
skipPartiallyExpanded: Boolean = true,
confirmValueChange: (SheetValue) -> Boolean = { true },
): SheetState {
val sheetManager = LocalSheetStateManager.current
val sheetState =
rememberSheetState(
skipPartiallyExpanded = skipPartiallyExpanded,
confirmValueChange = confirmValueChange,
initialValue = initialValue,
skipHiddenState = skipHiddenState,
)
DisposableEffect(sheetState) {
sheetManager.onSheetOpened(sheetState)
onDispose {
sheetManager.onSheetDisposed(sheetState)
}
}
return sheetState
}

View File

@ -1,18 +1,13 @@
package co.electriccoin.zcash.ui.screen.accountlist
import android.view.WindowManager
import androidx.activity.compose.BackHandler
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.window.DialogWindowProvider
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.electriccoin.zcash.ui.design.LocalSheetStateManager
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import co.electriccoin.zcash.ui.screen.accountlist.view.AccountListView
import co.electriccoin.zcash.ui.screen.accountlist.viewmodel.AccountListViewModel
import org.koin.androidx.compose.koinViewModel
@ -22,38 +17,12 @@ import org.koin.androidx.compose.koinViewModel
fun AndroidAccountList() {
val viewModel = koinViewModel<AccountListViewModel>()
val state by viewModel.state.collectAsStateWithLifecycle()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val sheetManager = LocalSheetStateManager.current
DisposableEffect(sheetState) {
sheetManager.onSheetOpened(sheetState)
onDispose {
sheetManager.onSheetDisposed(sheetState)
}
}
val parent = LocalView.current.parent
SideEffect {
(parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
(parent as? DialogWindowProvider)?.window?.setDimAmount(0f)
}
state?.let {
AccountListView(
state = it,
sheetState = sheetState,
onDismissRequest = {
state?.onBack?.invoke()
}
)
LaunchedEffect(Unit) {
sheetState.show()
}
BackHandler {
state?.onBack?.invoke()
}
AccountListView(it)
}
}

View File

@ -2,6 +2,7 @@ package co.electriccoin.zcash.ui.screen.accountlist.model
import androidx.annotation.DrawableRes
import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.ModalBottomSheetState
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState
import co.electriccoin.zcash.ui.design.util.StringResource
@ -9,8 +10,8 @@ data class AccountListState(
val items: List<AccountListItem>?,
val isLoading: Boolean,
val addWalletButton: ButtonState?,
val onBack: () -> Unit,
)
override val onBack: () -> Unit,
) : ModalBottomSheetState
data class ZashiAccountListItemState(
@DrawableRes val icon: Int,

View File

@ -33,13 +33,14 @@ import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.LottieProgress
import co.electriccoin.zcash.ui.design.component.ZashiButton
import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
import co.electriccoin.zcash.ui.design.component.ZashiModalBottomSheet
import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet
import co.electriccoin.zcash.ui.design.component.listitem.BaseListItem
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemColors
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemDefaults
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemDesignType
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
@ -54,16 +55,15 @@ import kotlinx.collections.immutable.persistentListOf
@Composable
@OptIn(ExperimentalMaterial3Api::class)
internal fun AccountListView(
onDismissRequest: () -> Unit,
sheetState: SheetState,
state: AccountListState
state: AccountListState,
sheetState: SheetState = rememberScreenModalBottomSheetState(),
) {
ZashiModalBottomSheet(
ZashiScreenModalBottomSheet(
state = state,
sheetState = sheetState,
content = {
BottomSheetContent(state)
},
onDismissRequest = onDismissRequest
)
}
@ -111,7 +111,10 @@ private fun BottomSheetContent(state: AccountListState) {
Spacer(modifier = Modifier.height(32.dp))
ZashiButton(
state = state.addWalletButton,
modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp),
modifier =
Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp),
colors =
ZashiButtonDefaults.secondaryColors(
borderColor = ZashiColors.Btns.Secondary.btnSecondaryBorder
@ -273,7 +276,6 @@ private fun Preview() =
onBack = {},
addWalletButton = ButtonState(stringRes("Connect Hardware Wallet"))
),
onDismissRequest = {},
sheetState =
rememberModalBottomSheetState(
skipHiddenState = true,
@ -317,7 +319,6 @@ private fun HardwareWalletAddedPreview() =
onBack = {},
addWalletButton = null
),
onDismissRequest = {},
sheetState =
rememberModalBottomSheetState(
skipHiddenState = true,

View File

@ -11,11 +11,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
@ -35,12 +30,9 @@ import co.electriccoin.zcash.ui.fixture.ZashiMainTopAppBarStateFixture
import co.electriccoin.zcash.ui.screen.balances.BalanceState
import co.electriccoin.zcash.ui.screen.balances.BalanceWidget
import co.electriccoin.zcash.ui.screen.home.messages.HomeMessage
import co.electriccoin.zcash.ui.screen.home.messages.HomeMessageState
import co.electriccoin.zcash.ui.screen.transactionhistory.widget.TransactionHistoryWidgetState
import co.electriccoin.zcash.ui.screen.transactionhistory.widget.TransactionHistoryWidgetStateFixture
import co.electriccoin.zcash.ui.screen.transactionhistory.widget.createTransactionHistoryWidgets
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
internal fun HomeView(
@ -142,8 +134,6 @@ private fun NavButtons(
@Composable
private fun Preview() {
ZcashTheme {
var isHomeMessageStateVisible by remember { mutableStateOf(true) }
val scope = rememberCoroutineScope()
HomeView(
appBarState = ZashiMainTopAppBarStateFixture.new(),
balanceState = BalanceStateFixture.new(),
@ -174,7 +164,7 @@ private fun Preview() {
icon = R.drawable.ic_warning,
onClick = {}
),
message = null.takeIf { isHomeMessageStateVisible }
message = null
)
)
}

View File

@ -40,7 +40,6 @@ class HomeViewModel(
private val isRestoreSuccessDialogVisible: IsRestoreSuccessDialogVisibleUseCase,
private val navigateToCoinbase: NavigateToCoinbaseUseCase
) : ViewModel() {
private val isMessageVisible = MutableStateFlow(true)
private val isRestoreDialogVisible: Flow<Boolean?> =

View File

@ -35,6 +35,7 @@ import androidx.compose.ui.zIndex
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
import kotlinx.coroutines.delay
@Suppress("MagicNumber")
@Composable
fun HomeMessage(state: HomeMessageState?) {
val cutoutHeight = 16.dp
@ -46,36 +47,41 @@ fun HomeMessage(state: HomeMessageState?) {
)
Box(
modifier = Modifier
.background(Color.Gray)
modifier =
Modifier
.background(Color.Gray)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(cutoutHeight)
.zIndex(2f)
.bottomOnlyShadow(
elevation = 2.dp,
shape = RoundedCornerShape(bottomStart = 32.dp, bottomEnd = 32.dp),
backgroundColor = ZashiColors.Surfaces.bgPrimary
),
modifier =
Modifier
.fillMaxWidth()
.height(cutoutHeight)
.zIndex(2f)
.bottomOnlyShadow(
elevation = 2.dp,
shape = RoundedCornerShape(bottomStart = 32.dp, bottomEnd = 32.dp),
backgroundColor = ZashiColors.Surfaces.bgPrimary
),
)
AnimatedVisibility(
modifier = Modifier
.fillMaxWidth()
.zIndex(0f),
modifier =
Modifier
.fillMaxWidth()
.zIndex(0f),
visible = isVisible,
enter = expandIn(animationSpec = tween(350)),
exit = shrinkOut(animationSpec = tween(350))
) {
when (normalizedState) {
is WalletBackupMessageState -> WalletBackupMessage(
state = normalizedState as WalletBackupMessageState,
contentPadding = PaddingValues(
vertical = cutoutHeight
is WalletBackupMessageState ->
WalletBackupMessage(
state = normalizedState as WalletBackupMessageState,
contentPadding =
PaddingValues(
vertical = cutoutHeight
)
)
)
null -> {
// do nothing
@ -84,16 +90,17 @@ fun HomeMessage(state: HomeMessageState?) {
}
Box(
modifier = Modifier
.fillMaxWidth()
.height(cutoutHeight)
.zIndex(1f)
.align(Alignment.BottomCenter)
.topOnlyShadow(
elevation = 2.dp,
shape = RoundedCornerShape(topStart = bottomCornerSize, topEnd = bottomCornerSize),
backgroundColor = ZashiColors.Surfaces.bgPrimary
),
modifier =
Modifier
.fillMaxWidth()
.height(cutoutHeight)
.zIndex(1f)
.align(Alignment.BottomCenter)
.topOnlyShadow(
elevation = 2.dp,
shape = RoundedCornerShape(topStart = bottomCornerSize, topEnd = bottomCornerSize),
backgroundColor = ZashiColors.Surfaces.bgPrimary
),
)
}
@ -116,25 +123,26 @@ private fun Modifier.bottomOnlyShadow(
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor,
): Modifier = this
.drawWithCache {
// bottom shadow offset in Px based on elevation
val bottomOffsetPx = elevation.toPx()
// Adjust the size to extend the bottom by the bottom shadow offset
val adjustedSize = Size(size.width, size.height + bottomOffsetPx)
val outline = shape.createOutline(adjustedSize, layoutDirection, this)
val path = Path().apply { addOutline(outline) }
onDrawWithContent {
clipPath(path, ClipOp.Intersect) {
this@onDrawWithContent.drawContent()
): Modifier =
this
.drawWithCache {
// bottom shadow offset in Px based on elevation
val bottomOffsetPx = elevation.toPx()
// Adjust the size to extend the bottom by the bottom shadow offset
val adjustedSize = Size(size.width, size.height + bottomOffsetPx)
val outline = shape.createOutline(adjustedSize, layoutDirection, this)
val path = Path().apply { addOutline(outline) }
onDrawWithContent {
clipPath(path, ClipOp.Intersect) {
this@onDrawWithContent.drawContent()
}
}
}
}
.shadow(elevation, shape, clip, ambientColor, spotColor)
.background(
backgroundColor,
shape
)
.shadow(elevation, shape, clip, ambientColor, spotColor)
.background(
backgroundColor,
shape
)
private fun Modifier.topOnlyShadow(
elevation: Dp,
@ -143,20 +151,21 @@ private fun Modifier.topOnlyShadow(
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor,
): Modifier = this
.drawWithCache {
// Adjust the size to extend the bottom by the bottom shadow offset
val adjustedSize = Size(size.width, size.height)
val outline = shape.createOutline(adjustedSize, layoutDirection, this)
val path = Path().apply { addOutline(outline) }
onDrawWithContent {
clipPath(path, ClipOp.Intersect) {
this@onDrawWithContent.drawContent()
): Modifier =
this
.drawWithCache {
// Adjust the size to extend the bottom by the bottom shadow offset
val adjustedSize = Size(size.width, size.height)
val outline = shape.createOutline(adjustedSize, layoutDirection, this)
val path = Path().apply { addOutline(outline) }
onDrawWithContent {
clipPath(path, ClipOp.Intersect) {
this@onDrawWithContent.drawContent()
}
}
}
}
.shadow(elevation, shape, clip, ambientColor, spotColor)
.background(
backgroundColor,
shape
)
.shadow(elevation, shape, clip, ambientColor, spotColor)
.background(
backgroundColor,
shape
)

View File

@ -1,3 +1,3 @@
package co.electriccoin.zcash.ui.screen.home.messages
sealed interface HomeMessageState
sealed interface HomeMessageState

View File

@ -25,13 +25,14 @@ fun HomeMessageWrapper(
modifier = Modifier.padding(contentPadding)
) {
Row(
modifier = Modifier.padding(
horizontal = 16.dp,
vertical = 14.dp
),
modifier =
Modifier.padding(
horizontal = 16.dp,
vertical = 14.dp
),
verticalAlignment = Alignment.CenterVertically,
content = content
)
}
}
}
}

View File

@ -25,7 +25,10 @@ import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
import co.electriccoin.zcash.ui.design.util.stringRes
@Composable
fun WalletBackupMessage(state: WalletBackupMessageState, contentPadding: PaddingValues) {
fun WalletBackupMessage(
state: WalletBackupMessageState,
contentPadding: PaddingValues
) {
HomeMessageWrapper(
color = ZashiColors.Utility.Espresso.utilityEspresso100,
contentPadding = contentPadding,
@ -54,10 +57,11 @@ fun WalletBackupMessage(state: WalletBackupMessageState, contentPadding: Padding
}
ZashiButton(
modifier = Modifier.height(36.dp),
state = ButtonState(
onClick = state.onClick,
text = stringRes("Start")
)
state =
ButtonState(
onClick = state.onClick,
text = stringRes("Start")
)
)
}
}
@ -69,13 +73,15 @@ data class WalletBackupMessageState(
@PreviewScreens
@Composable
private fun Preview() = ZcashTheme {
BlankSurface {
WalletBackupMessage(
state = WalletBackupMessageState(
onClick = {}
),
contentPadding = PaddingValues()
)
private fun Preview() =
ZcashTheme {
BlankSurface {
WalletBackupMessage(
state =
WalletBackupMessageState(
onClick = {}
),
contentPadding = PaddingValues()
)
}
}
}

View File

@ -1,18 +1,13 @@
package co.electriccoin.zcash.ui.screen.integrations
import android.view.WindowManager
import androidx.activity.compose.BackHandler
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.window.DialogWindowProvider
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.electriccoin.zcash.ui.design.LocalSheetStateManager
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import kotlinx.serialization.Serializable
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf
@ -20,22 +15,10 @@ import org.koin.core.parameter.parametersOf
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AndroidDialogIntegrations() {
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val sheetManager = LocalSheetStateManager.current
DisposableEffect(sheetState) {
sheetManager.onSheetOpened(sheetState)
onDispose {
sheetManager.onSheetDisposed(sheetState)
}
}
val parent = LocalView.current.parent
val viewModel = koinViewModel<IntegrationsViewModel> { parametersOf(true) }
val state by viewModel.state.collectAsStateWithLifecycle()
BackHandler(enabled = state != null) {
state?.onBack?.invoke()
}
SideEffect {
(parent as? DialogWindowProvider)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
(parent as? DialogWindowProvider)?.window?.setDimAmount(0f)
@ -44,15 +27,7 @@ fun AndroidDialogIntegrations() {
state?.let {
IntegrationsDialogView(
state = it,
sheetState = sheetState,
onDismissRequest = {
it.onBack()
}
)
LaunchedEffect(Unit) {
sheetState.show()
}
}
}

View File

@ -25,9 +25,10 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.design.component.HorizontalSpacer
import co.electriccoin.zcash.ui.design.component.ZashiModalBottomSheet
import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
@ -38,16 +39,15 @@ import kotlinx.collections.immutable.persistentListOf
@Composable
@OptIn(ExperimentalMaterial3Api::class)
internal fun IntegrationsDialogView(
onDismissRequest: () -> Unit,
sheetState: SheetState,
state: IntegrationsState
state: IntegrationsState,
sheetState: SheetState = rememberScreenModalBottomSheetState(),
) {
ZashiModalBottomSheet(
ZashiScreenModalBottomSheet(
state = state,
sheetState = sheetState,
content = {
BottomSheetContent(state)
},
onDismissRequest = onDismissRequest
)
}
@ -99,7 +99,6 @@ fun BottomSheetContent(state: IntegrationsState) {
private fun IntegrationSettings() =
ZcashTheme {
IntegrationsDialogView(
onDismissRequest = {},
sheetState =
rememberModalBottomSheetState(
skipHiddenState = true,

View File

@ -1,11 +1,12 @@
package co.electriccoin.zcash.ui.screen.integrations
import co.electriccoin.zcash.ui.design.component.ModalBottomSheetState
import co.electriccoin.zcash.ui.design.component.listitem.ZashiListItemState
import co.electriccoin.zcash.ui.design.util.StringResource
import kotlinx.collections.immutable.ImmutableList
data class IntegrationsState(
val disabledInfo: StringResource?,
val onBack: () -> Unit,
override val onBack: () -> Unit,
val items: ImmutableList<ZashiListItemState>,
)
) : ModalBottomSheetState

View File

@ -3,17 +3,11 @@ package co.electriccoin.zcash.ui.screen.restore.info
import android.view.WindowManager
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.window.DialogWindowProvider
import co.electriccoin.zcash.ui.NavigationRouter
import co.electriccoin.zcash.ui.design.LocalSheetStateManager
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import org.koin.compose.koinInject
@ -28,25 +22,9 @@ fun AndroidSeedInfo() {
(parent as? DialogWindowProvider)?.window?.setDimAmount(0f)
}
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val sheetManager = LocalSheetStateManager.current
DisposableEffect(sheetState) {
sheetManager.onSheetOpened(sheetState)
onDispose {
sheetManager.onSheetDisposed(sheetState)
}
}
SeedInfoView(
sheetState = sheetState,
state = remember { SeedInfoState(onBack = { navigationRouter.back() }) },
onDismissRequest = { navigationRouter.back() }
)
LaunchedEffect(Unit) {
sheetState.show()
}
}
@Serializable

View File

@ -1,5 +1,7 @@
package co.electriccoin.zcash.ui.screen.restore.info
import co.electriccoin.zcash.ui.design.component.ModalBottomSheetState
data class SeedInfoState(
val onBack: () -> Unit
)
override val onBack: () -> Unit
) : ModalBottomSheetState

View File

@ -1,6 +1,5 @@
package co.electriccoin.zcash.ui.screen.restore.info
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -28,8 +27,9 @@ import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.design.component.ZashiButton
import co.electriccoin.zcash.ui.design.component.ZashiModalBottomSheet
import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
@ -38,19 +38,15 @@ import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
@Composable
@OptIn(ExperimentalMaterial3Api::class)
internal fun SeedInfoView(
onDismissRequest: () -> Unit,
state: SeedInfoState,
sheetState: SheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
sheetState: SheetState = rememberScreenModalBottomSheetState(),
) {
ZashiModalBottomSheet(
ZashiScreenModalBottomSheet(
state = state,
sheetState = sheetState,
content = {
BackHandler {
state.onBack()
}
Content(state)
},
onDismissRequest = onDismissRequest
)
}
@ -132,6 +128,5 @@ private fun Preview() =
initialValue = SheetValue.Expanded,
),
state = SeedInfoState { },
onDismissRequest = {}
)
}

View File

@ -18,13 +18,14 @@ fun AndroidSeedBackup() {
val viewModel = koinActivityViewModel<WalletViewModel>()
val appBarState by viewModel.walletStateInformation.collectAsStateWithLifecycle()
val navigationRouter = koinInject<NavigationRouter>()
val state = remember {
SeedBackupState(
onBack = { navigationRouter.back() },
onNextClick = { navigationRouter.replace(SeedRecovery) },
onInfoClick = { navigationRouter.forward(SeedInfo) }
)
}
val state =
remember {
SeedBackupState(
onBack = { navigationRouter.back() },
onNextClick = { navigationRouter.replace(SeedRecovery) },
onInfoClick = { navigationRouter.forward(SeedInfo) }
)
}
BackHandler {
state.onBack()

View File

@ -157,10 +157,11 @@ private fun Content(
VerticalSpacer(24.dp)
ZashiButton(
state = ButtonState(
text = stringRes(stringResource(R.string.wallet_backup_btn)),
onClick = state.onNextClick
),
state =
ButtonState(
text = stringRes(stringResource(R.string.wallet_backup_btn)),
onClick = state.onNextClick
),
modifier = Modifier.fillMaxWidth()
)
}
@ -202,10 +203,11 @@ private fun Preview() =
ZcashTheme {
SeedBackupView(
appBarState = TopAppBarSubTitleState.None,
state = SeedBackupState(
onBack = {},
onNextClick = {},
onInfoClick = {}
)
state =
SeedBackupState(
onBack = {},
onNextClick = {},
onInfoClick = {}
)
)
}

View File

@ -1,18 +1,13 @@
package co.electriccoin.zcash.ui.screen.transactionfilters
import android.view.WindowManager
import androidx.activity.compose.BackHandler
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.window.DialogWindowProvider
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.electriccoin.zcash.ui.design.LocalSheetStateManager
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import co.electriccoin.zcash.ui.screen.transactionfilters.view.TransactionFiltersView
import co.electriccoin.zcash.ui.screen.transactionfilters.viewmodel.TransactionFiltersViewModel
import org.koin.androidx.compose.koinViewModel
@ -22,16 +17,6 @@ import org.koin.androidx.compose.koinViewModel
fun AndroidTransactionFiltersList() {
val viewModel = koinViewModel<TransactionFiltersViewModel>()
val state by viewModel.state.collectAsStateWithLifecycle()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val sheetManager = LocalSheetStateManager.current
DisposableEffect(sheetState) {
sheetManager.onSheetOpened(sheetState)
onDispose {
sheetManager.onSheetDisposed(sheetState)
}
}
val parent = LocalView.current.parent
SideEffect {
@ -41,15 +26,5 @@ fun AndroidTransactionFiltersList() {
TransactionFiltersView(
state = state,
sheetState = sheetState,
onDismissRequest = state?.onBack ?: {}
)
LaunchedEffect(Unit) {
sheetState.show()
}
BackHandler(state != null) {
state?.onBack?.invoke()
}
}

View File

@ -1,14 +1,15 @@
package co.electriccoin.zcash.ui.screen.transactionfilters.model
import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.ModalBottomSheetState
import co.electriccoin.zcash.ui.design.util.StringResource
data class TransactionFiltersState(
val filters: List<TransactionFilterState>,
val onBack: () -> Unit,
override val onBack: () -> Unit,
val primaryButton: ButtonState,
val secondaryButton: ButtonState
)
) : ModalBottomSheetState
data class TransactionFilterState(
val text: StringResource,

View File

@ -35,8 +35,9 @@ import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
import co.electriccoin.zcash.ui.design.component.ZashiChipButton
import co.electriccoin.zcash.ui.design.component.ZashiChipButtonDefaults
import co.electriccoin.zcash.ui.design.component.ZashiChipButtonState
import co.electriccoin.zcash.ui.design.component.ZashiModalBottomSheet
import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
@ -47,16 +48,15 @@ import co.electriccoin.zcash.ui.screen.transactionfilters.model.TransactionFilte
@Composable
@OptIn(ExperimentalMaterial3Api::class)
internal fun TransactionFiltersView(
onDismissRequest: () -> Unit,
sheetState: SheetState,
state: TransactionFiltersState?
state: TransactionFiltersState?,
sheetState: SheetState = rememberScreenModalBottomSheetState(),
) {
ZashiModalBottomSheet(
ZashiScreenModalBottomSheet(
state = state,
sheetState = sheetState,
content = {
BottomSheetContent(state)
},
onDismissRequest = onDismissRequest
)
}
@ -168,7 +168,6 @@ private fun Preview() =
ZcashTheme {
TransactionFiltersView(
state = TransactionFiltersStateFixture.new(),
onDismissRequest = {},
sheetState =
rememberModalBottomSheetState(
skipHiddenState = true,

View File

@ -1,23 +1,15 @@
package co.electriccoin.zcash.ui.screen.transactionnote
import android.view.WindowManager
import androidx.activity.compose.BackHandler
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SheetValue.Expanded
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.window.DialogWindowProvider
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.electriccoin.zcash.ui.design.LocalSheetStateManager
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import co.electriccoin.zcash.ui.screen.transactionnote.view.TransactionNoteView
import co.electriccoin.zcash.ui.screen.transactionnote.viewmodel.TransactionNoteViewModel
import kotlinx.coroutines.cancel
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf
@ -26,15 +18,6 @@ import org.koin.core.parameter.parametersOf
fun AndroidTransactionNote(transactionNote: TransactionNote) {
val viewModel = koinViewModel<TransactionNoteViewModel> { parametersOf(transactionNote) }
val state by viewModel.state.collectAsStateWithLifecycle()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val sheetManager = LocalSheetStateManager.current
DisposableEffect(sheetState) {
sheetManager.onSheetOpened(sheetState)
onDispose {
sheetManager.onSheetDisposed(sheetState)
}
}
val parent = LocalView.current.parent
SideEffect {
@ -42,25 +25,5 @@ fun AndroidTransactionNote(transactionNote: TransactionNote) {
(parent as? DialogWindowProvider)?.window?.setDimAmount(0f)
}
TransactionNoteView(
state = state,
sheetState = sheetState,
onDismissRequest = state.onBack,
)
LaunchedEffect(Unit) {
sheetState.show()
}
LaunchedEffect(Unit) {
snapshotFlow { sheetState.currentValue }.collect {
if (it == Expanded) {
this.cancel()
}
}
}
BackHandler {
state.onBack()
}
TransactionNoteView(state = state)
}

View File

@ -1,16 +1,17 @@
package co.electriccoin.zcash.ui.screen.transactionnote.model
import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.ModalBottomSheetState
import co.electriccoin.zcash.ui.design.component.TextFieldState
import co.electriccoin.zcash.ui.design.util.StringResource
import co.electriccoin.zcash.ui.design.util.StyledStringResource
data class TransactionNoteState(
val onBack: () -> Unit,
override val onBack: () -> Unit,
val title: StringResource,
val note: TextFieldState,
val noteCharacters: StyledStringResource,
val primaryButton: ButtonState?,
val secondaryButton: ButtonState?,
val negative: ButtonState?,
)
) : ModalBottomSheetState

View File

@ -22,9 +22,10 @@ import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.TextFieldState
import co.electriccoin.zcash.ui.design.component.ZashiButton
import co.electriccoin.zcash.ui.design.component.ZashiButtonDefaults
import co.electriccoin.zcash.ui.design.component.ZashiModalBottomSheet
import co.electriccoin.zcash.ui.design.component.ZashiScreenModalBottomSheet
import co.electriccoin.zcash.ui.design.component.ZashiTextField
import co.electriccoin.zcash.ui.design.component.rememberModalBottomSheetState
import co.electriccoin.zcash.ui.design.component.rememberScreenModalBottomSheetState
import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
@ -38,16 +39,15 @@ import co.electriccoin.zcash.ui.screen.transactionnote.model.TransactionNoteStat
@Composable
@OptIn(ExperimentalMaterial3Api::class)
internal fun TransactionNoteView(
onDismissRequest: () -> Unit,
sheetState: SheetState,
state: TransactionNoteState,
sheetState: SheetState = rememberScreenModalBottomSheetState(),
) {
ZashiModalBottomSheet(
ZashiScreenModalBottomSheet(
state = state,
sheetState = sheetState,
content = {
BottomSheetContent(state)
},
onDismissRequest = onDismissRequest
)
}
@ -147,7 +147,6 @@ private fun Preview() =
secondaryButton = null,
negative = ButtonState(stringRes("Delete note")),
),
onDismissRequest = {},
sheetState =
rememberModalBottomSheetState(
skipHiddenState = true,