-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: refactor see 24 words screen (#162)
* fix: refactor see 24 words screen * fix: remove typo * fix: update navation name * fix: changes styles to make it on ios * fix: changes styles to make it on ios * fix: refactor word into component * fix: change styles * fix: change styles * fix: change colors * UI/UX for repeting 24 words (#163) * fix: confirm seed phrase * fix: shuffle words * fix: lint code * fix: change badge styles for IOS * fix: change styles * fix: change colors * Update src/ux/createKeys/new/ConfirmNewMasterKeyScreen.tsx Co-authored-by: Ilan <36084092+ilanolkies@users.noreply.github.com> Co-authored-by: Ilan <36084092+ilanolkies@users.noreply.github.com>
- Loading branch information
1 parent
ad4c798
commit bc4177c
Showing
4 changed files
with
288 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,152 @@ | ||
import React, { useState } from 'react' | ||
import { StyleSheet, View, ScrollView, TextInput } from 'react-native' | ||
import { Button, Header2, Paragraph } from '../../../components' | ||
import { | ||
StyleSheet, | ||
View, | ||
ScrollView, | ||
Text, | ||
TouchableOpacity, | ||
} from 'react-native' | ||
import { CreateKeysProps, ScreenProps } from '../types' | ||
import { useTranslation, Trans } from 'react-i18next' | ||
import { useTranslation } from 'react-i18next' | ||
import { grid } from '../../../styles/grid' | ||
import { SquareButton } from '../../../components/button/SquareButton' | ||
import { Arrow } from '../../../components/icons' | ||
import { getTokenColor } from '../../../screens/home/tokenColor' | ||
import { WordInput } from './WordInput' | ||
import { colors } from '../../../styles/colors' | ||
|
||
interface ConfirmMasterKeyScreenProps { | ||
createFirstWallet: CreateKeysProps['createFirstWallet'] | ||
} | ||
// source: https://stackoverflow.com/questions/63813211/qualtrics-and-javascript-randomly-insert-words-into-sentences | ||
const shuffle = (array: string[]) => { | ||
let currentIndex = array.length, | ||
randomIndex | ||
|
||
// While there remain elements to shuffle... | ||
while (currentIndex !== 0) { | ||
// Pick a remaining element... | ||
randomIndex = Math.floor(Math.random() * currentIndex) | ||
currentIndex-- | ||
|
||
// And swap it with the current element. | ||
;[array[currentIndex], array[randomIndex]] = [ | ||
array[randomIndex], | ||
array[currentIndex], | ||
] | ||
} | ||
|
||
return array | ||
} | ||
|
||
export const ConfirmNewMasterKeyScreen: React.FC< | ||
ScreenProps<'ConfirmNewMasterKey'> & ConfirmMasterKeyScreenProps | ||
> = ({ route, navigation, createFirstWallet }) => { | ||
const mnemonic = route.params.mnemonic | ||
const [selectedWords, setSelectedWords] = useState<string[]>([]) | ||
const [words, setWords] = useState<string[]>(shuffle(mnemonic.split(' '))) | ||
|
||
//TODO: create "three column grid" component | ||
const rows = [1, 2, 3, 4, 5, 6, 7, 8] | ||
|
||
const [mnemonicToConfirm, setMnemonicToConfirm] = useState< | ||
string | undefined | ||
>() | ||
const { t } = useTranslation() | ||
|
||
const [error, setError] = useState<string | null>(null) | ||
|
||
const selectWord = (selectedWord: string) => { | ||
setError(null) | ||
const updatedWords = [...selectedWords, selectedWord] | ||
setSelectedWords(updatedWords) | ||
setWords(words.filter(word => !updatedWords.find(w => w === word))) | ||
} | ||
const saveAndNavigate = async () => { | ||
const rifWallet = await createFirstWallet(mnemonic) | ||
// @ts-ignore | ||
navigation.navigate('KeysCreated', { address: rifWallet.address }) | ||
} | ||
|
||
const handleConfirmMnemonic = async () => { | ||
const isValid = mnemonic === mnemonicToConfirm | ||
const isValid = mnemonic === selectedWords.join(' ') | ||
|
||
if (!isValid) { | ||
setError(t('entered words does not match you your master key')) | ||
setError(t('Entered words does not match you your master key')) | ||
return | ||
} | ||
|
||
await saveAndNavigate() | ||
} | ||
|
||
return ( | ||
<ScrollView> | ||
<View style={styles.sectionCentered}> | ||
<Paragraph> | ||
<Trans> | ||
With your master key (seed phrase) you are able to create as many | ||
wallets as you need. | ||
</Trans> | ||
</Paragraph> | ||
</View> | ||
<View style={styles.sectionCentered}> | ||
<Paragraph>validate your master key</Paragraph> | ||
</View> | ||
<View style={styles.section}> | ||
<Header2>Master key</Header2> | ||
<TextInput | ||
onChangeText={text => setMnemonicToConfirm(text)} | ||
value={mnemonicToConfirm} | ||
placeholder={t('Enter your 12 words master key')} | ||
multiline | ||
style={styles.input} | ||
testID="Input.Confirm" | ||
/> | ||
{error && <Paragraph>{error}</Paragraph>} | ||
</View> | ||
<View style={styles.section}> | ||
<Button onPress={saveAndNavigate} title={'Skip'} /> | ||
</View> | ||
<View style={styles.section}> | ||
<Button | ||
onPress={handleConfirmMnemonic} | ||
title={'Confirm'} | ||
testID="Button.Confirm" | ||
/> | ||
<ScrollView style={styles.parent}> | ||
<Text style={styles.header}>Confirm your master key</Text> | ||
|
||
{rows.map(row => ( | ||
<View style={grid.row}> | ||
<WordInput wordNumber={row} initValue={selectedWords[row - 1]} /> | ||
<WordInput | ||
wordNumber={row + rows.length} | ||
initValue={selectedWords[row + rows.length - 1]} | ||
/> | ||
<WordInput | ||
wordNumber={row + rows.length * 2} | ||
initValue={selectedWords[row + rows.length * 2 - 1]} | ||
/> | ||
<Text>{row + rows.length}</Text> | ||
</View> | ||
))} | ||
<View style={styles.badgeArea}> | ||
{words.map(word => ( | ||
<View key={word} style={styles.badgeContainer}> | ||
<TouchableOpacity | ||
style={styles.badgeText} | ||
onPress={() => selectWord(word)}> | ||
<Text>{word}</Text> | ||
</TouchableOpacity> | ||
</View> | ||
))} | ||
</View> | ||
{error && <Text style={styles.defaultText}>{error}</Text>} | ||
|
||
<SquareButton | ||
// @ts-ignore | ||
onPress={handleConfirmMnemonic} | ||
title="" | ||
testID="Address.CopyButton" | ||
icon={<Arrow color={getTokenColor('RBTC')} rotate={90} />} | ||
/> | ||
</ScrollView> | ||
) | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
section: { | ||
paddingTop: 15, | ||
paddingBottom: 15, | ||
borderBottomWidth: 1, | ||
borderBottomColor: '#CCCCCC', | ||
defaultText: { | ||
color: colors.white, | ||
}, | ||
parent: { | ||
backgroundColor: colors.darkBlue, | ||
}, | ||
sectionCentered: { | ||
paddingTop: 15, | ||
paddingBottom: 15, | ||
borderBottomWidth: 1, | ||
borderBottomColor: '#CCCCCC', | ||
alignItems: 'center', | ||
|
||
badgeArea: { | ||
flexDirection: 'row', | ||
flex: 1, | ||
flexWrap: 'wrap', | ||
}, | ||
badgeContainer: { | ||
padding: 1, | ||
|
||
marginVertical: 1, | ||
}, | ||
input: { | ||
height: 80, | ||
margin: 12, | ||
borderWidth: 1, | ||
borderColor: '#000', | ||
padding: 10, | ||
textAlignVertical: 'top', | ||
badgeText: { | ||
backgroundColor: colors.purple, | ||
color: colors.white, | ||
borderRadius: 30, | ||
paddingHorizontal: 10, | ||
paddingVertical: 5, | ||
}, | ||
|
||
header: { | ||
color: colors.white, | ||
fontSize: 22, | ||
paddingVertical: 20, | ||
textAlign: 'center', | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,74 @@ | ||
import React, { useMemo, useState } from 'react' | ||
import React, { useMemo } from 'react' | ||
import { StyleSheet, View, ScrollView, Text } from 'react-native' | ||
import { CopyComponent } from '../../../components' | ||
import { CreateKeysProps, ScreenProps } from '../types' | ||
import { TouchableOpacity } from 'react-native-gesture-handler' | ||
import LinearGradient from 'react-native-linear-gradient' | ||
import { Trans } from 'react-i18next' | ||
import { colors } from '../../../styles/colors' | ||
|
||
import { | ||
getTokenColor, | ||
getTokenColorWithOpacity, | ||
setOpacity, | ||
} from '../../../screens/home/tokenColor' | ||
import { getTokenColor } from '../../../screens/home/tokenColor' | ||
import { SquareButton } from '../../../components/button/SquareButton' | ||
import { Arrow } from '../../../components/icons' | ||
import balances from '../../../screens/home/tempBalances.json' | ||
import { ITokenWithBalance } from '../../../lib/rifWalletServices/RIFWalletServicesTypes' | ||
type CreateMasterKeyScreenProps = { | ||
generateMnemonic: CreateKeysProps['generateMnemonic'] | ||
} | ||
import { grid } from '../../../styles/grid' | ||
import { Word } from './Word' | ||
|
||
export const NewMasterKeyScreen: React.FC< | ||
ScreenProps<'NewMasterKey'> & CreateMasterKeyScreenProps | ||
> = ({ navigation, generateMnemonic }) => { | ||
const mnemonic = useMemo(generateMnemonic, []) | ||
const [selected] = useState<ITokenWithBalance>( | ||
balances[0] as ITokenWithBalance, | ||
) | ||
|
||
const selectedTokenColor = getTokenColor(selected.symbol) | ||
|
||
const containerStyles = { | ||
shadowColor: setOpacity(selectedTokenColor, 0.5), | ||
} | ||
const selectedToken = 'TRBTC' | ||
const words = mnemonic.split(' ') | ||
const rows = [0, 1, 2, 3, 4, 5, 6, 7] | ||
|
||
return ( | ||
<LinearGradient | ||
colors={['#FFFFFF', getTokenColorWithOpacity('TRBTC', 0.1)]} | ||
style={styles.parent}> | ||
<Text style={styles.header}>Master Key</Text> | ||
<LinearGradient | ||
colors={['#FFFFFF', '#E1E1E1']} | ||
style={{ ...styles.topContainer, ...containerStyles }}> | ||
<ScrollView style={styles.portfolio}> | ||
<TouchableOpacity> | ||
<CopyComponent testID={'mnemonic'} value={mnemonic} /> | ||
</TouchableOpacity> | ||
</ScrollView> | ||
</LinearGradient> | ||
<View style={styles.centerRow}> | ||
<SquareButton | ||
// @ts-ignore | ||
onPress={() => navigation.navigate('ImportMasterKey', { mnemonic })} | ||
title="Continue" | ||
testID="Address.CopyButton" | ||
icon={<Arrow color={getTokenColor(selectedToken)} rotate={90} />} | ||
/> | ||
</View> | ||
</LinearGradient> | ||
<ScrollView style={styles.parent}> | ||
<Text style={styles.header}> | ||
<Trans>Write down your master key</Trans> | ||
</Text> | ||
|
||
{rows.map(row => ( | ||
<View style={grid.row} key={row}> | ||
<Word wordNumber={row + 1} text={words[row]} /> | ||
<Word | ||
wordNumber={row + 1 + rows.length} | ||
text={words[row + rows.length]} | ||
/> | ||
<Word | ||
wordNumber={row + 1 + rows.length * 2} | ||
text={words[row + rows.length * 2]} | ||
/> | ||
</View> | ||
))} | ||
{/*TODO:This button will be remove when the navigation is implemented*/} | ||
<SquareButton | ||
// @ts-ignore | ||
onPress={() => navigation.navigate('ConfirmNewMasterKey', { mnemonic })} | ||
title="" | ||
testID="Address.CopyButton" | ||
icon={<Arrow color={getTokenColor('RBTC')} rotate={90} />} | ||
/> | ||
</ScrollView> | ||
) | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
centerRow: { | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
}, | ||
parent: { | ||
height: '100%', | ||
backgroundColor: colors.darkBlue, | ||
}, | ||
header: { | ||
fontSize: 26, | ||
color: colors.white, | ||
fontSize: 22, | ||
paddingVertical: 25, | ||
marginBottom: 5, | ||
textAlign: 'center', | ||
fontWeight: 'bold', | ||
}, | ||
secHeader: { | ||
fontSize: 18, | ||
textAlign: 'center', | ||
}, | ||
|
||
portfolio: { | ||
backgroundColor: '#ffffff', | ||
paddingHorizontal: 25, | ||
borderRadius: 25, | ||
padding: 30, | ||
}, | ||
topContainer: { | ||
marginTop: 60, | ||
marginHorizontal: 25, | ||
borderRadius: 25, | ||
backgroundColor: '#ffffff', | ||
shadowOpacity: 0.1, | ||
// shadowRadius: 10, | ||
elevation: 2, | ||
wordContent: { | ||
borderRadius: 30, | ||
backgroundColor: colors.darkPurple2, | ||
alignItems: 'flex-start', | ||
justifyContent: 'flex-start', | ||
paddingHorizontal: 10, | ||
paddingVertical: 7, | ||
}, | ||
}) |
Oops, something went wrong.