diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/KeyboardManager.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/KeyboardManager.kt new file mode 100644 index 000000000..4bc6526fa --- /dev/null +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/KeyboardManager.kt @@ -0,0 +1,80 @@ +package co.electriccoin.zcash.ui.design + +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.ime +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.Stable +import androidx.compose.runtime.State +import androidx.compose.runtime.compositionLocalOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.platform.SoftwareKeyboardController +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.withTimeoutOrNull +import kotlin.time.Duration.Companion.seconds + +@Stable +class KeyboardManager( + isOpen: Boolean, + private val softwareKeyboardController: SoftwareKeyboardController? +) { + private var targetState = MutableStateFlow(isOpen) + + var isOpen by mutableStateOf(isOpen) + private set + + suspend fun close() { + if (targetState.value) { + withTimeoutOrNull(.5.seconds) { + softwareKeyboardController?.hide() + targetState.filter { !it }.first() + } + } + } + + fun onKeyboardOpened() { + targetState.update { true } + isOpen = true + } + + fun onKeyboardClosed() { + targetState.update { false } + isOpen = false + } +} + +@Composable +fun rememberKeyboardManager(): KeyboardManager { + val isKeyboardOpen by rememberKeyboardState() + val softwareKeyboardController = LocalSoftwareKeyboardController.current + val keyboardManager = remember { KeyboardManager(isKeyboardOpen, softwareKeyboardController) } + LaunchedEffect(isKeyboardOpen) { + if (isKeyboardOpen) { + keyboardManager.onKeyboardOpened() + } else { + keyboardManager.onKeyboardClosed() + } + } + return keyboardManager +} + +@Composable +private fun rememberKeyboardState(): State { + val isImeVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0 + return rememberUpdatedState(isImeVisible) +} + +@Suppress("CompositionLocalAllowlist") +val LocalKeyboardManager = + compositionLocalOf { + error("Keyboard manager not provided") + } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/SheetStateManager.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/SheetStateManager.kt new file mode 100644 index 000000000..12c83d27e --- /dev/null +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/SheetStateManager.kt @@ -0,0 +1,41 @@ +package co.electriccoin.zcash.ui.design + +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.compositionLocalOf +import androidx.compose.runtime.remember +import kotlinx.coroutines.withTimeoutOrNull +import kotlin.time.Duration.Companion.seconds + +@OptIn(ExperimentalMaterial3Api::class) +@Stable +class SheetStateManager { + private var sheetState: SheetState? = null + + fun onSheetOpened(sheetState: SheetState) { + this.sheetState = sheetState + } + + fun onSheetDisposed(sheetState: SheetState) { + if (this.sheetState == sheetState) { + this.sheetState = null + } + } + + suspend fun hide() { + withTimeoutOrNull(.5.seconds) { + sheetState?.hide() + } + } +} + +@Composable +fun rememberSheetStateManager() = remember { SheetStateManager() } + +@Suppress("CompositionLocalAllowlist") +val LocalSheetStateManager = + compositionLocalOf { + error("Sheet state manager not provided") + } diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ZcashTheme.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ZcashTheme.kt index 375771aed..a9ea1bf24 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ZcashTheme.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ZcashTheme.kt @@ -9,6 +9,10 @@ import androidx.compose.material3.RippleConfiguration import androidx.compose.material3.RippleDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import co.electriccoin.zcash.ui.design.LocalKeyboardManager +import co.electriccoin.zcash.ui.design.LocalSheetStateManager +import co.electriccoin.zcash.ui.design.rememberKeyboardManager +import co.electriccoin.zcash.ui.design.rememberSheetStateManager import co.electriccoin.zcash.ui.design.theme.balances.LocalBalancesAvailable import co.electriccoin.zcash.ui.design.theme.colors.DarkZashiColorsInternal import co.electriccoin.zcash.ui.design.theme.colors.LightZashiColorsInternal @@ -49,7 +53,9 @@ fun ZcashTheme( LocalZashiColors provides zashiColors, LocalZashiTypography provides ZashiTypographyInternal, LocalRippleConfiguration provides MaterialRippleConfig, - LocalBalancesAvailable provides balancesAvailable + LocalBalancesAvailable provides balancesAvailable, + LocalKeyboardManager provides rememberKeyboardManager(), + LocalSheetStateManager provides rememberSheetStateManager() ) { ProvideDimens { MaterialTheme( diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt index a92117498..a2e160be4 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/MainActivity.kt @@ -118,7 +118,6 @@ class MainActivity : FragmentActivity() { } } - // Note this condition needs to be kept in sync with the condition in MainContent() SecretState.LOADING == walletViewModel.secretState.value } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt index fbc2c1201..5027ce957 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt @@ -6,7 +6,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.window.DialogProperties import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -39,6 +38,8 @@ import co.electriccoin.zcash.ui.NavigationTargets.WHATS_NEW import co.electriccoin.zcash.ui.common.compose.LocalNavController import co.electriccoin.zcash.ui.common.provider.ApplicationStateProvider import co.electriccoin.zcash.ui.common.provider.isInForeground +import co.electriccoin.zcash.ui.design.LocalKeyboardManager +import co.electriccoin.zcash.ui.design.LocalSheetStateManager import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.enterTransition import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.exitTransition import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.popEnterTransition @@ -122,9 +123,10 @@ import org.koin.compose.koinInject @Suppress("LongMethod", "CyclomaticComplexMethod") internal fun MainActivity.Navigation() { val navController = LocalNavController.current - val focusManager = LocalFocusManager.current + val keyboardManager = LocalKeyboardManager.current val flexaViewModel = koinViewModel() val navigationRouter = koinInject() + val sheetStateManager = LocalSheetStateManager.current // Helper properties for triggering the system security UI from callbacks val (exportPrivateDataAuthentication, setExportPrivateDataAuthentication) = @@ -136,13 +138,15 @@ internal fun MainActivity.Navigation() { remember( navController, flexaViewModel, - focusManager + keyboardManager, + sheetStateManager ) { NavigatorImpl( activity = this@Navigation, navController = navController, flexaViewModel = flexaViewModel, - focusManager = focusManager + keyboardManager = keyboardManager, + sheetStateManager = sheetStateManager ) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigator.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigator.kt index e80fab719..44eaf731b 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigator.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigator.kt @@ -2,10 +2,11 @@ package co.electriccoin.zcash.ui import android.annotation.SuppressLint import androidx.activity.ComponentActivity -import androidx.compose.ui.focus.FocusManager import androidx.navigation.NavHostController import androidx.navigation.NavOptionsBuilder import androidx.navigation.serialization.generateHashCode +import co.electriccoin.zcash.ui.design.KeyboardManager +import co.electriccoin.zcash.ui.design.SheetStateManager import co.electriccoin.zcash.ui.screen.ExternalUrl import co.electriccoin.zcash.ui.screen.about.util.WebBrowserUtil import co.electriccoin.zcash.ui.screen.flexa.FlexaViewModel @@ -15,17 +16,19 @@ import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.serializer interface Navigator { - fun executeCommand(command: NavigationCommand) + suspend fun executeCommand(command: NavigationCommand) } class NavigatorImpl( private val activity: ComponentActivity, private val navController: NavHostController, private val flexaViewModel: FlexaViewModel, - private val focusManager: FocusManager, + private val keyboardManager: KeyboardManager, + private val sheetStateManager: SheetStateManager, ) : Navigator { - override fun executeCommand(command: NavigationCommand) { - focusManager.clearFocus(true) + override suspend fun executeCommand(command: NavigationCommand) { + keyboardManager.close() + sheetStateManager.hide() when (command) { is NavigationCommand.Forward -> forward(command) is NavigationCommand.Replace -> replace(command) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/ApplyTransactionFiltersUseCase.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/ApplyTransactionFiltersUseCase.kt index 740e82b02..b634fd577 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/ApplyTransactionFiltersUseCase.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/ApplyTransactionFiltersUseCase.kt @@ -8,12 +8,8 @@ class ApplyTransactionFiltersUseCase( private val transactionFilterRepository: TransactionFilterRepository, private val navigationRouter: NavigationRouter, ) { - suspend operator fun invoke( - filters: List, - hideBottomSheet: suspend () -> Unit - ) { + operator fun invoke(filters: List) { transactionFilterRepository.apply(filters) - hideBottomSheet() navigationRouter.back() } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/CreateOrUpdateTransactionNoteUseCase.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/CreateOrUpdateTransactionNoteUseCase.kt index 75f008769..d948b5467 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/CreateOrUpdateTransactionNoteUseCase.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/CreateOrUpdateTransactionNoteUseCase.kt @@ -9,11 +9,9 @@ class CreateOrUpdateTransactionNoteUseCase( ) { suspend operator fun invoke( txId: String, - note: String, - closeBottomSheet: suspend () -> Unit + note: String ) { metadataRepository.createOrUpdateTxNote(txId, note.trim()) - closeBottomSheet() navigationRouter.back() } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/DeleteTransactionNoteUseCase.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/DeleteTransactionNoteUseCase.kt index 9c4e34865..9f0bf06fb 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/DeleteTransactionNoteUseCase.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/DeleteTransactionNoteUseCase.kt @@ -7,12 +7,8 @@ class DeleteTransactionNoteUseCase( private val metadataRepository: MetadataRepository, private val navigationRouter: NavigationRouter ) { - suspend operator fun invoke( - txId: String, - closeBottomSheet: suspend () -> Unit - ) { + suspend operator fun invoke(txId: String) { metadataRepository.deleteTxNote(txId) - closeBottomSheet() navigationRouter.back() } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/SelectWalletAccountUseCase.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/SelectWalletAccountUseCase.kt index c80a29547..a039347dc 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/SelectWalletAccountUseCase.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/SelectWalletAccountUseCase.kt @@ -8,12 +8,8 @@ class SelectWalletAccountUseCase( private val accountDataSource: AccountDataSource, private val navigationRouter: NavigationRouter ) { - suspend operator fun invoke( - account: WalletAccount, - hideBottomSheet: suspend () -> Unit - ) { + suspend operator fun invoke(account: WalletAccount) { accountDataSource.selectAccount(account) - hideBottomSheet() navigationRouter.back() } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/AndroidAccountList.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/AndroidAccountList.kt index 8686c4802..d1d02b780 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/AndroidAccountList.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/AndroidAccountList.kt @@ -4,12 +4,14 @@ 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 @@ -22,6 +24,13 @@ fun AndroidAccountList() { 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 @@ -43,13 +52,6 @@ fun AndroidAccountList() { sheetState.show() } - LaunchedEffect(Unit) { - viewModel.hideBottomSheetRequest.collect { - sheetState.hide() - state?.onBottomSheetHidden?.invoke() - } - } - BackHandler { state?.onBack?.invoke() } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/model/AccountListState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/model/AccountListState.kt index f1d58d626..af6a7598a 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/model/AccountListState.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/model/AccountListState.kt @@ -8,7 +8,6 @@ import co.electriccoin.zcash.ui.design.util.StringResource data class AccountListState( val items: List?, val isLoading: Boolean, - val onBottomSheetHidden: () -> Unit, val addWalletButton: ButtonState?, val onBack: () -> Unit, ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/view/AccountListView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/view/AccountListView.kt index f450e8bab..7d7e85082 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/view/AccountListView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/view/AccountListView.kt @@ -270,7 +270,6 @@ private fun Preview() = ) ), isLoading = false, - onBottomSheetHidden = {}, onBack = {}, addWalletButton = ButtonState(stringRes("Connect Hardware Wallet")) ), @@ -315,7 +314,6 @@ private fun HardwareWalletAddedPreview() = ), ), isLoading = false, - onBottomSheetHidden = {}, onBack = {}, addWalletButton = null ), diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/viewmodel/AccountListViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/viewmodel/AccountListViewModel.kt index 1ed5cf1ef..180a90450 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/viewmodel/AccountListViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/accountlist/viewmodel/AccountListViewModel.kt @@ -19,10 +19,8 @@ import co.electriccoin.zcash.ui.screen.accountlist.model.AccountListState import co.electriccoin.zcash.ui.screen.accountlist.model.ZashiAccountListItemState import co.electriccoin.zcash.ui.screen.addressbook.viewmodel.ADDRESS_MAX_LENGTH import co.electriccoin.zcash.ui.screen.connectkeystone.ConnectKeystone -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.WhileSubscribed -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -32,10 +30,6 @@ class AccountListViewModel( private val selectWalletAccount: SelectWalletAccountUseCase, private val navigationRouter: NavigationRouter, ) : ViewModel() { - val hideBottomSheetRequest = MutableSharedFlow() - - private val bottomSheetHiddenResponse = MutableSharedFlow() - @Suppress("SpreadOperator") val state = getWalletAccounts.observe().map { accounts -> @@ -77,7 +71,6 @@ class AccountListViewModel( AccountListState( items = items, isLoading = accounts == null, - onBottomSheetHidden = ::onBottomSheetHidden, onBack = ::onBack, addWalletButton = ButtonState( @@ -94,35 +87,14 @@ class AccountListViewModel( ) private fun onShowKeystonePromoClicked() = - viewModelScope.launch { - hideBottomSheet() - navigationRouter.replace(ExternalUrl("https://keyst.one/shop/products/keystone-3-pro?discount=Zashi")) - } - - private suspend fun hideBottomSheet() { - hideBottomSheetRequest.emit(Unit) - bottomSheetHiddenResponse.first() - } - - private fun onBottomSheetHidden() = - viewModelScope.launch { - bottomSheetHiddenResponse.emit(Unit) - } + navigationRouter.replace(ExternalUrl("https://keyst.one/shop/products/keystone-3-pro?discount=Zashi")) private fun onAccountClicked(account: WalletAccount) = viewModelScope.launch { - selectWalletAccount(account) { hideBottomSheet() } + selectWalletAccount(account) } - private fun onAddWalletButtonClicked() = - viewModelScope.launch { - hideBottomSheet() - navigationRouter.forward(ConnectKeystone) - } + private fun onAddWalletButtonClicked() = navigationRouter.forward(ConnectKeystone) - private fun onBack() = - viewModelScope.launch { - hideBottomSheet() - navigationRouter.back() - } + private fun onBack() = navigationRouter.back() } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/AndroidDialogIntegrations.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/AndroidDialogIntegrations.kt index 1ca3a22d3..45a56764c 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/AndroidDialogIntegrations.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/AndroidDialogIntegrations.kt @@ -4,12 +4,14 @@ 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 @@ -19,6 +21,13 @@ import org.koin.core.parameter.parametersOf @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 { parametersOf(true) } val state by viewModel.state.collectAsStateWithLifecycle() @@ -44,13 +53,6 @@ fun AndroidDialogIntegrations() { LaunchedEffect(Unit) { sheetState.show() } - - LaunchedEffect(Unit) { - viewModel.hideBottomSheetRequest.collect { - sheetState.hide() - state?.onBottomSheetHidden?.invoke() - } - } } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsDialogView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsDialogView.kt index ba5d9028a..770558670 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsDialogView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsDialogView.kt @@ -132,7 +132,6 @@ private fun IntegrationSettings() = onClick = {} ), ), - onBottomSheetHidden = {} ), ) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsState.kt index 361d7fda8..caeebbdfb 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsState.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsState.kt @@ -8,5 +8,4 @@ data class IntegrationsState( val disabledInfo: StringResource?, val onBack: () -> Unit, val items: ImmutableList, - val onBottomSheetHidden: () -> Unit, ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsView.kt index 451d1d2e8..ee9d5399a 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsView.kt @@ -197,7 +197,6 @@ private fun IntegrationSettings() = onClick = {} ), ), - onBottomSheetHidden = {} ), topAppBarSubTitleState = TopAppBarSubTitleState.None, ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsViewModel.kt index 6bdd0e1a0..cbf90aa3e 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/integrations/IntegrationsViewModel.kt @@ -25,11 +25,9 @@ import co.electriccoin.zcash.ui.design.util.stringRes import co.electriccoin.zcash.ui.screen.connectkeystone.ConnectKeystone import co.electriccoin.zcash.ui.screen.flexa.Flexa import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.WhileSubscribed import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -45,10 +43,6 @@ class IntegrationsViewModel( private val navigationRouter: NavigationRouter, private val navigateToCoinbase: NavigateToCoinbaseUseCase, ) : ViewModel() { - val hideBottomSheetRequest = MutableSharedFlow() - - private val bottomSheetHiddenResponse = MutableSharedFlow() - private val isRestoring = getWalletRestoringState.observe().map { it == WalletRestoringState.RESTORING } val state = @@ -123,43 +117,25 @@ class IntegrationsViewModel( onClick = ::onConnectKeystoneClick ).takeIf { keystoneStatus != UNAVAILABLE }, ).toImmutableList(), - onBottomSheetHidden = ::onBottomSheetHidden ) private fun onBack() = navigationRouter.back() - private suspend fun hideBottomSheet() { - if (isDialog) { - hideBottomSheetRequest.emit(Unit) - bottomSheetHiddenResponse.first() - } - } - - private fun onBottomSheetHidden() = - viewModelScope.launch { - bottomSheetHiddenResponse.emit(Unit) - } - private fun onBuyWithCoinbaseClicked() = viewModelScope.launch { - hideBottomSheet() navigateToCoinbase(isDialog) } private fun onConnectKeystoneClick() = viewModelScope.launch { - hideBottomSheet() navigationRouter.replace(ConnectKeystone) } - private fun onFlexaClicked() = - viewModelScope.launch { - if (isDialog) { - hideBottomSheet() - navigationRouter.replace(Flexa) - } else { - hideBottomSheet() - navigationRouter.forward(Flexa) - } + private fun onFlexaClicked() { + if (isDialog) { + navigationRouter.replace(Flexa) + } else { + navigationRouter.forward(Flexa) } + } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/OnboardingNavigation.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/OnboardingNavigation.kt index 61aaa5091..bf4c78f42 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/OnboardingNavigation.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/onboarding/OnboardingNavigation.kt @@ -6,7 +6,6 @@ import android.content.Context import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember -import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.window.DialogProperties import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -27,6 +26,8 @@ import co.electriccoin.zcash.ui.common.compose.LocalNavController import co.electriccoin.zcash.ui.common.model.OnboardingState import co.electriccoin.zcash.ui.common.model.WalletRestoringState import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel +import co.electriccoin.zcash.ui.design.LocalKeyboardManager +import co.electriccoin.zcash.ui.design.LocalSheetStateManager import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.enterTransition import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.exitTransition import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.popEnterTransition @@ -51,19 +52,23 @@ fun MainActivity.OnboardingNavigation() { val activity = LocalActivity.current val navigationRouter = koinInject() val navController = LocalNavController.current - val focusManager = LocalFocusManager.current + val keyboardManager = LocalKeyboardManager.current val flexaViewModel = koinViewModel() + val sheetStateManager = LocalSheetStateManager.current + val navigator: Navigator = remember( navController, flexaViewModel, - focusManager + keyboardManager, + sheetStateManager ) { NavigatorImpl( activity = this@OnboardingNavigation, navController = navController, flexaViewModel = flexaViewModel, - focusManager = focusManager + keyboardManager = keyboardManager, + sheetStateManager = sheetStateManager ) } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/AndroidSeedInfo.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/AndroidSeedInfo.kt index 7d5d39771..1ec7e1a5a 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/AndroidSeedInfo.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/info/AndroidSeedInfo.kt @@ -3,12 +3,14 @@ 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.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 @@ -27,6 +29,14 @@ fun AndroidSeedInfo() { } val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + val sheetManager = LocalSheetStateManager.current + + DisposableEffect(sheetState) { + sheetManager.onSheetOpened(sheetState) + onDispose { + sheetManager.onSheetDisposed(sheetState) + } + } SeedInfoView( sheetState = sheetState, @@ -34,14 +44,14 @@ fun AndroidSeedInfo() { SeedInfoState( onBack = { scope.launch { - sheetState.hide() + // sheetState.hide() navigationRouter.back() } } ), onDismissRequest = { scope.launch { - sheetState.hide() + // sheetState.hide() navigationRouter.back() } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/seed/RestoreSeedView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/seed/RestoreSeedView.kt index cc19aa546..3f2b37618 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/seed/RestoreSeedView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/seed/RestoreSeedView.kt @@ -8,11 +8,9 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.ime import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -25,17 +23,14 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource @@ -44,6 +39,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.common.appbar.ZashiTopAppBarTags +import co.electriccoin.zcash.ui.design.LocalKeyboardManager import co.electriccoin.zcash.ui.design.component.BlankBgScaffold import co.electriccoin.zcash.ui.design.component.ButtonState import co.electriccoin.zcash.ui.design.component.IconButtonState @@ -76,13 +72,12 @@ fun RestoreSeedView( val focusManager = LocalFocusManager.current var wasKeyboardOpen by remember { mutableStateOf(false) } - val isKeyboardOpen by rememberKeyboardState() - + val keyboardManager = LocalKeyboardManager.current + val isKeyboardOpen = keyboardManager.isOpen LaunchedEffect(isKeyboardOpen) { if (wasKeyboardOpen && !isKeyboardOpen) { focusManager.clearFocus(true) } - wasKeyboardOpen = isKeyboardOpen } @@ -278,12 +273,6 @@ private fun getFilteredSuggestions( } } -@Composable -private fun rememberKeyboardState(): State { - val isImeVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0 - return rememberUpdatedState(isImeVisible) -} - @PreviewScreens @Composable private fun Preview() = diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/AndroidTransactionFilters.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/AndroidTransactionFilters.kt index 3377cca4f..abac116cf 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/AndroidTransactionFilters.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/AndroidTransactionFilters.kt @@ -4,12 +4,14 @@ 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 @@ -22,6 +24,13 @@ fun AndroidTransactionFiltersList() { 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 @@ -40,13 +49,6 @@ fun AndroidTransactionFiltersList() { sheetState.show() } - LaunchedEffect(Unit) { - viewModel.hideBottomSheetRequest.collect { - sheetState.hide() - state?.onBottomSheetHidden?.invoke() - } - } - BackHandler(state != null) { state?.onBack?.invoke() } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/fixture/TransactionFiltersStateFixture.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/fixture/TransactionFiltersStateFixture.kt index fc5d3ff37..e40adb81e 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/fixture/TransactionFiltersStateFixture.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/fixture/TransactionFiltersStateFixture.kt @@ -55,14 +55,12 @@ object TransactionFiltersStateFixture { fun new( onBack: () -> Unit = {}, - onBottomSheetHidden: () -> Unit = {}, filters: List = FILTERS, primaryButtonState: ButtonState = PRIMARY_BUTTON_STATE, secondaryButtonState: ButtonState = SECONDARY_BUTTON_STATE ) = TransactionFiltersState( filters = filters, onBack = onBack, - onBottomSheetHidden = onBottomSheetHidden, primaryButton = primaryButtonState, secondaryButton = secondaryButtonState ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/model/TransactionFiltersState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/model/TransactionFiltersState.kt index 693a5cc09..87bf5ac4b 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/model/TransactionFiltersState.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/model/TransactionFiltersState.kt @@ -6,7 +6,6 @@ import co.electriccoin.zcash.ui.design.util.StringResource data class TransactionFiltersState( val filters: List, val onBack: () -> Unit, - val onBottomSheetHidden: () -> Unit, val primaryButton: ButtonState, val secondaryButton: ButtonState ) diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/viewmodel/TransactionFiltersViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/viewmodel/TransactionFiltersViewModel.kt index 10a469404..230cb17de 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/viewmodel/TransactionFiltersViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionfilters/viewmodel/TransactionFiltersViewModel.kt @@ -19,26 +19,19 @@ import co.electriccoin.zcash.ui.design.util.stringRes import co.electriccoin.zcash.ui.screen.transactionfilters.model.TransactionFilterState import co.electriccoin.zcash.ui.screen.transactionfilters.model.TransactionFiltersState import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.WhileSubscribed -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch internal class TransactionFiltersViewModel( private val navigationRouter: NavigationRouter, getTransactionFilters: GetTransactionFiltersUseCase, private val applyTransactionFilters: ApplyTransactionFiltersUseCase, ) : ViewModel() { - val hideBottomSheetRequest = MutableSharedFlow() - - private val bottomSheetHiddenResponse = MutableSharedFlow() - private val selectedFilters = MutableStateFlow(getTransactionFilters()) @OptIn(ExperimentalCoroutinesApi::class) @@ -87,7 +80,6 @@ internal class TransactionFiltersViewModel( } }, onBack = ::onBack, - onBottomSheetHidden = ::onBottomSheetHidden, primaryButton = ButtonState( text = stringRes(R.string.transaction_filters_btn_apply), @@ -100,9 +92,9 @@ internal class TransactionFiltersViewModel( ), ) }.stateIn( - viewModelScope, - SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), - null + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), + initialValue = null ) private fun onTransactionFilterClicked(filter: TransactionFilter) { @@ -115,29 +107,9 @@ internal class TransactionFiltersViewModel( } } - private suspend fun hideBottomSheet() { - hideBottomSheetRequest.emit(Unit) - bottomSheetHiddenResponse.first() - } + private fun onBack() = navigationRouter.back() - private fun onBottomSheetHidden() = - viewModelScope.launch { - bottomSheetHiddenResponse.emit(Unit) - } + private fun onApplyTransactionFiltersClick() = applyTransactionFilters(selectedFilters.value) - private fun onBack() = - viewModelScope.launch { - hideBottomSheet() - navigationRouter.back() - } - - private fun onApplyTransactionFiltersClick() = - viewModelScope.launch { - applyTransactionFilters(selectedFilters.value) { hideBottomSheet() } - } - - private fun onResetTransactionFiltersClick() = - viewModelScope.launch { - selectedFilters.update { emptyList() } - } + private fun onResetTransactionFiltersClick() = selectedFilters.update { emptyList() } } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/AndroidTransactionNote.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/AndroidTransactionNote.kt index 0598e9580..9ff5fb430 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/AndroidTransactionNote.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/AndroidTransactionNote.kt @@ -5,6 +5,7 @@ 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 @@ -12,6 +13,7 @@ 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 @@ -26,7 +28,13 @@ fun AndroidTransactionNote(transactionNote: 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 { @@ -52,13 +60,6 @@ fun AndroidTransactionNote(transactionNote: TransactionNote) { } } - LaunchedEffect(Unit) { - viewModel.hideBottomSheetRequest.collect { - sheetState.hide() - state.onBottomSheetHidden() - } - } - BackHandler { state.onBack() } diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/model/TransactionNoteState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/model/TransactionNoteState.kt index 8bae6a07f..2ba1aacba 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/model/TransactionNoteState.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/model/TransactionNoteState.kt @@ -7,7 +7,6 @@ import co.electriccoin.zcash.ui.design.util.StyledStringResource data class TransactionNoteState( val onBack: () -> Unit, - val onBottomSheetHidden: () -> Unit, val title: StringResource, val note: TextFieldState, val noteCharacters: StyledStringResource, diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/view/TransactionNoteView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/view/TransactionNoteView.kt index 486b61101..8e82e7ed2 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/view/TransactionNoteView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/view/TransactionNoteView.kt @@ -137,7 +137,6 @@ private fun Preview() = state = TransactionNoteState( onBack = {}, - onBottomSheetHidden = {}, title = stringRes("Title"), note = TextFieldState(stringRes("")) {}, noteCharacters = diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/viewmodel/TransactionNoteViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/viewmodel/TransactionNoteViewModel.kt index af0d4c886..24f1b305c 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/viewmodel/TransactionNoteViewModel.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/transactionnote/viewmodel/TransactionNoteViewModel.kt @@ -15,13 +15,11 @@ import co.electriccoin.zcash.ui.design.util.StyledStringResource import co.electriccoin.zcash.ui.design.util.stringRes import co.electriccoin.zcash.ui.screen.transactionnote.TransactionNote import co.electriccoin.zcash.ui.screen.transactionnote.model.TransactionNoteState -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.WhileSubscribed import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -33,10 +31,6 @@ internal class TransactionNoteViewModel( private val createOrUpdateTransactionNote: CreateOrUpdateTransactionNoteUseCase, private val deleteTransactionNote: DeleteTransactionNoteUseCase ) : ViewModel() { - val hideBottomSheetRequest = MutableSharedFlow() - - private val bottomSheetHiddenResponse = MutableSharedFlow() - private val noteText = MutableStateFlow("") private val foundNote = MutableStateFlow(null) @@ -54,12 +48,9 @@ internal class TransactionNoteViewModel( foundNote: String? ): TransactionNoteState { val noteTextNormalized = noteText.trim() - val isNoteTextTooLong = noteText.length > MAX_NOTE_LENGTH - return TransactionNoteState( onBack = ::onBack, - onBottomSheetHidden = ::onBottomSheetHidden, title = if (foundNote == null) { stringRes(R.string.transaction_note_add_note_title) @@ -107,37 +98,19 @@ internal class TransactionNoteViewModel( private fun onAddOrUpdateNoteClick() = viewModelScope.launch { - createOrUpdateTransactionNote(txId = transactionNote.txId, note = noteText.value) { - hideBottomSheet() - } + createOrUpdateTransactionNote(txId = transactionNote.txId, note = noteText.value) } private fun onDeleteNoteClick() = viewModelScope.launch { - deleteTransactionNote(transactionNote.txId) { - hideBottomSheet() - } + deleteTransactionNote(transactionNote.txId) } private fun onNoteTextChanged(newValue: String) { noteText.update { newValue } } - private suspend fun hideBottomSheet() { - hideBottomSheetRequest.emit(Unit) - bottomSheetHiddenResponse.first() - } - - private fun onBottomSheetHidden() = - viewModelScope.launch { - bottomSheetHiddenResponse.emit(Unit) - } - - private fun onBack() = - viewModelScope.launch { - hideBottomSheet() - navigationRouter.back() - } + private fun onBack() = navigationRouter.back() } private const val MAX_NOTE_LENGTH = 90