on master help sign in
feat: add accept/cancel/reject views
33c8b8dMatt Condon (shrugs)
src/lib/routeNames.js+1−6
@@ -14,18 +14,13 @@ export const ROUTE_NAMES = {
14 PERMISSIONS: Symbol('PERMISSIONS'),
14 PERMISSIONS: Symbol('PERMISSIONS'),
15 //
15 //
16 ACCEPT_TRANSFER: Symbol('ACCEPT_TRANSFER'),
16 ACCEPT_TRANSFER: Symbol('ACCEPT_TRANSFER'),
17+ REJECT_TRANSFER: Symbol('REJECT_TRANSFER'),
17 CANCEL_TRANSFER: Symbol('CANCEL_TRANSFER'),
18 CANCEL_TRANSFER: Symbol('CANCEL_TRANSFER'),
18 LANDING: Symbol('LANDING'),
19 LANDING: Symbol('LANDING'),
19 VIEW_POINT: Symbol('VIEW_POINT'),
20 VIEW_POINT: Symbol('VIEW_POINT'),
20 POINTS: Symbol('POINTS'),
21 POINTS: Symbol('POINTS'),
21 POINT: Symbol('POINT'),
22 POINT: Symbol('POINT'),
22− SET_MANAGEMENT_PROXY: Symbol('SET_MANAGEMENT_PROXY'),
23− SET_SPAWN_PROXY: Symbol('SET_SPAWN_PROXY'),
24− SET_TRANSFER_PROXY: Symbol('SET_TRANSFER_PROXY'),
25 CREATE_GALAXY: Symbol('CREATE_GALAXY'),
23 CREATE_GALAXY: Symbol('CREATE_GALAXY'),
26 ISSUE_CHILD: Symbol('ISSUE_CHILD'),
24 ISSUE_CHILD: Symbol('ISSUE_CHILD'),
27− SET_KEYS: Symbol('SET_KEYS'),
28− TRANSFER: Symbol('TRANSFER'),
29− GEN_KEYFILE: Symbol('GEN_KEYFILE'),
30 PARTY_SET_POOL_SIZE: Symbol('PARTY_SET_POOL_SIZE'),
25 PARTY_SET_POOL_SIZE: Symbol('PARTY_SET_POOL_SIZE'),
31};
26};
src/lib/router.js+8−1
@@ -12,6 +12,9 @@ import Invite from 'views/Invite';
12import Activate from 'views/Activate';
12import Activate from 'views/Activate';
13
13
14import PartySetPoolSize from 'views/Party/PartySetPoolSize';
14import PartySetPoolSize from 'views/Party/PartySetPoolSize';
15+import AcceptTransfer from 'views/AcceptTransfer';
16+import CancelTransfer from 'views/CancelTransfer';
17+import RejectTransfer from 'views/RejectTransfer';
15
18
16import { ROUTE_NAMES } from './routeNames';
19import { ROUTE_NAMES } from './routeNames';
17
20
@@ -25,8 +28,12 @@ export const ROUTES = {
25 [ROUTE_NAMES.POINT]: Point,
28 [ROUTE_NAMES.POINT]: Point,
26 [ROUTE_NAMES.CREATE_GALAXY]: CreateGalaxy,
29 [ROUTE_NAMES.CREATE_GALAXY]: CreateGalaxy,
27 [ROUTE_NAMES.ISSUE_CHILD]: IssueChild,
30 [ROUTE_NAMES.ISSUE_CHILD]: IssueChild,
28− [ROUTE_NAMES.PARTY_SET_POOL_SIZE]: PartySetPoolSize,
29 [ROUTE_NAMES.INVITE]: Invite,
31 [ROUTE_NAMES.INVITE]: Invite,
30 [ROUTE_NAMES.ADMIN]: Admin,
32 [ROUTE_NAMES.ADMIN]: Admin,
31 // TODO: nest this route under the Party.js router
33 // TODO: nest this route under the Party.js router
34+ [ROUTE_NAMES.PARTY_SET_POOL_SIZE]: PartySetPoolSize,
35+ [ROUTE_NAMES.ACCEPT_TRANSFER]: AcceptTransfer,
36+ [ROUTE_NAMES.REJECT_TRANSFER]: RejectTransfer,
37+ // TODO: replace this with deep link to AdminCancelTransfer
38+ [ROUTE_NAMES.CANCEL_TRANSFER]: CancelTransfer,
32};
39};
src/views/AcceptTransfer.jsnew file+96
@@ -0,0 +1,96 @@
1+import React, { useCallback } from 'react';
2+import cn from 'classnames';
3+import { Grid, Text } from 'indigo-react';
4+import * as azimuth from 'azimuth-js';
5+
6+import { useNetwork } from 'store/network';
7+import { usePointCursor } from 'store/pointCursor';
8+import { usePointCache } from 'store/pointCache';
9+import { useHistory } from 'store/history';
10+import { useWallet } from 'store/wallet';
11+
12+import * as need from 'lib/need';
13+import useCurrentPointName from 'lib/useCurrentPointName';
14+import useEthereumTransaction from 'lib/useEthereumTransaction';
15+import { GAS_LIMITS } from 'lib/constants';
16+import useLifecycle from 'lib/useLifecycle';
17+
18+import ViewHeader from 'components/ViewHeader';
19+import MiniBackButton from 'components/MiniBackButton';
20+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
21+import View from 'components/View';
22+
23+function useAcceptTransfer() {
24+ const { contracts } = useNetwork();
25+ const { pointCursor } = usePointCursor();
26+ const { syncOwnedPoint, syncControlledPoints } = usePointCache();
27+ const { wallet } = useWallet();
28+
29+ const _contracts = need.contracts(contracts);
30+ const _point = need.point(pointCursor);
31+ const _address = need.addressFromWallet(wallet);
32+
33+ const { construct, ...rest } = useEthereumTransaction(
34+ useCallback(
35+ () =>
36+ azimuth.ecliptic.transferPoint(
37+ _contracts,
38+ _point,
39+ _address,
40+ /* reset */ true
41+ ),
42+ [_contracts, _point, _address]
43+ ),
44+ useCallback(
45+ () => Promise.all([syncOwnedPoint(_point), syncControlledPoints()]),
46+ [_point, syncControlledPoints, syncOwnedPoint]
47+ ),
48+ GAS_LIMITS.TRANSFER
49+ );
50+
51+ useLifecycle(() => {
52+ construct();
53+ });
54+
55+ return {
56+ ...rest,
57+ };
58+}
59+
60+export default function AcceptTransfer() {
61+ const { pop } = useHistory();
62+
63+ const name = useCurrentPointName();
64+
65+ const { completed, bind } = useAcceptTransfer();
66+
67+ return (
68+ <View inset>
69+ <Grid>
70+ <Grid.Item full as={MiniBackButton} onClick={() => pop()} />
71+
72+ <Grid.Item full as={ViewHeader}>
73+ Accept Transfer
74+ </Grid.Item>
75+
76+ <Grid.Item
77+ full
78+ as={Text}
79+ className={cn('f5', {
80+ green3: completed,
81+ })}>
82+ {completed
83+ ? `${name} has been accepted.`
84+ : `Accept the incoming transfer of ${name}.`}
85+ </Grid.Item>
86+
87+ <Grid.Item
88+ full
89+ as={InlineEthereumTransaction}
90+ {...bind}
91+ onReturn={() => pop()}
92+ />
93+ </Grid>
94+ </View>
95+ );
96+}
src/views/CancelTransfer.jsnew file+21
@@ -0,0 +1,21 @@
1+import React from 'react';
2+
3+import View from 'components/View';
4+
5+import AdminCancelTransfer from './Admin/AdminCancelTransfer';
6+import { LocalRouterProvider } from 'lib/LocalRouter';
7+import { useHistory } from 'store/history';
8+
9+export default function CancelTransfer() {
10+ const history = useHistory();
11+
12+ return (
13+ // TODO: this is a hack so AdminCancelTransfer works unmodified
14+ // TODO: consolidate history & 'local' router providers
15+ <LocalRouterProvider value={history}>
16+ <View inset>
17+ <AdminCancelTransfer />
18+ </View>
19+ </LocalRouterProvider>
20+ );
21+}
src/views/Points.js+15−11
@@ -49,7 +49,9 @@ const PointList = function({ points, className, actions, ...rest }) {
49 }}
49 }}
50 {...rest}
50 {...rest}
51 />
51 />
52+ {actions && (
52− <Flex.Item className="mt2">{actions}</Flex.Item>
53+ <Flex.Item className="mt2">{actions(point, i)}</Flex.Item>
54+ )}
53 </Flex>
55 </Flex>
54 </Grid.Item>
56 </Grid.Item>
55 ))}
57 ))}
@@ -76,6 +78,7 @@ function ActionButtons({ actions = [] }) {
76export default function Points() {
78export default function Points() {
77 const { wallet } = useWallet();
79 const { wallet } = useWallet();
78 const history = useHistory();
80 const history = useHistory();
81+ const { setPointCursor } = usePointCursor();
79 const { controlledPoints, getDetails } = usePointCache();
82 const { controlledPoints, getDetails } = usePointCache();
80 const isEclipticOwner = useIsEclipticOwner();
83 const isEclipticOwner = useIsEclipticOwner();
81
84
@@ -133,26 +136,26 @@ export default function Points() {
133 full
136 full
134 as={PointList}
137 as={PointList}
135 points={incomingPoints}
138 points={incomingPoints}
136− actions={
139+ actions={(point, i) => (
137 <ActionButtons
140 <ActionButtons
138 actions={[
141 actions={[
139 {
142 {
140 text: 'Accept',
143 text: 'Accept',
141 onClick: () => {
144 onClick: () => {
142− // TODO: accept
145+ setPointCursor(Just(point));
143− console.log('accept');
146+ history.push(history.names.ACCEPT_TRANSFER);
144 },
147 },
145 },
148 },
146 {
149 {
147 text: 'Reject',
150 text: 'Reject',
148 onClick: () => {
151 onClick: () => {
149− // TODO: reject
152+ setPointCursor(Just(point));
150− console.log('reject');
153+ history.push(history.names.REJECT_TRANSFER);
151 },
154 },
152 },
155 },
153 ]}
156 ]}
154 />
157 />
155− }
158+ )}
156 inverted
159 inverted
157 />
160 />
158 </Grid.Item>
161 </Grid.Item>
@@ -167,19 +170,20 @@ export default function Points() {
167 full
170 full
168 as={PointList}
171 as={PointList}
169 points={outgoingPoints}
172 points={outgoingPoints}
170− actions={
173+ actions={(point, i) => (
171 <ActionButtons
174 <ActionButtons
172 actions={[
175 actions={[
173 {
176 {
174 text: 'Cancel',
177 text: 'Cancel',
175 onClick: () => {
178 onClick: () => {
176− // TODO: cancel
179+ setPointCursor(Just(point));
177− console.log('cancel');
180+ // TODO: deep linking to fix this duplicate route
181+ history.push(history.names.CANCEL_TRANSFER);
178 },
182 },
179 },
183 },
180 ]}
184 ]}
181 />
185 />
182− }
186+ )}
183 inverted
187 inverted
184 />
188 />
185 </Grid.Item>
189 </Grid.Item>
src/views/RejectTransfer.jsnew file+93
@@ -0,0 +1,93 @@
1+import React, { useCallback } from 'react';
2+import cn from 'classnames';
3+import { Grid, Text } from 'indigo-react';
4+import * as azimuth from 'azimuth-js';
5+
6+import { useNetwork } from 'store/network';
7+import { usePointCursor } from 'store/pointCursor';
8+import { usePointCache } from 'store/pointCache';
9+import { useHistory } from 'store/history';
10+
11+import * as need from 'lib/need';
12+import useCurrentPointName from 'lib/useCurrentPointName';
13+import useEthereumTransaction from 'lib/useEthereumTransaction';
14+import { GAS_LIMITS } from 'lib/constants';
15+import { ETH_ZERO_ADDR } from 'lib/wallet';
16+import useLifecycle from 'lib/useLifecycle';
17+
18+import ViewHeader from 'components/ViewHeader';
19+import MiniBackButton from 'components/MiniBackButton';
20+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
21+import View from 'components/View';
22+
23+function useRejectTransfer() {
24+ const { contracts } = useNetwork();
25+ const { pointCursor } = usePointCursor();
26+ const { syncDetails, syncControlledPoints } = usePointCache();
27+
28+ const _contracts = need.contracts(contracts);
29+ const _point = need.point(pointCursor);
30+
31+ const { construct, ...rest } = useEthereumTransaction(
32+ useCallback(
33+ () =>
34+ azimuth.ecliptic.setTransferProxy(_contracts, _point, ETH_ZERO_ADDR),
35+ [_contracts, _point]
36+ ),
37+ useCallback(
38+ () => Promise.all([syncDetails(_point), syncControlledPoints()]),
39+ [_point, syncControlledPoints, syncDetails]
40+ ),
41+ GAS_LIMITS.SET_PROXY
42+ );
43+
44+ useLifecycle(() => {
45+ construct();
46+ });
47+
48+ return {
49+ ...rest,
50+ };
51+}
52+
53+export default function RejectTransfer() {
54+ const { pop } = useHistory();
55+ const { getDetails } = usePointCache();
56+ const { pointCursor } = usePointCursor();
57+ const _point = need.point(pointCursor);
58+
59+ const name = useCurrentPointName();
60+ const _details = need.details(getDetails(_point));
61+
62+ const { completed, bind } = useRejectTransfer();
63+
64+ return (
65+ <View inset>
66+ <Grid>
67+ <Grid.Item full as={MiniBackButton} onClick={() => pop()} />
68+
69+ <Grid.Item full as={ViewHeader}>
70+ Reject Incoming Transfer
71+ </Grid.Item>
72+
73+ <Grid.Item
74+ full
75+ as={Text}
76+ className={cn('f5', {
77+ green3: completed,
78+ })}>
79+ {completed
80+ ? `The incoming transfer of ${name} has been rejected.`
81+ : `Reject the incoming transfer of ${name} from ${_details.owner}.`}
82+ </Grid.Item>
83+
84+ <Grid.Item
85+ full
86+ as={InlineEthereumTransaction}
87+ {...bind}
88+ onReturn={() => pop()}
89+ />
90+ </Grid>
91+ </View>
92+ );
93+}