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

fix: refine the state control in account seed (#662)

* refine the state control in account seed

* no suggestion on selection

* fix e2e test
parent 5b5c5c78
Pipeline #102152 failed with stages
in 4 minutes and 38 seconds
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, ReactElement } from 'react'; import React, { ReactElement, useState } from 'react';
import { import {
NativeSyntheticEvent, NativeSyntheticEvent,
StyleSheet, StyleSheet,
...@@ -41,34 +41,28 @@ const SUGGESTIONS_COUNT = 5; ...@@ -41,34 +41,28 @@ const SUGGESTIONS_COUNT = 5;
interface Props extends TextInputProps { interface Props extends TextInputProps {
onChangeText: (text: string) => void; onChangeText: (text: string) => void;
valid: boolean; valid: boolean;
value: string;
} }
export default class AccountSeed extends Component< export default function AccountSeed({
Props, valid,
{ onChangeText,
cursorPosition: number; ...props
} }: Props): React.ReactElement {
> { const [cursorPosition, setCursorPosition] = useState({
state = { end: 0,
cursorPosition: 0 start: 0
}; });
const [value, setValue] = useState('');
handleCursorPosition = ( function handleCursorPosition(
event: NativeSyntheticEvent<TextInputSelectionChangeEventData> event: NativeSyntheticEvent<TextInputSelectionChangeEventData>
): void => { ): void {
const { start, end } = event.nativeEvent.selection; setCursorPosition(event.nativeEvent.selection);
}
if (start !== end) {
return;
}
this.setState({ cursorPosition: start });
};
/** /**
* Generate a list of suggestions for input * Generate a list of suggestions for input
*/ */
generateSuggestions(input: string, wordList: string[]): string[] { function generateSuggestions(input: string, wordList: string[]): string[] {
const fromIndex = binarySearch(wordList, input).index; // index to start search from const fromIndex = binarySearch(wordList, input).index; // index to start search from
let suggestions = wordList.slice(fromIndex, fromIndex + SUGGESTIONS_COUNT); let suggestions = wordList.slice(fromIndex, fromIndex + SUGGESTIONS_COUNT);
...@@ -84,7 +78,7 @@ export default class AccountSeed extends Component< ...@@ -84,7 +78,7 @@ export default class AccountSeed extends Component<
return suggestions; return suggestions;
} }
selectWordList(otherWords: string[]): string[] { function selectWordList(otherWords: string[]): string[] {
for (const word of otherWords) { for (const word of otherWords) {
const isBIP39 = binarySearch(BIP39_WORDS, word).hit; const isBIP39 = binarySearch(BIP39_WORDS, word).hit;
const isParity = binarySearch(PARITY_WORDS, word).hit; const isParity = binarySearch(PARITY_WORDS, word).hit;
...@@ -99,22 +93,33 @@ export default class AccountSeed extends Component< ...@@ -99,22 +93,33 @@ export default class AccountSeed extends Component<
return ALL_WORDS as string[]; return ALL_WORDS as string[];
} }
renderSuggestions(): ReactElement { function onNativeChangeText(text: string): void {
const { value } = this.props; setValue(text);
const { cursorPosition } = this.state; onChangeText(text);
}
let left = value.substring(0, cursorPosition).split(' ');
let right = value.substring(cursorPosition).split(' ');
function renderSuggestions(): ReactElement {
const { start, end } = cursorPosition;
if (start !== end) return <View style={styles.suggestions} />;
const currentPosition = end;
let left = value.substring(0, currentPosition).split(' ');
let right = value.substring(currentPosition).split(' ');
const isLeftSpace =
currentPosition === 0 || value[currentPosition - 1] === '';
const isRightSpace =
currentPosition === value.length - 1 || value[currentPosition + 1] === '';
const leftInput = isLeftSpace ? '' : left[left.length - 1];
const rightInput = isRightSpace ? '' : right[0];
// combine last nibble before cursor and first nibble after cursor into a word // combine last nibble before cursor and first nibble after cursor into a word
const input = left[left.length - 1] + right[0]; const input = leftInput + rightInput;
left = left.slice(0, -1); left = left.slice(0, -1);
right = right.slice(1); right = right.slice(1);
// find a wordList using words around as discriminator // find a wordList using words around as discriminator
const wordList = this.selectWordList(left.concat(right)); const wordList = selectWordList(left.concat(right));
const suggestions = this.generateSuggestions(input.toLowerCase(), wordList); const suggestions = generateSuggestions(input.toLowerCase(), wordList);
return ( return (
<View style={styles.suggestions}> <View style={styles.suggestions}>
...@@ -130,7 +135,7 @@ export default class AccountSeed extends Component< ...@@ -130,7 +135,7 @@ export default class AccountSeed extends Component<
let phrase = left.concat(suggestion, right).join(' ').trimEnd(); let phrase = left.concat(suggestion, right).join(' ').trimEnd();
const is24words = phrase.split(' ').length === 24; const is24words = phrase.split(' ').length === 24;
if (!is24words) phrase += ' '; if (!is24words) phrase += ' ';
this.props.onChangeText(phrase); onNativeChangeText(phrase);
}} }}
> >
<View key={suggestion} style={[styles.suggestion, sepStyle]}> <View key={suggestion} style={[styles.suggestion, sepStyle]}>
...@@ -143,31 +148,31 @@ export default class AccountSeed extends Component< ...@@ -143,31 +148,31 @@ export default class AccountSeed extends Component<
); );
} }
render(): ReactElement { const invalidStyles = !valid ? styles.invalidInput : {};
const { valid, value } = this.props; return (
const invalidStyles = !valid ? styles.invalidInput : {}; <View>
return ( <TextInput
<View> style={StyleSheet.flatten([
<TextInput fontStyles.t_seed,
style={StyleSheet.flatten([ styles.input,
fontStyles.t_seed, invalidStyles
styles.input, ])}
invalidStyles multiline
])} autoCorrect={false}
multiline autoCompleteType="off"
autoCorrect={false} autoCapitalize="none"
autoCompleteType="off" returnKeyType="done"
autoCapitalize="none" blurOnSubmit={true}
returnKeyType="done" textAlignVertical="top"
blurOnSubmit={true} onSelectionChange={handleCursorPosition}
textAlignVertical="top" selection={cursorPosition}
onSelectionChange={this.handleCursorPosition} value={value}
{...this.props} onChangeText={onNativeChangeText}
/> {...props}
{value.length > 0 && this.renderSuggestions()} />
</View> {value.length > 0 && renderSuggestions()}
); </View>
} );
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
......
...@@ -125,7 +125,6 @@ function IdentityNew({ ...@@ -125,7 +125,6 @@ function IdentityNew({
onSubmitEditing={onRecoverConfirm} onSubmitEditing={onRecoverConfirm}
returnKeyType="done" returnKeyType="done"
valid={isSeedValid.valid} valid={isSeedValid.valid}
value={seedPhrase}
/> />
<View style={styles.btnBox}> <View style={styles.btnBox}>
<Button <Button
......
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