on master help sign in
feat: extract point state
0e2963eMatt Condon (shrugs)
src/bridge/Bridge.js+6−35
@@ -17,6 +17,7 @@ import { TxnConfirmationsProvider } from './store/txnConfirmations';
17import { OnlineProvider } from './store/online';
17import { OnlineProvider } from './store/online';
18import { NetworkProvider } from './store/network';
18import { NetworkProvider } from './store/network';
19import { WalletProvider } from './store/wallet';
19import { WalletProvider } from './store/wallet';
20+import { PointCursorProvider } from './store/pointCursor';
20
21
21const kInitialNetworkType = isDevelopment
22const kInitialNetworkType = isDevelopment
22 ? NETWORK_TYPES.LOCAL
23 ? NETWORK_TYPES.LOCAL
@@ -45,6 +46,7 @@ const kInitialWallet = kIsStubbed
45const kInitialMnemonic = kIsStubbed
46const kInitialMnemonic = kIsStubbed
46 ? process.env.REACT_APP_DEV_MNEMONIC
47 ? process.env.REACT_APP_DEV_MNEMONIC
47 : Nothing();
48 : Nothing();
49+const kInitialPointCursor = kIsStubbed ? Just(0) : Nothing();
48
50
49// the router itself is just a component that renders a specific view
51// the router itself is just a component that renders a specific view
50// depending on the history
52// depending on the history
@@ -83,6 +85,7 @@ const AllProviders = nest([
83 OnlineProvider,
85 OnlineProvider,
84 NetworkProvider,
86 NetworkProvider,
85 WalletProvider,
87 WalletProvider,
88+ PointCursorProvider,
86]);
89]);
87
90
88class Bridge extends React.Component {
91class Bridge extends React.Component {
@@ -91,30 +94,13 @@ class Bridge extends React.Component {
91
94
92 this.state = {
95 this.state = {
93 networkSeedCache: null,
96 networkSeedCache: null,
94− // point
95− pointCursor: Nothing(),
96− pointCache: {},
97 // txn
97 // txn
98 txnHashCursor: Nothing(),
98 txnHashCursor: Nothing(),
99 txnConfirmations: {},
99 txnConfirmations: {},
100 };
100 };
101
101
102− this.setPointCursor = this.setPointCursor.bind(this);
103 this.setTxnHashCursor = this.setTxnHashCursor.bind(this);
102 this.setTxnHashCursor = this.setTxnHashCursor.bind(this);
104 this.setNetworkSeedCache = this.setNetworkSeedCache.bind(this);
103 this.setNetworkSeedCache = this.setNetworkSeedCache.bind(this);
105− this.addToPointCache = this.addToPointCache.bind(this);
106− }
107−
108− componentDidMount() {
109− // NB (jtobin, shrugs):
110− //
111− // If running in development, the following can be tweaked to get you set
112− // up with a desirable initial state.
113− if (kIsStubbed) {
114− this.setState({
115− pointCursor: Just(0),
116− });
117− }
118 }
104 }
119
105
120 setNetworkSeedCache(networkSeed, revision) {
106 setNetworkSeedCache(networkSeed, revision) {
@@ -124,16 +110,6 @@ class Bridge extends React.Component {
124 });
110 });
125 }
111 }
126
112
127− setPointCursor(pointCursor) {
128− this.setState({ pointCursor });
129− }
130−
131− addToPointCache(entry) {
132− this.setState((state, _) => ({
133− pointCache: Object.assign(state.pointCache, entry),
134− }));
135− }
136−
137 setTxnHashCursor(txnHashCursor) {
113 setTxnHashCursor(txnHashCursor) {
138 this.setState({ txnHashCursor });
114 this.setState({ txnHashCursor });
139 }
115 }
@@ -142,8 +118,6 @@ class Bridge extends React.Component {
142 const {
118 const {
143 networkSeedCache,
119 networkSeedCache,
144 networkRevisionCache,
120 networkRevisionCache,
145− pointCursor,
146− pointCache,
147 txnHashCursor,
121 txnHashCursor,
148 } = this.state;
122 } = this.state;
149
123
@@ -152,18 +126,15 @@ class Bridge extends React.Component {
152 initialRoutes={kInitialRoutes}
126 initialRoutes={kInitialRoutes}
153 initialNetworkType={kInitialNetworkType}
127 initialNetworkType={kInitialNetworkType}
154 initialWallet={kInitialWallet}
128 initialWallet={kInitialWallet}
155− initialMnemonic={kInitialMnemonic}>
129+ initialMnemonic={kInitialMnemonic}
130+ initialPointCursor={kInitialPointCursor}>
156 <Container>
131 <Container>
157 <Row>
132 <Row>
158 <VariableWidthColumn>
133 <VariableWidthColumn>
159− <Header pointCursor={pointCursor} />
134+ <Header />
160
135
161 <Row className={'row wrapper'}>
136 <Row className={'row wrapper'}>
162 <Router
137 <Router
163− setPointCursor={this.setPointCursor}
164− addToPointCache={this.addToPointCache}
165− pointCursor={pointCursor}
166− pointCache={pointCache}
167 networkSeedCache={networkSeedCache}
138 networkSeedCache={networkSeedCache}
168 networkRevisionCache={networkRevisionCache}
139 networkRevisionCache={networkRevisionCache}
169 setNetworkSeedCache={this.setNetworkSeedCache}
140 setNetworkSeedCache={this.setNetworkSeedCache}
src/bridge/components/Header.js+6−4
@@ -7,19 +7,21 @@ import { useHistory } from '../store/history';
7import { isLast } from '../lib/lib';
7import { isLast } from '../lib/lib';
8import { useNetwork } from '../store/network';
8import { useNetwork } from '../store/network';
9import { useWallet } from '../store/wallet';
9import { useWallet } from '../store/wallet';
10+import { usePointCursor } from '../store/pointCursor';
10
11
11// hook to create a breadcrumb builder function based on the current
12// hook to create a breadcrumb builder function based on the current
12// global states
13// global states
13−function useRouteBreadcrumbBuilder(props) {
14+function useRouteBreadcrumbBuilder() {
14 const { networkType } = useNetwork();
15 const { networkType } = useNetwork();
15 const { wallet } = useWallet();
16 const { wallet } = useWallet();
17+ const { pointCursor } = usePointCursor();
16
18
17− return getRouteBreadcrumb({ ...props, networkType, wallet });
19+ return getRouteBreadcrumb({ pointCursor, networkType, wallet });
18}
20}
19
21
20function Crumbs(props) {
22function Crumbs(props) {
21 const history = useHistory();
23 const history = useHistory();
22− const breadcrumbBuilder = useRouteBreadcrumbBuilder(props);
24+ const breadcrumbBuilder = useRouteBreadcrumbBuilder();
23
25
24 return (
26 return (
25 <>
27 <>
@@ -53,7 +55,7 @@ function Header(props) {
53 if (showCrumbs) {
55 if (showCrumbs) {
54 return (
56 return (
55 <div className={'flex items-center h-10'}>
57 <div className={'flex items-center h-10'}>
56− <Crumbs pointCursor={props.pointCursor} />
58+ <Crumbs />
57 </div>
59 </div>
58 );
60 );
59 }
61 }
src/bridge/components/PointList.js+5−2
@@ -1,11 +1,14 @@
1import React from 'react';
1import React from 'react';
2import { chunk } from 'lodash';
2import { chunk } from 'lodash';
3
3
4+import { usePointCursor } from '../store/pointCursor';
5+
4import { Row } from './Base';
6import { Row } from './Base';
5import RenderedPoint from './RenderedPoint';
7import RenderedPoint from './RenderedPoint';
6
8
7−const PointList = props => {
9+const PointList = function(props) {
10+ const { setPointCursor } = usePointCursor();
8− const { setPointCursor, routeHandler, points, loading } = props;
11+ const { routeHandler, points, loading } = props;
9 const chunks = chunk(points, 3);
12 const chunks = chunk(points, 3);
10
13
11 return points.length === 0 ? (
14 return points.length === 0 ? (
src/bridge/lib/router.js+1−1
@@ -68,9 +68,9 @@ const ROUTES = {
68};
68};
69
69
70export const getRouteBreadcrumb = ({
70export const getRouteBreadcrumb = ({
71+ pointCursor,
71 networkType,
72 networkType,
72 wallet,
73 wallet,
73− pointCursor,
74}) => route => {
74}) => route => {
75 switch (route.name) {
75 switch (route.name) {
76 case ROUTE_NAMES.INVITE_TICKET:
76 case ROUTE_NAMES.INVITE_TICKET:
src/bridge/store/pointCache.jsnew file+39
@@ -0,0 +1,39 @@
1+import React, { createContext, forwardRef, useContext, useState } from 'react';
2+import Maybe from 'folktale/maybe';
3+
4+export const PointCacheContext = createContext(null);
5+
6+function _usePointCache(initialPointCache = Maybe.Nothing()) {
7+ const [pointCache, _setPointCache] = useState(initialPointCache);
8+
9+ const addToPointCache = entry =>
10+ _setPointCache(cache => ({ ...cache, entry }));
11+
12+ return {
13+ pointCache,
14+ addToPointCache,
15+ };
16+}
17+
18+export function PointCacheProvider({ initialPointCache, children }) {
19+ const pointCache = _usePointCache(initialPointCache);
20+
21+ return (
22+ <PointCacheContext.Provider value={pointCache}>
23+ {children}
24+ </PointCacheContext.Provider>
25+ );
26+}
27+
28+// Hook version
29+export function usePointCache() {
30+ return useContext(PointCacheContext);
31+}
32+
33+// HOC version
34+export const withPointCache = Component =>
35+ forwardRef((props, ref) => (
36+ <PointCacheContext.Consumer>
37+ {pointCache => <Component ref={ref} {...pointCache} {...props} />}
38+ </PointCacheContext.Consumer>
39+ ));
src/bridge/store/pointCursor.jsnew file+36
@@ -0,0 +1,36 @@
1+import React, { createContext, forwardRef, useContext, useState } from 'react';
2+import Maybe from 'folktale/maybe';
3+
4+export const PointCursorContext = createContext(null);
5+
6+function _usePointCursor(initialPointCursor = Maybe.Nothing()) {
7+ const [pointCursor, setPointCursor] = useState(initialPointCursor);
8+
9+ return {
10+ pointCursor,
11+ setPointCursor,
12+ };
13+}
14+
15+export function PointCursorProvider({ initialPointCursor, children }) {
16+ const pointCursor = _usePointCursor(initialPointCursor);
17+
18+ return (
19+ <PointCursorContext.Provider value={pointCursor}>
20+ {children}
21+ </PointCursorContext.Provider>
22+ );
23+}
24+
25+// Hook version
26+export function usePointCursor() {
27+ return useContext(PointCursorContext);
28+}
29+
30+// HOC version
31+export const withPointCursor = Component =>
32+ forwardRef((props, ref) => (
33+ <PointCursorContext.Consumer>
34+ {pointCursor => <Component ref={ref} {...pointCursor} {...props} />}
35+ </PointCursorContext.Consumer>
36+ ));
src/bridge/views/AcceptTransfer.js+3−1
@@ -17,6 +17,7 @@ import { isValidAddress } from '../lib/wallet';
17import { withNetwork } from '../store/network';
17import { withNetwork } from '../store/network';
18import { compose } from '../lib/lib';
18import { compose } from '../lib/lib';
19import { withWallet } from '../store/wallet';
19import { withWallet } from '../store/wallet';
20+import { withPointCursor } from '../store/pointCursor';
20
21
21class AcceptTransfer extends React.Component {
22class AcceptTransfer extends React.Component {
22 constructor(props) {
23 constructor(props) {
@@ -122,5 +123,6 @@ class AcceptTransfer extends React.Component {
122
123
123export default compose(
124export default compose(
124 withNetwork,
125 withNetwork,
125− withWallet
126+ withWallet,
127+ withPointCursor
126)(AcceptTransfer);
128)(AcceptTransfer);
src/bridge/views/CancelTransfer.js+7−1
@@ -9,6 +9,8 @@ import StatelessTransaction from '../components/StatelessTransaction';
9import { ETH_ZERO_ADDR } from '../lib/wallet';
9import { ETH_ZERO_ADDR } from '../lib/wallet';
10import { withNetwork } from '../store/network';
10import { withNetwork } from '../store/network';
11import { compose } from '../lib/lib';
11import { compose } from '../lib/lib';
12+import { withPointCursor } from '../store/pointCursor';
13+import { withPointCache } from '../store/pointCache';
12
14
13class CancelTransfer extends React.Component {
15class CancelTransfer extends React.Component {
14 constructor(props) {
16 constructor(props) {
@@ -75,4 +77,8 @@ class CancelTransfer extends React.Component {
75 }
77 }
76}
78}
77
79
78−export default compose(withNetwork)(CancelTransfer);
80+export default compose(
81+ withNetwork,
82+ withPointCursor,
83+ withPointCache
84+)(CancelTransfer);
src/bridge/views/GenKeyfile.js+5−1
@@ -13,6 +13,7 @@ import { attemptSeedDerivation, genKey } from '../lib/keys';
13import { addHexPrefix } from '../lib/wallet';
13import { addHexPrefix } from '../lib/wallet';
14import { compose } from '../lib/lib';
14import { compose } from '../lib/lib';
15import { withWallet } from '../store/wallet';
15import { withWallet } from '../store/wallet';
16+import { withPointCursor } from '../store/pointCursor';
16
17
17class GenKeyfile extends React.Component {
18class GenKeyfile extends React.Component {
18 constructor(props) {
19 constructor(props) {
@@ -134,4 +135,7 @@ class GenKeyfile extends React.Component {
134 }
135 }
135}
136}
136
137
137−export default compose(withWallet)(GenKeyfile);
138+export default compose(
139+ withWallet,
140+ withPointCursor
141+)(GenKeyfile);
src/bridge/views/InvitesManage.js+5−1
@@ -16,6 +16,7 @@ import {
16import StatelessTransaction from '../components/StatelessTransaction';
16import StatelessTransaction from '../components/StatelessTransaction';
17import { withNetwork } from '../store/network';
17import { withNetwork } from '../store/network';
18import { compose } from '../lib/lib';
18import { compose } from '../lib/lib';
19+import { withPointCursor } from '../store/pointCursor';
19
20
20class InvitesManage extends React.Component {
21class InvitesManage extends React.Component {
21 constructor(props) {
22 constructor(props) {
@@ -184,4 +185,7 @@ class InvitesManage extends React.Component {
184 }
185 }
185}
186}
186
187
187−export default compose(withNetwork)(InvitesManage);
188+export default compose(
189+ withNetwork,
190+ withPointCursor
191+)(InvitesManage);
src/bridge/views/InvitesSend.js+3−1
@@ -22,6 +22,7 @@ import * as tank from '../lib/tank';
22import { withNetwork } from '../store/network';
22import { withNetwork } from '../store/network';
23import { compose } from '../lib/lib';
23import { compose } from '../lib/lib';
24import { withWallet } from '../store/wallet';
24import { withWallet } from '../store/wallet';
25+import { withPointCursor } from '../store/pointCursor';
25
26
26const GAS_PRICE_GWEI = 20; // we pay the premium for faster ux
27const GAS_PRICE_GWEI = 20; // we pay the premium for faster ux
27const GAS_LIMIT = 350000;
28const GAS_LIMIT = 350000;
@@ -496,5 +497,6 @@ class InvitesSend extends React.Component {
496
497
497export default compose(
498export default compose(
498 withNetwork,
499 withNetwork,
499− withWallet
500+ withWallet,
501+ withPointCursor
500)(InvitesSend);
502)(InvitesSend);
src/bridge/views/IssueChild.js+5−1
@@ -26,6 +26,7 @@ import { canDecodePatp } from '../lib/txn';
26import { isValidAddress } from '../lib/wallet';
26import { isValidAddress } from '../lib/wallet';
27import { withNetwork } from '../store/network';
27import { withNetwork } from '../store/network';
28import { compose } from '../lib/lib';
28import { compose } from '../lib/lib';
29+import { withPointCursor } from '../store/pointCursor';
29
30
30const setFind = (set, pred) => {
31const setFind = (set, pred) => {
31 for (const e of set) {
32 for (const e of set) {
@@ -255,4 +256,7 @@ class IssueChild extends React.Component {
255 }
256 }
256}
257}
257
258
258−export default compose(withNetwork)(IssueChild);
259+export default compose(
260+ withNetwork,
261+ withPointCursor
262+)(IssueChild);
src/bridge/views/Point.js+7−7
@@ -14,6 +14,8 @@ import { withHistory } from '../store/history';
14import { withNetwork } from '../store/network';
14import { withNetwork } from '../store/network';
15import { compose } from '../lib/lib';
15import { compose } from '../lib/lib';
16import { withWallet } from '../store/wallet';
16import { withWallet } from '../store/wallet';
17+import { withPointCursor } from '../store/pointCursor';
18+import { withPointCache } from '../store/pointCache';
17
19
18class Point extends React.Component {
20class Point extends React.Component {
19 constructor(props) {
21 constructor(props) {
@@ -77,7 +79,7 @@ class Point extends React.Component {
77 };
79 };
78
80
79 render() {
81 render() {
80− const { web3, history, wallet, setPointCursor, pointCache } = this.props;
82+ const { web3, history, wallet, pointCache } = this.props;
81
83
82 const { spawned } = this.state;
84 const { spawned } = this.state;
83
85
@@ -105,11 +107,7 @@ class Point extends React.Component {
105 <div>
107 <div>
106 <H3>{'Issued Points'}</H3>
108 <H3>{'Issued Points'}</H3>
107
109
108− <PointList
109− setPointCursor={setPointCursor}
110− routeHandler={history.popAndPush}
110+ <PointList routeHandler={history.popAndPush} points={spawned} />
111− points={spawned}
112− />
113 </div>
111 </div>
114 );
112 );
115
113
@@ -140,5 +138,7 @@ class Point extends React.Component {
140export default compose(
138export default compose(
141 withNetwork,
139 withNetwork,
142 withHistory,
140 withHistory,
143− withWallet
141+ withWallet,
142+ withPointCursor,
143+ withPointCache
144)(Point);
144)(Point);
src/bridge/views/Points.js+3−1
@@ -11,6 +11,7 @@ import { ETH_ZERO_ADDR, eqAddr } from '../lib/wallet';
11import { withNetwork } from '../store/network';
11import { withNetwork } from '../store/network';
12import { compose } from '../lib/lib';
12import { compose } from '../lib/lib';
13import { withWallet } from '../store/wallet';
13import { withWallet } from '../store/wallet';
14+import { withPointCache } from '../store/pointCache';
14
15
15const hasTransferProxy = (cache, point) =>
16const hasTransferProxy = (cache, point) =>
16 point in cache ? !eqAddr(cache[point].transferProxy, ETH_ZERO_ADDR) : false;
17 point in cache ? !eqAddr(cache[point].transferProxy, ETH_ZERO_ADDR) : false;
@@ -260,5 +261,6 @@ class Points extends React.Component {
260export default compose(
261export default compose(
261 withNetwork,
262 withNetwork,
262 withHistory,
263 withHistory,
263− withWallet
264+ withWallet,
265+ withPointCache
264)(Points);
266)(Points);
src/bridge/views/SentTransaction.js+2−1
@@ -10,6 +10,7 @@ import { BRIDGE_ERROR, renderTxnError } from '../lib/error';
10import { NETWORK_TYPES } from '../lib/network';
10import { NETWORK_TYPES } from '../lib/network';
11import { useTxnConfirmations } from '../store/txnConfirmations';
11import { useTxnConfirmations } from '../store/txnConfirmations';
12import { useNetwork } from '../store/network';
12import { useNetwork } from '../store/network';
13+import { usePointCursor } from '../store/pointCursor';
13
14
14class Success extends React.Component {
15class Success extends React.Component {
15 constructor(props) {
16 constructor(props) {
@@ -113,10 +114,10 @@ const Failure = props => (
113function SentTransaction(props) {
114function SentTransaction(props) {
114 const history = useHistory();
115 const history = useHistory();
115 const { txnConfirmations } = useTxnConfirmations();
116 const { txnConfirmations } = useTxnConfirmations();
117+ const { setPointCursor, pointCursor } = usePointCursor();
116 const { web3 } = useNetwork();
118 const { web3 } = useNetwork();
117
119
118 const { txnHashCursor, networkType } = props;
120 const { txnHashCursor, networkType } = props;
119− const { setPointCursor, pointCursor } = props;
120
121
121 const promptKeyfile = history.data && history.data.promptKeyfile;
122 const promptKeyfile = history.data && history.data.promptKeyfile;
122
123
src/bridge/views/SetKeys.js+3−1
@@ -14,6 +14,7 @@ import { compose } from '../lib/lib';
14
14
15import { withNetwork } from '../store/network';
15import { withNetwork } from '../store/network';
16import { withWallet } from '../store/wallet';
16import { withWallet } from '../store/wallet';
17+import { withPointCursor } from '../store/pointCursor';
17
18
18class SetKeys extends React.Component {
19class SetKeys extends React.Component {
19 constructor(props) {
20 constructor(props) {
@@ -201,5 +202,6 @@ class SetKeys extends React.Component {
201
202
202export default compose(
203export default compose(
203 withNetwork,
204 withNetwork,
204− withWallet
205+ withWallet,
206+ withPointCursor
205)(SetKeys);
207)(SetKeys);
src/bridge/views/SetProxy.js+5−1
@@ -24,6 +24,7 @@ import StatelessTransaction from '../components/StatelessTransaction';
24import { isValidAddress } from '../lib/wallet';
24import { isValidAddress } from '../lib/wallet';
25import { withNetwork } from '../store/network';
25import { withNetwork } from '../store/network';
26import { compose } from '../lib/lib';
26import { compose } from '../lib/lib';
27+import { withPointCursor } from '../store/pointCursor';
27
28
28class _SetProxy extends React.Component {
29class _SetProxy extends React.Component {
29 constructor(props) {
30 constructor(props) {
@@ -169,7 +170,10 @@ class _SetProxy extends React.Component {
169 }
170 }
170}
171}
171
172
172−const SetProxy = compose(withNetwork)(_SetProxy);
173+const SetProxy = compose(
174+ withNetwork,
175+ withPointCursor
176+)(_SetProxy);
173
177
174export const SetManagementProxy = props => (
178export const SetManagementProxy = props => (
175 <SetProxy {...props} proxyType={PROXY_TYPE.MANAGEMENT_PROXY} />
179 <SetProxy {...props} proxyType={PROXY_TYPE.MANAGEMENT_PROXY} />
src/bridge/views/Transfer.js+5−1
@@ -21,6 +21,7 @@ import { NETWORK_TYPES } from '../lib/network';
21import { isValidAddress } from '../lib/wallet';
21import { isValidAddress } from '../lib/wallet';
22import { withNetwork } from '../store/network';
22import { withNetwork } from '../store/network';
23import { compose } from '../lib/lib';
23import { compose } from '../lib/lib';
24+import { withPointCursor } from '../store/pointCursor';
24
25
25class Transfer extends React.Component {
26class Transfer extends React.Component {
26 constructor(props) {
27 constructor(props) {
@@ -132,4 +133,7 @@ class Transfer extends React.Component {
132 }
133 }
133}
134}
134
135
135−export default compose(withNetwork)(Transfer);
136+export default compose(
137+ withNetwork,
138+ withPointCursor
139+)(Transfer);
src/bridge/views/ViewPoint.js+5−1
@@ -9,6 +9,7 @@ import { InnerLabel, PointInput, ValidatedSigil } from '../components/Base';
9import { ROUTE_NAMES } from '../lib/routeNames';
9import { ROUTE_NAMES } from '../lib/routeNames';
10import { withHistory } from '../store/history';
10import { withHistory } from '../store/history';
11import { compose } from '../lib/lib';
11import { compose } from '../lib/lib';
12+import { withPointCursor } from '../store/pointCursor';
12
13
13class ViewPoint extends React.Component {
14class ViewPoint extends React.Component {
14 constructor(props) {
15 constructor(props) {
@@ -81,4 +82,7 @@ class ViewPoint extends React.Component {
81 }
82 }
82}
83}
83
84
84−export default compose(withHistory)(ViewPoint);
85+export default compose(
86+ withHistory,
87+ withPointCursor
88+)(ViewPoint);