diff --git a/CHANGELOG.md b/CHANGELOG.md
index cfba92d8c57..0a7bd700f26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,6 +28,7 @@
- fixed: Notification center cards no longer shrink their text to fit. Long titles and messages now truncate with an ellipsis so every card renders at the same size.
- fixed: Sort the Privacy Settings Nym Mix Net asset list alphabetically by display name
- fixed: Next button overlapping the wallet list on the Choose Wallets to Add scene
+- fixed: Keyboard no longer covers the Next button on the Import Wallet scene. The scene shrinks to the space above the keyboard, the spacing around the key logo gives up its room first, and the whole seed phrase and the Next button stay visible with no empty space left below the button.
- fixed: Wrap the fiat value in parentheses on the Stake/Unstake/Claim amount row, and remove the space between the fiat symbol and amount to match the network fee tile.
- fixed: Staked "locked" balance in the wallet view no longer gets cut off. The crypto amount is truncated to an exchange-rate-appropriate number of decimals, and the text is no longer clamped to a fraction of the card width.
- fixed: Improve the unstake error experience by replacing the popup alert and generic "unknown error occurred" with the real error in the scene's error field, and showing a clear message when the wallet lacks the balance to cover the unstaking network fee.
diff --git a/maestro/07-wallets/C000029a-migrate-wallets.yaml b/maestro/07-wallets/C000029a-migrate-wallets.yaml
index e166e442070..61038f09b4b 100644
--- a/maestro/07-wallets/C000029a-migrate-wallets.yaml
+++ b/maestro/07-wallets/C000029a-migrate-wallets.yaml
@@ -96,20 +96,13 @@ tags:
- tapOn: Private Key or Private Seed
- inputText: ${IMPORT_SEED}
-# Drop keyboard - Android
+# The Import Wallet scene keeps Next clear of the keyboard, so iOS taps it
+# straight away. Android still drops the keyboard first.
- runFlow:
when:
platform: Android
commands:
- - hideKeyboard
- # - tapOn: Next # odd additional tap required on android sometimes
-# Drop keyboard - iOS
-- runFlow:
- when:
- platform: iOS
- commands:
- - tapOn: "Private Key or Private Seed"
-
+ - hideKeyboard
- tapOn: Next
# Sometimes android requires additional tap
diff --git a/maestro/common/import-wallets.yaml b/maestro/common/import-wallets.yaml
index 0d6025a3f9a..927acc0a848 100644
--- a/maestro/common/import-wallets.yaml
+++ b/maestro/common/import-wallets.yaml
@@ -39,29 +39,15 @@ env:
- tapOn: Private Key or Private Seed
- inputText: ${SEED_PHRASE}
-# Drop keyboard - Android
+# The Import Wallet scene keeps Next clear of the keyboard, so iOS taps it
+# straight away. Android still drops the keyboard first.
- runFlow:
when:
platform: Android
commands:
- - hideKeyboard
- - tapOn: "Enter your.*"
-# Drop keyboard - iOS
-- runFlow:
- when:
- platform: iOS
- commands:
- - tapOn: "Private Key or Private Seed"
-
+ - hideKeyboard
- tapOn: Next
-# # Sometimes android requires additional tap
-# - runFlow:
-# when:
-# visible: Import Wallet
-# commands:
-# - tapOn: Next
-
# Add birthday height for Zcash and Pirate Chain
# Index for targetting the correct "edit" icon
- evalScript: ${var index = 0}
diff --git a/src/__tests__/scenes/__snapshots__/CreateWalletImportScene.test.tsx.snap b/src/__tests__/scenes/__snapshots__/CreateWalletImportScene.test.tsx.snap
index 14e26ace388..06cd67f2cda 100644
--- a/src/__tests__/scenes/__snapshots__/CreateWalletImportScene.test.tsx.snap
+++ b/src/__tests__/scenes/__snapshots__/CreateWalletImportScene.test.tsx.snap
@@ -2,6 +2,42 @@
exports[`CreateWalletImportScene should render with loading props 1`] = `
@@ -364,142 +421,48 @@ exports[`CreateWalletImportScene should render with loading props 1`] = `
Enter your private seed, private key, or active key to verify and restore the associated wallet
-
+
-
+
+ Private Key or Private Seed
+
+
+
- Private Key or Private Seed
-
+ testID="undefined.textInput"
+ textAlignVertical="top"
+ />
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/components/scenes/CreateWalletImportScene.tsx b/src/components/scenes/CreateWalletImportScene.tsx
index 5ee9f302db1..bd0380ecac9 100644
--- a/src/components/scenes/CreateWalletImportScene.tsx
+++ b/src/components/scenes/CreateWalletImportScene.tsx
@@ -1,11 +1,11 @@
import type { JsonObject } from 'edge-core-js'
import * as React from 'react'
-import { Linking, Platform, View } from 'react-native'
-import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
+import { Linking, Platform, ScrollView, View } from 'react-native'
import { sprintf } from 'sprintf-js'
import { PLACEHOLDER_WALLET_ID } from '../../actions/CreateWalletActions'
import ImportKeySvg from '../../assets/images/import-key-icon.svg'
+import { SCROLL_INDICATOR_INSET_FIX } from '../../constants/constantSettings'
import {
type ImportKeyOption,
SPECIAL_CURRENCY_INFO
@@ -44,7 +44,7 @@ interface Props extends EdgeAppSceneProps<'createWalletImport'> {}
const getOptionKey = (pluginId: string, opt: ImportKeyOption): string =>
`${pluginId}${opt.optionName}`
-const CreateWalletImportComponent = (props: Props): React.JSX.Element => {
+const CreateWalletImportComponent: React.FC = props => {
const { navigation, route } = props
const { createWalletList, walletNames, walletSettingValues } = route.params
const theme = useTheme()
@@ -244,7 +244,7 @@ const CreateWalletImportComponent = (props: Props): React.JSX.Element => {
)
return (
-
+
{/* We have to use the SceneHeaderUi4 component here because
the SceneContainer component does not implement the specific flex
@@ -252,7 +252,12 @@ const CreateWalletImportComponent = (props: Props): React.JSX.Element => {
one-off case which has not been codified into our design hierarchy
and made it completely into our abstraction (SceneContainer). */}
-
+
{
{lstrings.create_wallet_import_all_instructions}
-
+ {/* FilledTextInput's multiline containers are flexGrow/flexShrink 1,
+ and a ScrollView lays its content out against the scroll viewport, so
+ the seed box would shrink to whatever room the keyboard leaves instead
+ of showing the whole phrase. This wrapper refuses to shrink, so the
+ field sizes to its text and the scene scrolls instead. */}
+
+
+
{importOptsEntries.length > 0 ? (
{lstrings.create_wallet_import_options_title}
@@ -360,7 +374,7 @@ const CreateWalletImportComponent = (props: Props): React.JSX.Element => {
onPress: handleNext
}}
/>
-
+
)
@@ -368,13 +382,39 @@ const CreateWalletImportComponent = (props: Props): React.JSX.Element => {
const getStyles = cacheStyles((theme: Theme) => ({
container: {
- flexShrink: 1,
+ flex: 1,
margin: theme.rem(0.5)
},
+ scroll: {
+ // Take whatever room the header leaves, and give it back as the keyboard
+ // opens, so the content scrolls instead of running off the scene:
+ flex: 1
+ },
+ scrollContent: {
+ // SceneButtons lays itself out as `flexGrow: 1` + `justifyContent:
+ // 'flex-end'`, which only means anything inside a flex-sized parent. A
+ // scroll content container is content-sized by default, so without this
+ // the button's growth is resolved against the scroll frame instead, and
+ // the content keeps the height it had before the keyboard shrank the
+ // scene: one keyboard's worth of empty scroll below the button. Growing
+ // the content container to the viewport is what makes the scene's
+ // flexible pieces (the logo spacing and the button block) share the
+ // leftover room, and it makes the content height depend on the content
+ // rather than on the keyboard:
+ flexGrow: 1
+ },
icon: {
flexDirection: 'row',
+ alignItems: 'center',
justifyContent: 'center',
- marginVertical: theme.rem(2)
+ // A 1 rem minimum around the logo that opens up when the scene has room
+ // to spare, and closes back to the minimum as the keyboard takes it away:
+ flexGrow: 1,
+ flexShrink: 0,
+ marginVertical: theme.rem(1)
+ },
+ seedInput: {
+ flexShrink: 0
},
optionsHeading: {
fontSize: theme.rem(1),