From 741601b65f87936b163fcf477f61b53924c2931b Mon Sep 17 00:00:00 2001 From: Milan Date: Fri, 19 Jul 2024 12:00:50 +0200 Subject: [PATCH] [#1467] Activity resizing according to soft keyboard (#1506) * [#1467] Activity resizing according to soft keyboard Closes #1467 * [#1467] Seed keyboard handling * [#1467] Seed keyboard handling Closes #1467 * [#1467] Documentation update * TODO reference * [#1467] Documentation update Closes #1467 * [#1467] Detekt fix Closes #1467 --------- Co-authored-by: Honza --- CHANGELOG.md | 4 ++ docs/whatsNew/WHATS_NEW_EN.md | 3 ++ ui-lib/src/main/AndroidManifest.xml | 3 +- .../co/electriccoin/zcash/ui/MainActivity.kt | 2 + .../ui/screen/restore/view/RestoreView.kt | 45 ++++++++++--------- 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ab9fcdf..5d00607a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this application adheres to [Semantic Versioning](https://semver.org/spec/v2 - The Restore Success dialog has been reworked into a separate screen, allowing users to opt out of the Keep screen on while restoring option +## Fixed +- Support Screen now shows the Send button above keyboard instead of overlaying it. This was achieved by setting + `adjustResize` to `MainActivity` and adding `imePadding` to top level composable + ## [1.1.3 (682)] - 2024-07-03 ### Added diff --git a/docs/whatsNew/WHATS_NEW_EN.md b/docs/whatsNew/WHATS_NEW_EN.md index 808dc47a..d45baa6d 100644 --- a/docs/whatsNew/WHATS_NEW_EN.md +++ b/docs/whatsNew/WHATS_NEW_EN.md @@ -16,3 +16,6 @@ directly impact users rather than highlighting other key architectural updates.* - The About screen has been redesigned to align with the new design guidelines - The Restore Success dialog has been reworked into a separate screen, allowing users to opt out of the Keep screen on while restoring option + +### Fixed +- Support Screen now shows the Send button above keyboard instead of overlaying it diff --git a/ui-lib/src/main/AndroidManifest.xml b/ui-lib/src/main/AndroidManifest.xml index fc58c36e..3c6805be 100644 --- a/ui-lib/src/main/AndroidManifest.xml +++ b/ui-lib/src/main/AndroidManifest.xml @@ -15,9 +15,10 @@ - \ No newline at end of file + 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 4304e242..3c7e0d1b 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 @@ -11,6 +11,7 @@ import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect @@ -133,6 +134,7 @@ class MainActivity : AppCompatActivity() { Modifier .fillMaxWidth() .fillMaxHeight() + .imePadding() ) { BindCompLocalProvider { MainContent() diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt index 81515bc5..4eb0224a 100644 --- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/restore/view/RestoreView.kt @@ -30,14 +30,11 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldDefaults 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.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -47,7 +44,6 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextRange @@ -84,7 +80,7 @@ import co.electriccoin.zcash.ui.screen.restore.state.WordList import co.electriccoin.zcash.ui.screen.restore.state.wordValidation import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentHashSetOf -import kotlinx.coroutines.launch +import kotlinx.coroutines.delay @Preview @Composable @@ -224,7 +220,6 @@ fun RestoreWallet( paste: () -> String?, onFinished: () -> Unit ) { - val scope = rememberCoroutineScope() var text by rememberSaveable { mutableStateOf("") } val parseResult = ParseResult.new(completeWordList, text) @@ -237,10 +232,16 @@ fun RestoreWallet( } // To avoid unnecessary recompositions that this flow produces - SideEffect { - scope.launch { - userWordList.wordValidation().collect { - isSeedValid = it is SeedPhraseValidation.Valid + LaunchedEffect(Unit) { + userWordList.wordValidation().collect { + if (it is SeedPhraseValidation.Valid) { + // TODO [#1522]: temporary fix to wait for other states to update first + // TODO [#1522]: https://github.com/Electric-Coin-Company/zashi-android/issues/1522 + @Suppress("MagicNumber") + delay(100) + isSeedValid = true + } else { + isSeedValid = false } } } @@ -258,6 +259,7 @@ fun RestoreWallet( } ) } + RestoreStage.Birthday -> { RestoreSeedBirthdayTopAppBar( onBack = { @@ -287,6 +289,7 @@ fun RestoreWallet( .fillMaxWidth() ) } + RestoreStage.Birthday -> { // No content. The action button is part of scrollable content. } @@ -318,6 +321,7 @@ fun RestoreWallet( modifier = commonModifier ) } + RestoreStage.Birthday -> { RestoreBirthdayMainContent( zcashNetwork = zcashNetwork, @@ -400,7 +404,7 @@ private fun RestoreSeedMainContent( goNext: () -> Unit, modifier: Modifier = Modifier, ) { - val scope = rememberCoroutineScope() + val focusManager = LocalFocusManager.current val scrollState = rememberScrollState() val focusRequester = remember { FocusRequester() } val textFieldScrollToHeight = rememberSaveable { mutableIntStateOf(0) } @@ -468,24 +472,21 @@ private fun RestoreSeedMainContent( Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingHuge)) } - if (isSeedValid) { - // Clear focus and hide keyboard to make it easier for users to see the next button - LocalSoftwareKeyboardController.current?.hide() - LocalFocusManager.current.clearFocus() + LaunchedEffect(isSeedValid) { + if (isSeedValid) { + // Clear focus and hide keyboard to make it easier for users to see the next button + focusManager.clearFocus() + } } - DisposableEffect(parseResult) { + LaunchedEffect(parseResult) { // Causes the TextFiled to refocus if (!isSeedValid) { focusRequester.requestFocus() } - // Causes scroll to the TextField after the first type action if (text.isNotEmpty() && userWordList.current.value.isEmpty()) { - scope.launch { - scrollState.animateScrollTo(textFieldScrollToHeight.intValue) - } + scrollState.animateScrollTo(textFieldScrollToHeight.intValue) } - onDispose { /* Nothing to dispose */ } } } @@ -674,9 +675,11 @@ private fun Autocomplete( is ParseResult.Autocomplete -> { Pair(false, parseResult.suggestions) } + is ParseResult.Warn -> { return } + else -> { Pair(false, null) }