on master help sign in
fix: implement warnings
e8991deMatt Condon (shrugs)
src/components/Highlighted.js+14−6
@@ -1,13 +1,21 @@
1import React from 'react';
1import React from 'react';
2import cn from 'classnames';
2import cn from 'classnames';
3
3
4−export default function Highlighted({ warning = false, ...rest }) {
4+export default function Highlighted({
5+ as: As = 'span',
6+ className,
7+ warning = false,
8+ ...rest
9+}) {
5 return (
10 return (
6− <span
11+ <As
7− className={cn({
12+ className={cn(
13+ {
8− red3: warning,
14+ red3: warning,
9− green3: !warning,
15+ green3: !warning,
16+ },
17+ className
10− })}
18+ )}
11 {...rest}
19 {...rest}
12 />
20 />
13 );
21 );
src/form/BridgeForm.js+3
@@ -6,6 +6,7 @@ import { noop } from 'lodash';
6
6
7import ValuesHandler from './ValuesHandler';
7import ValuesHandler from './ValuesHandler';
8import ValidationPauser from './ValidationPauser';
8import ValidationPauser from './ValidationPauser';
9+import WarningEngine from './WarningEngine';
9
10
10/**
11/**
11 * BridgeForm adds nice-to-haves for every form in bridge.
12 * BridgeForm adds nice-to-haves for every form in bridge.
@@ -20,6 +21,7 @@ export default function BridgeForm({
20 onValues,
21 onValues,
21 onSubmit = noop,
22 onSubmit = noop,
22 afterSubmit = noop,
23 afterSubmit = noop,
24+ warnings,
23 ...rest
25 ...rest
24}) {
26}) {
25 const _onSubmit = useCallback(
27 const _onSubmit = useCallback(
@@ -41,6 +43,7 @@ export default function BridgeForm({
41 {...rest}>
43 {...rest}>
42 {formProps => (
44 {formProps => (
43 <>
45 <>
46+ {warnings && <WarningEngine warnings={warnings} />}
44 <ValidationPauser />
47 <ValidationPauser />
45 {children(formProps)}
48 {children(formProps)}
46 {onValues && <ValuesHandler onValues={onValues} />}
49 {onValues && <ValuesHandler onValues={onValues} />}
src/form/WarningEngine.jsnew file+15
@@ -0,0 +1,15 @@
1+import { useEffect } from 'react';
2+import { useForm } from 'react-final-form';
3+import { map } from 'lodash';
4+
5+export default function WarningEngine({ warnings }) {
6+ const form = useForm();
7+
8+ useEffect(() => {
9+ map(warnings, (warning, name) =>
10+ form.mutators.setFieldData(name, { warning })
11+ );
12+ }, [form, warnings]);
13+
14+ return null;
15+}
src/indigo-react/components/Input.js+16−2
@@ -1,9 +1,9 @@
1import React from 'react';
1import React from 'react';
2import cn from 'classnames';
2import cn from 'classnames';
3+import { useField } from 'react-final-form';
3
4
4import Flex from './Flex';
5import Flex from './Flex';
5import { ErrorText } from './Typography';
6import { ErrorText } from './Typography';
6−import { useField } from 'react-final-form';
7
7
8export default function Input({
8export default function Input({
9 // visuals
9 // visuals
@@ -26,7 +26,14 @@ export default function Input({
26}) {
26}) {
27 const {
27 const {
28 input,
28 input,
29+ meta: {
30+ active,
31+ error,
29− meta: { active, error, submitting, touched, valid },
32+ submitting,
33+ touched,
34+ valid,
35+ data: { warning },
36+ },
30 } = useField(name, config);
37 } = useField(name, config);
31
38
32 disabled = disabled || submitting;
39 disabled = disabled || submitting;
@@ -101,6 +108,13 @@ export default function Input({
101 </div>
108 </div>
102 )}
109 )}
103 </Flex.Item>
110 </Flex.Item>
111+
112+ {warning && (
113+ <Flex.Item as={ErrorText} className="mv1">
114+ {warning}
115+ </Flex.Item>
116+ )}
117+
104 {touched && !active && error && (
118 {touched && !active && error && (
105 <Flex.Item as={ErrorText} className="mv1">
119 <Flex.Item as={ErrorText} className="mv1">
106 {error}
120 {error}
src/indigo-react/components/SelectInput.js+17−3
@@ -1,11 +1,11 @@
1import React, { useCallback, useRef, useState } from 'react';
1import React, { useCallback, useRef, useState } from 'react';
2import cn from 'classnames';
2import cn from 'classnames';
3+import { useField } from 'react-final-form';
4+import useOnClickOutside from 'indigo-react/lib/useOnClickOutside';
3
5
4import Flex from './Flex';
6import Flex from './Flex';
5import { ErrorText } from './Typography';
7import { ErrorText } from './Typography';
6−import useOnClickOutside from 'indigo-react/lib/useOnClickOutside';
7import AccessoryIcon from './AccessoryIcon';
8import AccessoryIcon from './AccessoryIcon';
8−import { useField } from 'react-final-form';
9
9
10// NOTE: if we really care about accessibility, we should pull in a dependency
10// NOTE: if we really care about accessibility, we should pull in a dependency
11export default function SelectInput({
11export default function SelectInput({
@@ -19,7 +19,14 @@ export default function SelectInput({
19}) {
19}) {
20 const {
20 const {
21 input,
21 input,
22+ meta: {
23+ active,
24+ error,
22− meta: { active, error, submitting, touched, valid },
25+ submitting,
26+ touched,
27+ valid,
28+ data: { warning },
29+ },
23 } = useField(name, {
30 } = useField(name, {
24 type: 'select',
31 type: 'select',
25 });
32 });
@@ -121,6 +128,13 @@ export default function SelectInput({
121 </Flex>
128 </Flex>
122 )}
129 )}
123 </Flex.Item>
130 </Flex.Item>
131+
132+ {warning && (
133+ <Flex.Item as={ErrorText} className="mv1">
134+ {warning}
135+ </Flex.Item>
136+ )}
137+
124 {touched && !active && error && (
138 {touched && !active && error && (
125 <Flex.Item as={ErrorText} className="mv1">
139 <Flex.Item as={ErrorText} className="mv1">
126 {error}
140 {error}
src/views/Login/Ledger.js+1−1
@@ -1,6 +1,6 @@
1import React, { useCallback, useMemo } from 'react';
1import React, { useCallback, useMemo } from 'react';
2import cn from 'classnames';
2import cn from 'classnames';
3−import { Just, Nothing } from 'folktale/maybe';
3+import { Just } from 'folktale/maybe';
4import {
4import {
5 P,
5 P,
6 Text,
6 Text,
src/views/Login/Ticket.js+11−6
@@ -30,6 +30,7 @@ import {
30import FormError from 'form/FormError';
30import FormError from 'form/FormError';
31
31
32import ContinueButton from './ContinueButton';
32import ContinueButton from './ContinueButton';
33+import useSetState from 'lib/useSetState';
33
34
34export default function Ticket({ className, goHome }) {
35export default function Ticket({ className, goHome }) {
35 useLoginView(WALLET_TYPES.TICKET);
36 useLoginView(WALLET_TYPES.TICKET);
@@ -38,6 +39,7 @@ export default function Ticket({ className, goHome }) {
38 const { setUrbitWallet } = useWallet();
39 const { setUrbitWallet } = useWallet();
39 const { setPointCursor } = usePointCursor();
40 const { setPointCursor } = usePointCursor();
40 const impliedPoint = useImpliedPoint();
41 const impliedPoint = useImpliedPoint();
42+ const [warnings, addWarning] = useSetState();
41
43
42 const cachedUrbitWallet = useRef(Nothing());
44 const cachedUrbitWallet = useRef(Nothing());
43
45
@@ -88,11 +90,13 @@ export default function Ticket({ className, goHome }) {
88 ),
90 ),
89 ]);
91 ]);
90
92
91− if (!isOwner && !isTransferProxy) {
93+ const noPermissions = !isOwner && !isTransferProxy;
92− // notify the user, but allow login regardless
94+ // notify the user, but allow login regardless
93− // TODO: warnings
95+ addWarning({
96+ point: noPermissions
94− // 'This ticket is not the owner of or transfer proxy for this point.'
97+ ? 'This wallet is not the owner or transfer proxy for this point.'
98+ : null,
95− }
99+ });
96 } catch (error) {
100 } catch (error) {
97 console.error(error);
101 console.error(error);
98 return {
102 return {
@@ -102,7 +106,7 @@ export default function Ticket({ className, goHome }) {
102 };
106 };
103 }
107 }
104 },
108 },
105− [contracts]
109+ [addWarning, contracts]
106 );
110 );
107
111
108 const validate = useMemo(
112 const validate = useMemo(
@@ -147,6 +151,7 @@ export default function Ticket({ className, goHome }) {
147 return (
151 return (
148 <Grid className={cn('mt4', className)}>
152 <Grid className={cn('mt4', className)}>
149 <BridgeForm
153 <BridgeForm
154+ warnings={warnings}
150 validate={validate}
155 validate={validate}
151 onValues={onValues}
156 onValues={onValues}
152 afterSubmit={goHome}
157 afterSubmit={goHome}
src/views/Login/Trezor.js+1−1
@@ -1,5 +1,5 @@
1import React, { useCallback, useMemo } from 'react';
1import React, { useCallback, useMemo } from 'react';
2−import { Just, Nothing } from 'folktale/maybe';
2+import { Just } from 'folktale/maybe';
3import * as bip32 from 'bip32';
3import * as bip32 from 'bip32';
4import { times } from 'lodash';
4import { times } from 'lodash';
5import TrezorConnect from 'trezor-connect';
5import TrezorConnect from 'trezor-connect';