on master help sign in
add adoption functionality
8227348Liam Fitzgerald
src/lib/routeNames.js+1
@@ -25,4 +25,5 @@ export const ROUTE_NAMES = {
25 HOSTING: Symbol('HOSTING'),
25 HOSTING: Symbol('HOSTING'),
26 URBIT_ID: Symbol('URBIT_ID'),
26 URBIT_ID: Symbol('URBIT_ID'),
27 RESIDENTS: Symbol('RESIDENTS'),
27 RESIDENTS: Symbol('RESIDENTS'),
28+ ADOPT: Symbol('ADOPT'),
28};
29};
src/lib/router.js+2
@@ -17,6 +17,7 @@ import CancelTransfer from 'views/CancelTransfer';
17import UrbitOS from 'views/UrbitOS';
17import UrbitOS from 'views/UrbitOS';
18import UrbitID from 'views/UrbitID';
18import UrbitID from 'views/UrbitID';
19import Residents from 'views/Residents';
19import Residents from 'views/Residents';
20+import Adopt from 'views/Adopt';
20
21
21import { ROUTE_NAMES } from './routeNames';
22import { ROUTE_NAMES } from './routeNames';
22
23
@@ -42,4 +43,5 @@ export const ROUTES = {
42 [ROUTE_NAMES.HOSTING]: Hosting,
43 [ROUTE_NAMES.HOSTING]: Hosting,
43 [ROUTE_NAMES.URBIT_ID]: UrbitID,
44 [ROUTE_NAMES.URBIT_ID]: UrbitID,
44 [ROUTE_NAMES.RESIDENTS]: Residents,
45 [ROUTE_NAMES.RESIDENTS]: Residents,
46+ [ROUTE_NAMES.ADOPT]: Adopt,
45};
47};
src/lib/useRouter.js+7−1
@@ -88,7 +88,13 @@ export default function useRouter({
88 const includes = useCallback(key => _includes(routes.map(r => r.key), key), [
88 const includes = useCallback(key => _includes(routes.map(r => r.key), key), [
89 routes,
89 routes,
90 ]);
90 ]);
91+ const data = useMemo(() => {
92+ try {
91− const data = useMemo(() => last(routes).data || NULL_DATA, [routes]);
93+ return last(routes).data || NULL_DATA;
94+ } catch (e) {
95+ debugger;
96+ }
97+ }, [routes]);
92 const Route = useMemo(() => views[peek().key], [views, peek]);
98 const Route = useMemo(() => views[peek().key], [views, peek]);
93
99
94 // Scroll to top of page with each route transition
100 // Scroll to top of page with each route transition
src/views/Adopt.jsnew file+89
@@ -0,0 +1,89 @@
1+import React, { useCallback, useEffect, useMemo } from 'react';
2+import { Grid } from 'indigo-react';
3+import * as ob from 'urbit-ob';
4+import { ecliptic } from 'azimuth-js';
5+
6+import View from 'components/View';
7+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
8+import ViewHeader from 'components/ViewHeader';
9+
10+import { useNetwork } from 'store/network';
11+import { usePointCache } from 'store/pointCache';
12+import { usePointCursor } from 'store/pointCursor';
13+import { useHistory } from 'store/history';
14+
15+import { GAS_LIMITS } from 'lib/constants';
16+import useEthereumTransaction from 'lib/useEthereumTransaction';
17+import * as need from 'lib/need';
18+
19+function useAdopt() {
20+ const { contracts } = useNetwork();
21+ const _contracts = need.contracts(contracts);
22+
23+ const { pointCursor } = usePointCursor();
24+ const point = need.point(pointCursor);
25+
26+ const { syncResidents } = usePointCache();
27+
28+ return useEthereumTransaction(
29+ useCallback(
30+ (adoptee, denied) =>
31+ denied
32+ ? ecliptic.reject(_contracts, adoptee)
33+ : ecliptic.adopt(_contracts, adoptee),
34+ [_contracts]
35+ ),
36+ useCallback(() => syncResidents(point), [syncResidents, point]),
37+ GAS_LIMITS.DEFAULT
38+ );
39+}
40+
41+export default function Adopt() {
42+ const { pop, data } = useHistory();
43+
44+ const { adoptee, denied } = data;
45+
46+ const patp = useMemo(() => ob.patp(adoptee), [adoptee]);
47+
48+ // const header = //useMemo(() => denied ? 'A Request' : 'Accept Request', [denied]);
49+ const { construct, bind, completed } = useAdopt();
50+
51+ const body = useMemo(
52+ () =>
53+ denied ? (
54+ <>
55+ {completed ? 'Denied' : 'Denying'} adoption request to{' '}
56+ <span className="mono">{patp}</span>
57+ </>
58+ ) : (
59+ <>
60+ {completed ? 'Approved' : 'Approving'} adoption request to{' '}
61+ <span className="mono">{patp}</span>
62+ </>
63+ ),
64+ [patp, denied, completed]
65+ );
66+
67+ useEffect(() => {
68+ construct(adoptee, denied);
69+ }, [construct, adoptee, denied]);
70+
71+ return (
72+ <View pop={() => pop()} inset>
73+ <Grid>
74+ <Grid.Item full as={ViewHeader} className="mb2">
75+ Adopt
76+ </Grid.Item>
77+ <Grid.Item full className="gray4 f5 mv2">
78+ {body}
79+ </Grid.Item>
80+ <Grid.Item
81+ full
82+ {...bind}
83+ as={InlineEthereumTransaction}
84+ onReturn={() => pop()}
85+ />
86+ </Grid>
87+ </View>
88+ );
89+}
src/views/Residents.js+32−13
@@ -1,5 +1,5 @@
1import React, { useState, useEffect, useCallback } from 'react';
1import React, { useState, useEffect, useCallback } from 'react';
2−import { Grid, H4 } from 'indigo-react';
2+import { Grid, H4, HelpText } from 'indigo-react';
3import { Nothing } from 'folktale/maybe';
3import { Nothing } from 'folktale/maybe';
4import * as ob from 'urbit-ob';
4import * as ob from 'urbit-ob';
5
5
@@ -7,6 +7,7 @@ import View from 'components/View';
7import Tabs from 'components/Tabs';
7import Tabs from 'components/Tabs';
8import Crumbs from 'components/Crumbs';
8import Crumbs from 'components/Crumbs';
9import Sigil from 'components/Sigil';
9import Sigil from 'components/Sigil';
10+import Blinky from 'components/Blinky';
10
11
11import { useLocalRouter } from 'lib/LocalRouter';
12import { useLocalRouter } from 'lib/LocalRouter';
12import useCurrentPointName from 'lib/useCurrentPointName';
13import useCurrentPointName from 'lib/useCurrentPointName';
@@ -30,13 +31,13 @@ const VIEWS = {
30 [NAMES.ALL]: AllResidents,
31 [NAMES.ALL]: AllResidents,
31};
32};
32
33
33−function Requests({ className, requests }) {
34+function Requests({ className, requests, onAccept, onDecline }) {
34− const onThing = () => {};
35−
36 if (Nothing.hasInstance(requests)) {
35 if (Nothing.hasInstance(requests)) {
37 return (
36 return (
38 <Grid className={className}>
37 <Grid className={className}>
38+ <Grid.Item full as={HelpText} className="mt8 t-center">
39+ <Blinky /> Loading...
39− <Grid.Item full>Loading...</Grid.Item>
40+ </Grid.Item>
40 </Grid>
41 </Grid>
41 );
42 );
42 }
43 }
@@ -49,8 +50,8 @@ function Requests({ className, requests }) {
49 <Resident
50 <Resident
50 key={point}
51 key={point}
51 point={point}
52 point={point}
52− onAccept={onThing}
53+ onAccept={onAccept}
53− onDecline={onThing}
54+ onDecline={onDecline}
54 />
55 />
55 ))}
56 ))}
56 </Grid>
57 </Grid>
@@ -81,13 +82,15 @@ function Resident({ point, onAccept, onDecline }) {
81 {isRequest && (
82 {isRequest && (
82 <>
83 <>
83 <Grid.Item
84 <Grid.Item
84− className="flex-row-r align-center underline green3"
85+ className="flex-row-r align-center underline green3 pointer"
85− cols={[7, 10]}>
86+ cols={[7, 10]}
87+ onClick={() => onAccept(point)}>
86 Accept
88 Accept
87 </Grid.Item>
89 </Grid.Item>
88 <Grid.Item
90 <Grid.Item
89− className="flex-row-r align-center underline red4"
91+ className="flex-row-r align-center underline red4 pointer"
90− cols={[10, 13]}>
92+ cols={[10, 13]}
93+ onClick={() => onDecline(point)}>
91 Decline
94 Decline
92 </Grid.Item>
95 </Grid.Item>
93 </>
96 </>
@@ -118,7 +121,7 @@ function AllResidents({ className, residents }) {
118}
121}
119
122
120export default function Residents() {
123export default function Residents() {
121− const { pop } = useLocalRouter();
124+ const { pop, push, names } = useLocalRouter();
122 const name = useCurrentPointName();
125 const name = useCurrentPointName();
123
126
124 const { pointCursor } = usePointCursor();
127 const { pointCursor } = usePointCursor();
@@ -133,8 +136,22 @@ export default function Residents() {
133
136
134 const [currentTab, setCurrentTab] = useState(NAMES.ALL);
137 const [currentTab, setCurrentTab] = useState(NAMES.ALL);
135
138
139+ const onAccept = useCallback(adoptee =>
140+ push(names.ADOPT, {
141+ adoptee,
142+ denied: false,
143+ })
144+ );
145+
146+ const onDecline = useCallback(adoptee =>
147+ push(names.ADOPT, {
148+ adoptee,
149+ denied: true,
150+ })
151+ );
152+
136 return (
153 return (
137− <View pop={pop}>
154+ <View pop={pop} inset>
138 <Grid>
155 <Grid>
139 <Grid.Item
156 <Grid.Item
140 full
157 full
@@ -156,6 +173,8 @@ export default function Residents() {
156 // Props for tab
173 // Props for tab
157 residents={residents}
174 residents={residents}
158 requests={requests}
175 requests={requests}
176+ onAccept={onAccept}
177+ onDecline={onDecline}
159 />
178 />
160 </Grid>
179 </Grid>
161 </View>
180 </View>