Unverified Commit fe2841aa authored by Hanwen Cheng's avatar Hanwen Cheng Committed by GitHub
Browse files

Fix keyboard aware scroll view related problem (#291)

* fix: scrollview drag problem

* fix: persistant scroll on each click

* fix: align seed input to top on Android

* fix: code prettier

* fix: according to the PR suggestion
parent e5a9e298
Pipeline #45144 failed with stage
in 14 seconds
......@@ -26,7 +26,7 @@
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
......
......@@ -132,6 +132,7 @@ export default class AccountSeed extends Component {
style={[styles.input, invalidStyles]}
multiline
autoCapitalize="none"
textAlignVertical="top"
onSelectionChange={this.handleCursorPosition}
{...this.props}
/>
......
import React from 'react';
import { Keyboard, Platform } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
class KeyboardScrollView extends React.Component {
render() {
const defaultProps = { enableAutomaticScroll: true };
return Platform.select({
ios: (
<KeyboardAwareScrollView
keyboardDismissMode="interactive"
keyboardShouldPersistTaps="handled"
{...defaultProps}
{...this.props}
/>
),
android: (
<KeyboardAwareScrollView
keyboardDismissMode="on-drag"
onScrollEndDrag={Keyboard.dismiss}
keyboardShouldPersistTaps="handled"
enableOnAndroid
{...defaultProps}
{...this.props}
/>
)
});
}
}
export default KeyboardScrollView;
......@@ -17,8 +17,7 @@
'use strict';
import React from 'react';
import { StyleSheet, ScrollView, Text, View } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
import { StyleSheet, Text, View } from 'react-native';
import { Subscribe } from 'unstated';
import colors from '../colors';
......@@ -26,11 +25,11 @@ import AccountIconChooser from '../components/AccountIconChooser';
import Background from '../components/Background';
import Button from '../components/Button';
import TextInput from '../components/TextInput';
import TouchableItem from '../components/TouchableItem';
import { NETWORK_LIST } from '../constants';
import AccountsStore from '../stores/AccountsStore';
import { validateSeed } from '../util/account';
import NetworkButton from '../components/NetworkButton';
import KeyboardScrollView from '../components/KeyboardScrollView';
export default class AccountNew extends React.Component {
static navigationOptions = {
......@@ -48,7 +47,7 @@ export default class AccountNew extends React.Component {
class AccountNewView extends React.Component {
render() {
const { accounts } = this.props;
const { accounts, navigation } = this.props;
const selected = accounts.getNew();
const network = NETWORK_LIST[selected.networkKey];
if (!selected) {
......@@ -56,54 +55,49 @@ class AccountNewView extends React.Component {
}
return (
<View style={styles.body}>
<KeyboardAwareScrollView>
<KeyboardScrollView style={{ padding: 20 }}>
<Background />
<ScrollView
style={{ padding: 20 }}
keyboardDismissMode="on-drag"
keyboardShouldPersistTaps="always"
containerStyle={styles.bodyContainer}
>
<View style={styles.top}>
<Text style={styles.titleTop}>CREATE ACCOUNT</Text>
<Text style={styles.title}>CHOOSE NETWORK</Text>
<NetworkButton network={network}/>
<Text style={[styles.title, { marginTop: 20 }]}>
CHOOSE AN IDENTICON
</Text>
<AccountIconChooser
value={selected && selected.seed && selected.address}
onSelect={({ address, bip39, seed }) => {
accounts.updateNew({ address, seed, validBip39Seed: bip39 });
}}
/>
<Text style={styles.title}>ACCOUNT NAME</Text>
<TextInput
onChangeText={name => accounts.updateNew({ name })}
value={selected && selected.name}
placeholder="Enter a new account name"
/>
</View>
<View style={styles.bottom}>
<Text style={styles.hintText}>
On the next step you will be asked to backup your account, get pen
and paper ready
</Text>
<Button
buttonStyles={styles.nextStep}
title="Next Step"
disabled={ !validateSeed(selected.seed, selected.validBip39Seed).valid }
onPress={() => {
validateSeed(selected.seed, selected.validBip39Seed).valid &&
this.props.navigation.navigate('AccountBackup', {
isNew: true,
isWelcome: this.props.navigation.getParam('isWelcome')
});
}}
/>
</View>
</ScrollView>
</KeyboardAwareScrollView>
<View style={styles.top}>
<Text style={styles.titleTop}>CREATE ACCOUNT</Text>
<Text style={styles.title}>CHOOSE NETWORK</Text>
<NetworkButton network={network} />
<Text style={[styles.title, { marginTop: 20 }]}>
CHOOSE AN IDENTICON
</Text>
<AccountIconChooser
value={selected && selected.seed && selected.address}
onSelect={({ address, bip39, seed }) => {
accounts.updateNew({ address, seed, validBip39Seed: bip39 });
}}
/>
<Text style={styles.title}>ACCOUNT NAME</Text>
<TextInput
onChangeText={name => accounts.updateNew({ name })}
value={selected && selected.name}
placeholder="Enter a new account name"
/>
</View>
<View style={styles.bottom}>
<Text style={styles.hintText}>
On the next step you will be asked to backup your account, get pen
and paper ready
</Text>
<Button
buttonStyles={styles.nextStep}
title="Next Step"
disabled={
!validateSeed(selected.seed, selected.validBip39Seed).valid
}
onPress={() => {
validateSeed(selected.seed, selected.validBip39Seed).valid &&
navigation.navigate('AccountBackup', {
isNew: true,
isWelcome: navigation.getParam('isWelcome')
});
}}
/>
</View>
</KeyboardScrollView>
</View>
);
}
......
......@@ -17,8 +17,13 @@
'use strict';
import React from 'react';
import { Alert, SafeAreaView, ScrollView, StyleSheet, Text } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
import {
Alert,
findNodeHandle,
SafeAreaView,
StyleSheet,
Text
} from 'react-native';
import { Subscribe } from 'unstated';
import colors from '../colors';
......@@ -26,12 +31,13 @@ import AccountCard from '../components/AccountCard';
import AccountSeed from '../components/AccountSeed';
import Background from '../components/Background';
import Button from '../components/Button';
import KeyboardScrollView from '../components/KeyboardScrollView';
import NetworkButton from '../components/NetworkButton';
import TextInput from '../components/TextInput';
import { NETWORK_LIST } from '../constants';
import AccountsStore from '../stores/AccountsStore';
import { validateSeed } from '../util/account';
import { debounce } from '../util/debounce'
import { debounce } from '../util/debounce';
import { brainWalletAddress } from '../util/native';
export default class AccountRecover extends React.Component {
......@@ -53,124 +59,121 @@ class AccountRecoverView extends React.Component {
constructor(...args) {
super(...args);
this.state = { seed: ''}
this.state = { seed: '' };
}
addressGeneration = (seed) => {
addressGeneration = seed => {
const { accounts } = this.props;
brainWalletAddress(seed)
.then(({ address, bip39 }) => accounts.updateNew({address, seed, validBip39Seed: bip39}))
.catch(console.error);
}
.then(({ address, bip39 }) =>
accounts.updateNew({ address, seed, validBip39Seed: bip39 })
)
.catch(console.error);
};
debouncedAddressGeneration = debounce(this.addressGeneration, 200)
componentWillUnmount = function () {
debouncedAddressGeneration = debounce(this.addressGeneration, 200);
componentWillUnmount = function() {
// called when the user goes back, or finishes the whole recovery process
this.props.accounts.updateNew({seed : ''});
}
this.props.accounts.updateNew({ seed: '' });
};
render() {
const { accounts } = this.props;
const { accounts, navigation } = this.props;
const selected = accounts.getNew();
const networkKey = selected.networkKey;
const network = NETWORK_LIST[networkKey];
return (
<SafeAreaView style={styles.safeAreaView}>
<KeyboardAwareScrollView style={styles.bodyContainer}>
<KeyboardScrollView
style={styles.bodyContainer}
innerRef={ref => {
this.scroll = ref;
}}
extraHeight={200}
contentContainerStyle={{ justifyContent: 'flex-end' }}
>
<Background />
<ScrollView
contentContainerStyle={{ justifyContent: 'flex-end' }}
style={{ flex: 1 }}
enableOnAndroid
scrollEnabled
keyboardShouldPersistTaps="always"
extraHeight={230}
innerRef={ref => {
this.scroll = ref;
<Text style={styles.titleTop}>RECOVER ACCOUNT</Text>
<Text style={styles.title}>CHOOSE NETWORK</Text>
<NetworkButton network={network} />
<Text style={styles.title}>ACCOUNT NAME</Text>
<TextInput
onChangeText={name => accounts.updateNew({ name })}
value={selected && selected.name}
placeholder="Enter an account name"
/>
<Text style={[styles.title, { marginTop: 20 }]}>
ENTER RECOVERY WORDS
</Text>
<AccountSeed
onFocus={event => {
this.scroll.props.scrollToFocusedInput(
findNodeHandle(event.target)
);
}}
ref={this._seed}
valid={validateSeed(selected.seed, selected.validBip39Seed).valid}
onChangeText={seed => {
this.debouncedAddressGeneration(seed);
this.setState({ seed });
}}
>
<Text style={styles.titleTop}>RECOVER ACCOUNT</Text>
<Text style={styles.title}>CHOOSE NETWORK</Text>
<NetworkButton network={network}/>
<Text style={styles.title}>ACCOUNT NAME</Text>
<TextInput
onChangeText={name => accounts.updateNew({ name })}
value={selected && selected.name}
placeholder="Enter an account name"
/>
<Text style={[styles.title, { marginTop: 20 }]}>
ENTER RECOVERY WORDS
</Text>
<AccountSeed
valid={validateSeed(selected.seed, selected.validBip39Seed).valid}
onChangeText={seed => {
this.debouncedAddressGeneration(seed);
this.setState({seed});
}}
value={this.state.seed}
/>
<AccountCard
style={{ marginTop: 20 }}
address={selected.address || ''}
networkKey={selected.networkKey || ''}
title={selected.name}
seedType={selected.validBip39Seed ? 'bip39' : 'brain wallet'}
/>
<Button
buttonStyles={{ marginBottom: 40 }}
title="Next Step"
onPress={() => {
const validation = validateSeed(selected.seed, selected.validBip39Seed);
if (!validation.valid) {
if (validation.accountRecoveryAllowed){
return Alert.alert(
'Warning:',
`${validation.reason}`,
[
{
text: 'I understand the risks',
style: 'default',
onPress: () => {
this.props.navigation.navigate('AccountPin', {
isWelcome: this.props.navigation.getParam(
'isWelcome'
),
isNew: true
});
}
},
{
text: 'Back',
style: 'cancel'
}
]
);
} else {
return Alert.alert(
'Error:',
`${validation.reason}`,
[
{
text: 'Back',
style: 'cancel'
}
]
);
}
value={this.state.seed}
/>
<AccountCard
style={{ marginTop: 20 }}
address={selected.address || ''}
networkKey={selected.networkKey || ''}
title={selected.name}
seedType={selected.validBip39Seed ? 'bip39' : 'brain wallet'}
/>
<Button
buttonStyles={{ marginBottom: 40 }}
title="Next Step"
onPress={() => {
const validation = validateSeed(
selected.seed,
selected.validBip39Seed
);
if (!validation.valid) {
if (validation.accountRecoveryAllowed) {
return Alert.alert('Warning:', `${validation.reason}`, [
{
text: 'I understand the risks',
style: 'default',
onPress: () => {
navigation.navigate('AccountPin', {
isWelcome: navigation.getParam(
'isWelcome'
),
isNew: true
});
}
},
{
text: 'Back',
style: 'cancel'
}
]);
} else {
return Alert.alert('Error:', `${validation.reason}`, [
{
text: 'Back',
style: 'cancel'
}
]);
}
this.props.navigation.navigate('AccountPin', {
isWelcome: this.props.navigation.getParam('isWelcome'),
isNew: true
});
}}
/>
</ScrollView>
</KeyboardAwareScrollView>
}
navigation.navigate('AccountPin', {
isWelcome: navigation.getParam('isWelcome'),
isNew: true
});
}}
/>
</KeyboardScrollView>
</SafeAreaView>
);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment