on master help sign in
feat: refactor top-level views to use new Button and Input components
commitbbf707aca8c056ff3160c00ba05459c84c6c8359 authorMatt Condon (shrugs) <mattgcondon@gmail.com> dateTue 18 Jun 2019, 23:52 (7 years ago) parentf130223
20 files changed+347−260
src/components/Buttons.js+6 src/components/InputSigil.js+49 src/components/Inputs.js+18−6 src/components/old/ReactSVGComponents.js → src/components/ReactSVGComponents.js src/components/Sigil.js+13 src/components/old/Passport.js+1−1 src/components/old/RenderedPoint.js+1−1 src/components/old/ValidatedSigil.js+1−1 src/indigo-react/components/Button.js+26 src/indigo-react/components/Input.js+38−18 src/indigo-react/index.js+1 src/lib/useLifecycle.js+6 src/lib/validators.js+2−2 src/style/indigo-proposals.scss+12 src/views/Landing.js+18−37 src/views/Mnemonic.js+10−10 src/views/Network.js+3−6 src/views/Point.js+1−1 src/views/ViewPoint.js+53−80 src/views/Wallet.js+88−97
src/components/Buttons.jsnew file+6
@@ -0,0 +1,6 @@
1+import React from 'react';
2+import { Button } from 'indigo-react';
3+
4+// TODO: use svg icons
5+export const ForwardButton = props => <Button icon="→" {...props} />;
6+export const DownloadButton = props => <Button icon="⬇" {...props} />;
src/components/InputSigil.jsnew file+49
@@ -0,0 +1,49 @@
1+import React from 'react';
2+import * as ob from 'urbit-ob';
3+
4+import Sigil from './Sigil';
5+
6+const selectColorway = (pass, fail, focused) => {
7+ if (pass) {
8+ return ['#FFFFFF', '#2AA779'];
9+ }
10+
11+ if (focused) {
12+ return ['#FFFFFF', '#4330FC'];
13+ }
14+
15+ if (fail) {
16+ return ['#FFFFFF', '#F8C134'];
17+ }
18+
19+ return ['#FFFFFF', '#7F7F7F'];
20+};
21+
22+export default function ValidatedSigil({
23+ className,
24+ patp,
25+ size,
26+ pass,
27+ error,
28+ focused,
29+ ...rest
30+}) {
31+ const colorway = selectColorway(pass, error, focused);
32+ const valid = ob.isValidPatp(patp);
33+
34+ return (
35+ <div className={className}>
36+ {valid ? (
37+ <Sigil patp={patp} size={size} colorway={colorway} {...rest} />
38+ ) : (
39+ <div
40+ className="bg-transparent"
41+ style={{
42+ width: size,
43+ height: size,
44+ }}
45+ />
46+ )}
47+ </div>
48+ );
49+}
src/components/Inputs.js+18−6
@@ -2,8 +2,13 @@ import React from 'react';
22import { Input } from 'indigo-react';
33import * as bip39 from 'bip39';
44
5−import { validateNotEmpty, validateMnemonic } from 'lib/validators';
65import { DEFAULT_HD_PATH } from 'lib/wallet';
6+import {
7+ validateNotEmpty,
8+ validateMnemonic,
9+ validatePoint,
10+} from 'lib/validators';
11+import { prependSig } from 'lib/transformers';
712
813const kExampleMnemonic = bip39.generateMnemonic();
914
@@ -68,11 +73,18 @@ export function HdPathInput(props) {
6873// transformers: [prependSig],
6974// });
7075
71−// const PointInput = advancedInput({
72−// WrappedComponent: Input,
73−// validators: [validatePoint, validateNotEmpty],
74−// transformers: [prependSig],
75−// });
76+export function PointInput(props) {
77+ return (
78+ <Input
79+ type="text"
80+ placeholder="e.g. ~zod"
81+ validators={[validatePoint, validateNotEmpty]}
82+ transformers={[prependSig]}
83+ mono
84+ {...props}
85+ />
86+ );
87+}
7688
7789// const TicketInput = advancedInput({
7890// WrappedComponent: Input,
src/components/old/ReactSVGComponents.js → src/components/ReactSVGComponents.jsrenamed

The content is the same.

src/components/Sigil.jsnew file+13
@@ -0,0 +1,13 @@
1+import { pour } from 'sigil-js';
2+
3+import ReactSVGComponents from './ReactSVGComponents';
4+
5+export default function Sigil({ patp, size, colorway, ...rest }) {
6+ return pour({
7+ renderer: ReactSVGComponents,
8+ patp,
9+ size,
10+ colorway,
11+ ...rest,
12+ });
13+}
src/components/old/Passport.js+1−1
@@ -1,7 +1,7 @@
11import React from 'react';
22import { pour } from 'sigil-js';
33import * as ob from 'urbit-ob';
4−import ReactSVGComponents from './ReactSVGComponents';
4+import ReactSVGComponents from '../ReactSVGComponents';
55import PropTypes from 'prop-types';
66import PaperCollateralRenderer from 'PaperCollateralRenderer';
77import { Button } from './Base';
src/components/old/RenderedPoint.js+1−1
@@ -6,7 +6,7 @@ import { pour } from 'sigil-js';
66import * as ob from 'urbit-ob';
77
88import { ROUTE_NAMES } from '../../lib/routeNames';
9−import ReactSVGComponents from './ReactSVGComponents';
9+import ReactSVGComponents from '../ReactSVGComponents';
1010
1111const RenderedPoint = props => {
1212 const { setPointCursor, routeHandler, point } = props;
src/components/old/ValidatedSigil.js+1−1
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
33
44import { pour } from 'sigil-js';
55import * as ob from 'urbit-ob';
6−import ReactSVGComponents from './ReactSVGComponents';
6+import ReactSVGComponents from '../ReactSVGComponents';
77
88const isValidPatp = patp => {
99 let isValid = false;
src/indigo-react/components/Button.jsnew file+26
@@ -0,0 +1,26 @@
1+import React from 'react';
2+import cn from 'classnames';
3+
4+export default function Button({
5+ solid = false,
6+ className,
7+ icon,
8+ children,
9+ ...rest
10+}) {
11+ return (
12+ <a
13+ className={cn(
14+ 'pointer pv3 pl4 pr0 truncate flex-row justify-between',
15+ {
16+ 'white bg-black bg-gray6-hover': solid,
17+ 'black bg-gray1-hover': !solid,
18+ },
19+ className
20+ )}
21+ {...rest}>
22+ {children}
23+ <div className="ph4">{icon}</div>
24+ </a>
25+ );
26+}
src/indigo-react/components/Input.js+38−18
@@ -10,10 +10,10 @@ function useInput({
1010 validators = [],
1111 transformers = [],
1212 initialValue = '',
13− autofocus = false,
13+ autoFocus = false,
1414}) {
1515 const [value, setValue] = useState(initialValue);
16− const [focused, setFocused] = useState(autofocus);
16+ const [focused, setFocused] = useState(autoFocus);
1717 const [hasBeenFocused, setHasBeenFocused] = useState(false);
1818
1919 // NB(shrugs)
@@ -92,13 +92,13 @@ function useInput({
9292
9393 // only set error if it should be visible
9494 const error = !pass && hasBeenFocused && !focused && _error;
95− // whether or not the 'pass' effect should be shown
96− const visiblePass = pass && hasBeenFocused && !focused;
95+ // visibly tell the user that their input has passed if it has passed
96+ // and they are or have interacted with the input before
97+ const visiblyPassed = pass && (hasBeenFocused || focused);
9798
9899 return {
99100 pass,
100− // TODO: need a better name for `visiblePass`
101− visiblePass,
101+ visiblyPassed,
102102 error,
103103 data,
104104 focused,
@@ -119,23 +119,42 @@ export default function Input({
119119 initialValue = '',
120120 className = '',
121121 validators = [],
122− onSuccess,
123− onFailure,
122+ transformers = [],
123+ onValue,
124+ onPass,
125+ onError,
126+ onFocus,
124127 disabled = false,
125128 mono = false,
126− autofocus = false,
129+ autoFocus = false,
127130 ...rest
128131}) {
129− const { focused, pass, visiblePass, error, data, bind } = useInput({
132+ const { focused, pass, visiblyPassed, error, data, bind } = useInput({
130133 validators,
134+ transformers,
131135 initialValue,
132− autofocus,
136+ autoFocus,
133137 });
134138
139+ // notify parent of value only when passing
140+ useEffect(() => {
141+ pass && onValue && onValue(data);
142+ }, [pass, data, onValue]);
143+
144+ // notify parent of pass
145+ useEffect(() => {
146+ onPass && onPass(pass);
147+ }, [pass, onPass]);
148+
149+ // notify parent of error whenever error changes
150+ useEffect(() => {
151+ onError && onError(error);
152+ }, [error, onError]);
153+
154+ // notify parent of focus
135155 useEffect(() => {
136− onSuccess && onSuccess(data);
137− onFailure && onFailure(error);
138− }, [pass, error, data, onSuccess, onFailure]);
156+ onFocus && onFocus(focused);
157+ }, [focused, onFocus]);
139158
140159 return (
141160 <Grid>
@@ -159,15 +178,16 @@ export default function Input({
159178 black: focused,
160179 },
161180 {
162− 'b-black': focused,
163− 'b-gray3': !focused && !error && !visiblePass,
164− 'b-yellow3': !focused && error && !visiblePass,
165− 'b-green3': !focused && !error && visiblePass,
181+ 'b-green3': visiblyPassed,
182+ 'b-black': focused && !visiblyPassed,
183+ 'b-yellow3': !focused && !visiblyPassed && error,
184+ 'b-gray3': !focused && !error && !visiblyPassed,
166185 },
167186 className
168187 )}
169188 id={name}
170189 name={name}
190+ autoFocus={autoFocus}
171191 {...bind}
172192 />
173193 </Grid.Item>
src/indigo-react/index.js+1
@@ -1,2 +1,3 @@
11export { default as IndigoApp } from './components/IndigoApp';
22export { default as Input } from './components/Input';
3+export { default as Button } from './components/Button';
src/lib/useLifecycle.jsnew file+6
@@ -0,0 +1,6 @@
1+import { useEffect } from 'react';
2+
3+// https://overreacted.io/a-complete-guide-to-useeffect/
4+export default function useLifecycle(fn) {
5+ return useEffect(fn, []);
6+}
src/lib/validators.js+2−2
@@ -17,7 +17,7 @@ export const simpleValidatorWrapper = config => {
1717
1818 // Run the validator and return the result.
1919 return config.validator(config.prevMessage.data)
20− ? newMessage(config.prevMessage.data, true, '')
20+ ? newMessage(config.prevMessage.data, true, null)
2121 : newMessage(config.prevMessage.data, false, config.errorMessage);
2222};
2323
@@ -38,7 +38,7 @@ const newMessage = (data, pass, error) => ({
3838});
3939
4040// A validator that always passes.
41−export const kDefaultValidator = data => newMessage(data, true, '');
41+export const kDefaultValidator = data => newMessage(data, true, null);
4242
4343// Validates a bip39 mnemonic
4444export const validateMnemonic = m =>
src/style/indigo-proposals.scss+12
@@ -11,3 +11,15 @@
1111.lh-tall {
1212 line-height: 2;
1313}
14+
15+.bg-gray1-hover:hover {
16+ background-color: #f9f9f9;
17+}
18+
19+.bg-gray6-hover:hover {
20+ background-color: #333333;
21+}
22+
23+.bg-transparent {
24+ background-color: transparent;
25+}
src/views/Landing.js+18−37
@@ -1,62 +1,43 @@
11import React from 'react';
2−import { Button } from '../components/old/Base';
3−import { Row, Col } from '../components/old/Base';
42import { H1, P } from '../components/old/Base';
53
64import { ROUTE_NAMES } from '../lib/routeNames';
75import { useHistory } from '../store/history';
6+
87import View from 'components/View';
8+import { ForwardButton } from 'components/Buttons';
99
1010function Landing(props) {
1111 const history = useHistory();
1212
1313 return (
1414 <View>
15− <H1>{'Welcome'}</H1>
15+ <H1>Welcome</H1>
1616
1717 <P>
18− {'Bridge is a tool for managing and viewing assets on ' +
19− 'Azimuth, the Urbit address space.'}
18+ Bridge is a tool for managing and viewing assets on Azimuth, the Urbit
19+ address space.
2020 </P>
2121
22− <Button
23− prop-type="link"
24− prop-size="lg"
25− className={'mb-4 mt-8'}
26− onClick={() => history.push(ROUTE_NAMES.INVITE_TICKET)}>
27− {'Claim an invite →'}
28− </Button>
22+ <ForwardButton onClick={() => history.push(ROUTE_NAMES.INVITE_TICKET)}>
23+ Claim an invite
24+ </ForwardButton>
2925
30− <P>{'If you were sent an Azimuth invite code, start here.'}</P>
26+ <P>If you were sent an Azimuth invite code, start here.</P>
3127
32− <Button
33− prop-type="link"
34− prop-size="lg"
35− className={'mb-4 mt-8'}
36− onClick={() => history.push(ROUTE_NAMES.NETWORK)}>
37− {'Unlock a Wallet →'}
38− </Button>
28+ <ForwardButton onClick={() => history.push(ROUTE_NAMES.NETWORK)}>
29+ Unlock a Wallet
30+ </ForwardButton>
3931
4032 <P>
41− {'If you own Azimuth assets and want to manage them in some ' +
42− "way, start here. You'll need either your Urbit ticket or a " +
43− 'keypair.'}
33+ If you own Azimuth assets and want to manage them in some way, start
34+ here. You'll need either your Urbit ticket or a keypair.
4435 </P>
4536
46− {
47− <Row>
48− <Col>
49− <Button
50− prop-type={'link'}
51− prop-size={'lg'}
52− className={'mb-4 mt-8'}
53− onClick={() => history.push(ROUTE_NAMES.VIEW_SHIP)}>
54− {'View a point →'}
55− </Button>
56− <P>{'View an Azimuth point without signing into a wallet.'}</P>
57− </Col>
58− </Row>
59− }
37+ <ForwardButton onClick={() => history.push(ROUTE_NAMES.VIEW_SHIP)}>
38+ View a point
39+ </ForwardButton>
40+ <P>{'View an Azimuth point without signing into a wallet.'}</P>
6041 </View>
6142 );
6243}
src/views/Mnemonic.js+10−10
@@ -1,16 +1,15 @@
11import React, { useCallback, useEffect, useState } from 'react';
22import { Just, Nothing } from 'folktale/maybe';
33
4−import { Button } from '../components/old/Base';
4+import View from 'components/View';
5+import { MnemonicInput, PassphraseInput, HdPathInput } from 'components/Inputs';
6+import { ForwardButton } from 'components/Buttons';
57
68import { ROUTE_NAMES } from 'lib/routeNames';
79import { useHistory } from 'store/history';
810import { walletFromMnemonic } from 'lib/wallet';
911import { useWallet } from 'store/wallet';
1012
11−import View from 'components/View';
12−import { MnemonicInput, PassphraseInput, HdPathInput } from 'components/Inputs';
13−
1413export default function Mnemonic() {
1514 const history = useHistory();
1615 const {
@@ -47,28 +46,29 @@ export default function Mnemonic() {
4746 name="mnemonic"
4847 label="BIP39 Mnemonic"
4948 initialValue={mnemonic}
50− onSuccess={_setAuthMnemonic}
49+ onValue={_setAuthMnemonic}
50+ autoFocus
5151 />
5252
5353 <PassphraseInput
5454 name="passphrase"
5555 label="(Optional) Wallet Passphrase"
5656 initialValue={passphrase}
57− onSuccess={setPassphrase}
57+ onValue={setPassphrase}
5858 />
5959
6060 <HdPathInput
6161 name="hdpath"
6262 label="HD Path"
6363 initialValue={walletHdPath}
64− onSuccess={setWalletHdPath}
64+ onValue={setWalletHdPath}
6565 />
6666
67− <Button
67+ <ForwardButton
6868 disabled={Nothing.hasInstance(wallet)}
6969 onClick={() => history.popAndPush(ROUTE_NAMES.SHIPS)}>
70− {'Continue →'}
71− </Button>
70+ Continue
71+ </ForwardButton>
7272 </View>
7373 );
7474}
src/views/Network.js+3−6
@@ -1,6 +1,6 @@
11import React from 'react';
2+import { Button } from 'indigo-react';
23
3−import { Button } from '../components/old/Base';
44import { InnerLabelDropdown } from '../components/old/Base';
55import { H1, P } from '../components/old/Base';
66import { NETWORK_TYPES, renderNetworkType } from '../lib/network';
@@ -46,17 +46,14 @@ function Network() {
4646 </P>
4747
4848 <InnerLabelDropdown
49− className={'mt-6'}
5049 title={'Node:'}
5150 handleUpdate={setNetworkType}
5251 options={kNetworkOptions}
5352 currentSelectionTitle={renderNetworkType(networkType)}
5453 />
5554
56− <Button
57− className={'mt-10'}
58− onClick={() => history.push(ROUTE_NAMES.WALLET)}>
59− {'Continue →'}
55+ <Button icon="→" onClick={() => history.push(ROUTE_NAMES.WALLET)}>
56+ Continue
6057 </Button>
6158 </View>
6259 );
src/views/Point.js+1−1
@@ -6,7 +6,7 @@ import * as azimuth from 'azimuth-js';
66import * as need from '../lib/need';
77
88import PointList from '../components/old/PointList';
9−import ReactSVGComponents from '../components/old/ReactSVGComponents';
9+import ReactSVGComponents from '../components/ReactSVGComponents';
1010import KeysAndMetadata from './Point/KeysAndMetadata';
1111import Actions from './Point/Actions';
1212import { H1, H3 } from '../components/old/Base';
src/views/ViewPoint.js+53−80
@@ -1,88 +1,61 @@
1+import React, { useState } from 'react';
12import Maybe from 'folktale/maybe';
2−import React from 'react';
33import * as ob from 'urbit-ob';
44
5−import { Button } from '../components/old/Base';
65import { H1, P } from '../components/old/Base';
7−import { InnerLabel, PointInput, ValidatedSigil } from '../components/old/Base';
86
9−import { ROUTE_NAMES } from '../lib/routeNames';
10−import { withHistory } from '../store/history';
11−import { compose } from '../lib/lib';
12−import { withPointCursor } from '../store/pointCursor';
13−import View from 'components/View';
14−
15−class ViewPoint extends React.Component {
16− constructor(props) {
17− super(props);
18−
19− this.state = {
20− pointName: '',
21− };
22−
23− this.handlePointInput = this.handlePointInput.bind(this);
24− }
25−
26− handlePointInput = pointName => {
27− if (pointName.length < 15) {
28− this.setState({ pointName });
29− }
30− };
31−
32− render() {
33− const { pointName } = this.state;
34− const { history, setPointCursor } = this.props;
7+import { useHistory } from 'store/history';
8+import { usePointCursor } from 'store/pointCursor';
359
36− // NB (jtobin):
37− //
38− // could use a better patp parser in urbit-ob
39− let valid;
40− try {
41− valid = ob.isValidPatp(pointName);
42− } catch (err) {
43− valid = false;
44− }
10+import { ROUTE_NAMES } from 'lib/routeNames';
4511
46− return (
47− <View>
48− <H1>{'View a Point'}</H1>
49−
50− <P>{'Enter a point name to view its public information.'}</P>
51−
52− <PointInput
53− autoFocus
54− prop-size="lg"
55− prop-format="innerLabel"
56− className="mono"
57− placeholder="e.g. ~zod"
58− onChange={this.handlePointInput}
59− value={pointName}>
60− <InnerLabel>{'Point Name'}</InnerLabel>
61− <ValidatedSigil
62− className={'tr-0 mt-05 mr-0 abs'}
63− patp={pointName}
64− show
65− size={68}
66− margin={8}
67− />
68− </PointInput>
69−
70− <Button
71− className={'mt-8'}
72− disabled={valid === false}
73− onClick={() => {
74− setPointCursor(Maybe.Just(parseInt(ob.patp2dec(pointName), 10)));
75− // ^ pointCursor expects native number type, not string
76− history.popAndPush(ROUTE_NAMES.SHIP);
77− }}>
78− {'Continue →'}
79− </Button>
80− </View>
81− );
82− }
12+import View from 'components/View';
13+import { ForwardButton } from 'components/Buttons';
14+import { PointInput } from 'components/Inputs';
15+import InputSigil from 'components/InputSigil';
16+
17+export default function ViewPoint() {
18+ const history = useHistory();
19+ const { setPointCursor } = usePointCursor();
20+ const [pointName, setPointName] = useState('');
21+ const [pass, setPass] = useState(false);
22+ const [error, setError] = useState();
23+ const [focused, setFocused] = useState(true);
24+
25+ return (
26+ <View>
27+ <H1>{'View a Point'}</H1>
28+
29+ <P>{'Enter a point name to view its public information.'}</P>
30+
31+ <PointInput
32+ name="point"
33+ label="Point Name"
34+ onValue={setPointName}
35+ onPass={setPass}
36+ onError={setError}
37+ onFocus={setFocused}
38+ autoFocus
39+ />
40+
41+ <InputSigil
42+ patp={pointName}
43+ size={68}
44+ margin={8}
45+ pass={pass}
46+ focused={focused}
47+ error={error}
48+ />
49+
50+ <ForwardButton
51+ disabled={error}
52+ onClick={() => {
53+ setPointCursor(Maybe.Just(parseInt(ob.patp2dec(pointName), 10)));
54+ // ^ pointCursor expects native number type, not string
55+ history.popAndPush(ROUTE_NAMES.SHIP);
56+ }}>
57+ Continue
58+ </ForwardButton>
59+ </View>
60+ );
8361}
84−
85−export default compose(
86− withHistory,
87− withPointCursor
88−)(ViewPoint);
src/views/Wallet.js+88−97
@@ -1,110 +1,101 @@
1−import Maybe from 'folktale/maybe';
21import React from 'react';
3−import { Button, H1, P } from '../components/old/Base';
2+import Maybe from 'folktale/maybe';
3+
4+import { H1, P } from '../components/old/Base';
45import { InnerLabelDropdown } from '../components/old/Base';
56
7+import View from 'components/View';
8+import { ForwardButton } from 'components/Buttons';
9+
10+import { useHistory } from '../store/history';
11+import { useWallet } from '../store/wallet';
12+
613import { ROUTE_NAMES } from '../lib/routeNames';
7−import { withHistory } from '../store/history';
814import { WALLET_TYPES, renderWalletType } from '../lib/wallet';
9−import { compose } from '../lib/lib';
10−import { withWallet } from '../store/wallet';
11−import View from 'components/View';
15+import useLifecycle from 'lib/useLifecycle';
1216
13−class Wallet extends React.Component {
14− componentDidMount() {
15− const { setWallet } = this.props;
16− setWallet(Maybe.Nothing());
17− }
17+const kWalletOptions = [
18+ {
19+ title: 'Urbit Master Ticket',
20+ value: WALLET_TYPES.TICKET,
21+ },
22+ {
23+ title: 'Urbit Master Ticket (Shards)',
24+ value: WALLET_TYPES.SHARDS,
25+ },
26+ {
27+ type: 'divider',
28+ },
29+ {
30+ title: 'Ledger',
31+ value: WALLET_TYPES.LEDGER,
32+ },
33+ {
34+ title: 'Trezor',
35+ value: WALLET_TYPES.TREZOR,
36+ },
37+ {
38+ type: 'divider',
39+ },
40+ {
41+ title: 'BIP39 Mnemonic',
42+ value: WALLET_TYPES.MNEMONIC,
43+ },
44+ {
45+ title: 'Ethereum Private Key',
46+ value: WALLET_TYPES.PRIVATE_KEY,
47+ },
48+ {
49+ title: 'Ethereum Keystore File',
50+ value: WALLET_TYPES.KEYSTORE,
51+ },
52+];
1853
19− getWalletOptions() {
20− return [
21− {
22− title: 'Urbit Master Ticket',
23− value: WALLET_TYPES.TICKET,
24− },
25− {
26− title: 'Urbit Master Ticket (Shards)',
27− value: WALLET_TYPES.SHARDS,
28− },
29− {
30− type: 'divider',
31− },
32− {
33− title: 'Ledger',
34− value: WALLET_TYPES.LEDGER,
35− },
36− {
37− title: 'Trezor',
38− value: WALLET_TYPES.TREZOR,
39− },
40− {
41− type: 'divider',
42− },
43− {
44− title: 'BIP39 Mnemonic',
45− value: WALLET_TYPES.MNEMONIC,
46− },
47− {
48− title: 'Ethereum Private Key',
49− value: WALLET_TYPES.PRIVATE_KEY,
50− },
51− {
52− title: 'Ethereum Keystore File',
53− value: WALLET_TYPES.KEYSTORE,
54− },
55− ];
56− }
54+export default function Wallet() {
55+ const history = useHistory();
56+ const { setWallet, walletType, setWalletType } = useWallet();
5757
58− render() {
59− const { props } = this;
60− const walletOptions = this.getWalletOptions();
58+ // reset wallet when this component is mounted
59+ useLifecycle(() => setWallet(Maybe.Nothing()));
6160
62− return (
63− <View>
64− <H1>{'Unlock a Wallet'}</H1>
61+ return (
62+ <View>
63+ <H1>Unlock a Wallet</H1>
6564
66− <P>
67− {`To manage your assets, you need to unlock a wallet.
68− Please select how you would like to access your wallet.`}
69− </P>
65+ <P>
66+ To manage your assets, you need to unlock a wallet. Please select how
67+ you would like to access your wallet.
68+ </P>
7069
71− <InnerLabelDropdown
72− className={'mb-10 mt-6'}
73− title={'Wallet Type:'}
74− options={walletOptions}
75− handleUpdate={props.setWalletType}
76− currentSelectionTitle={renderWalletType(props.walletType)}
77− />
70+ <InnerLabelDropdown
71+ title="Wallet Type:"
72+ options={kWalletOptions}
73+ handleUpdate={setWalletType}
74+ currentSelectionTitle={renderWalletType(walletType)}
75+ />
7876
79− <Button
80− className={'mt-10'}
81− onClick={() =>
82− props.history.push(
83− props.walletType === WALLET_TYPES.MNEMONIC
84− ? ROUTE_NAMES.MNEMONIC
85− : props.walletType === WALLET_TYPES.TICKET
86− ? ROUTE_NAMES.TICKET
87− : props.walletType === WALLET_TYPES.SHARDS
88− ? ROUTE_NAMES.SHARDS
89− : props.walletType === WALLET_TYPES.LEDGER
90− ? ROUTE_NAMES.LEDGER
91− : props.walletType === WALLET_TYPES.TREZOR
92− ? ROUTE_NAMES.TREZOR
93− : props.walletType === WALLET_TYPES.PRIVATE_KEY
94− ? ROUTE_NAMES.PRIVATE_KEY
95− : props.walletType === WALLET_TYPES.KEYSTORE
96− ? ROUTE_NAMES.KEYSTORE
97− : ROUTE_NAMES.DEFAULT
98− )
99− }>
100− {'Continue →'}
101− </Button>
102− </View>
103− );
104− }
77+ <ForwardButton
78+ onClick={() =>
79+ history.push(
80+ walletType === WALLET_TYPES.MNEMONIC
81+ ? ROUTE_NAMES.MNEMONIC
82+ : walletType === WALLET_TYPES.TICKET
83+ ? ROUTE_NAMES.TICKET
84+ : walletType === WALLET_TYPES.SHARDS
85+ ? ROUTE_NAMES.SHARDS
86+ : walletType === WALLET_TYPES.LEDGER
87+ ? ROUTE_NAMES.LEDGER
88+ : walletType === WALLET_TYPES.TREZOR
89+ ? ROUTE_NAMES.TREZOR
90+ : walletType === WALLET_TYPES.PRIVATE_KEY
91+ ? ROUTE_NAMES.PRIVATE_KEY
92+ : walletType === WALLET_TYPES.KEYSTORE
93+ ? ROUTE_NAMES.KEYSTORE
94+ : ROUTE_NAMES.DEFAULT
95+ )
96+ }>
97+ Continue
98+ </ForwardButton>
99+ </View>
100+ );
105101}
106−
107−export default compose(
108− withHistory,
109− withWallet
110−)(Wallet);