OSDN Git Service

d2eb5ca9e983888d42cca5c0a8525ab18d739071
[bytom/bytom-electron.git] / src / features / shared / components / ConfirmMnemonic / ConfirmMnemonic.jsx
1 import React from 'react'
2 import { ErrorBanner, SingletonField} from 'features/shared/components'
3 import {reduxForm} from 'redux-form'
4 import style from './ConfirmMnemonic.scss'
5 import {withNamespaces} from 'react-i18next'
6
7 class ConfirmMnemonic extends React.Component {
8   constructor(props) {
9     super(props)
10     this.state = this.getInitialState()
11
12     this.submitWithValidation = this.submitWithValidation.bind(this)
13   }
14
15   getInitialState() {
16     let seedWords = []
17     let randomThreshold = 0.3
18     let splitMnemonic = this.props.mnemonic.split(' ')
19     for (let i = 0; i < splitMnemonic.length; i++) {
20       let hideWord = Math.random()
21       seedWords.push({
22         word: hideWord > randomThreshold ? splitMnemonic[i] : '',
23         show: hideWord > randomThreshold,
24         index: i,
25       })
26       if(hideWord<= randomThreshold){
27         this.props.fields.words.addField({
28           seedIndex: i
29         })
30       }
31     }
32     return {
33       seedWords: seedWords,
34       splitMnemoic: splitMnemonic,
35     }
36   }
37
38   submitWithValidation(data) {
39     for(let word of data.words){
40       if(word.value.trim() !== this.state.splitMnemoic[word.seedIndex]){
41         return new Promise((_, reject) => reject({
42           _error: 'please match the word'
43         }))
44       }
45     }
46
47     return new Promise((resolve, reject) => {
48       this.props.succeeded()
49         .catch((err) => reject({type: err}))
50     })
51   }
52
53   render() {
54     const {
55       fields: {words},
56       error,
57       handleSubmit,
58       submitting,
59       t
60     } = this.props
61
62     const { seedWords } = this.state
63     let counter = 0
64
65     return (
66       <form  onSubmit={handleSubmit(this.submitWithValidation)}>
67         <h4>{t('mnemonic.confirmTitle')}</h4>
68         <p>{t('mnemonic.confirmMessage')}</p>
69         <div className={style.seedArea}>
70           {seedWords.map((seedWord) => {
71             return ( seedWord.show ?
72               <div key={seedWord.index} className={`${style.seed} ${style.seedWord}`}>{seedWord.word}</div> :
73               (words[counter]? <SingletonField
74                 className={style.seedWord}
75                 key={seedWord.index}
76                 fieldProps={ words[counter++].value }
77               /> : null)
78             )
79           })}
80         </div>
81
82         {error&& <ErrorBanner error={error} />}
83
84         <button
85           className={`btn btn-primary ${style.submit}`}
86           type='submit'
87           disabled={submitting}>
88           {t('mnemonic.confirm')}
89         </button>
90
91       </form>
92     )
93   }
94 }
95
96 const validate = (values, props) => {
97   const errors = {words: {}}
98   const splitMnemonic = props.mnemonic.split(' ')
99
100   // Actions
101   let numError
102   values.words.forEach((word, index) => {
103     const seedIndex = values.words[index].seedIndex
104     numError = values.words[index].value !== splitMnemonic[seedIndex]
105     if (numError) {
106       errors.words[index] = {...errors.words[index], value:' '}
107     }
108   })
109   return errors
110 }
111
112 export default  withNamespaces('translations') (reduxForm({
113   form: 'MnemonicInit',
114   fields: [
115     'words[].value',
116     'words[].seedIndex'
117   ],
118   validate
119 })(ConfirmMnemonic))