on master help sign in
cache useResidents data
68e8ca5Liam Fitzgerald
src/lib/useResidents.jsdeleted−54
@@ -1,54 +0,0 @@
1−import { useState, useCallback, useEffect } from 'react';
2−import { Just, Nothing } from 'folktale/maybe';
3−
4−import { azimuth } from 'azimuth-js';
5−
6−import { useNetwork } from 'store/network';
7−
8−import useCurrentPermissions from 'lib/useCurrentPermissions';
9−import * as need from 'lib/need';
10−
11−export function useResidents(point) {
12− const [residents, setResidents] = useState(Nothing());
13− const [residentCount, setResidentCount] = useState(Nothing());
14−
15− const { isParent } = useCurrentPermissions();
16− const { contracts } = useNetwork();
17− const _contracts = need.contracts(contracts);
18−
19− const syncResidentCount = useCallback(async () => {
20− if (!isParent) {
21− return;
22− }
23− const count = await azimuth.getSponsoringCount(_contracts, point);
24− setResidentCount(Just(count.toNumber()));
25− }, [isParent, setResidentCount, point, _contracts]);
26−
27− const syncResidents = useCallback(async () => {
28− if (Just.hasInstance(residents) || !isParent) {
29− return;
30− }
31− // Galaxies sponsor themselves
32− const children = (await azimuth.getSponsoring(_contracts, point)).filter(
33− p => p !== point
34− );
35−
36− setResidents(Just(children));
37− }, [residents, isParent, setResidents, point, _contracts]);
38−
39− const [requests, setRequests] = useState(Nothing);
40− const syncRequests = useCallback(async () => {
41− const reqs = await azimuth.getEscapeRequests(_contracts, point);
42− setRequests(Just(reqs));
43− }, [_contracts, point]);
44−
45− useEffect(() => {
46− syncResidentCount();
47− }, [syncResidentCount]);
48−
49− // useEffect(() => {
50− // syncRequests();
51− // });
52−
53− return { residents, residentCount, syncResidents, requests, syncRequests };
54−}
src/store/lib/usePointStore.js+12−1
@@ -6,6 +6,7 @@ import useRekeyDateStore from './useRekeyDateStore';
6import useInvitesStore from './useInvitesStore';
6import useInvitesStore from './useInvitesStore';
7import useControlledPointsStore from './useControlledPointsStore';
7import useControlledPointsStore from './useControlledPointsStore';
8import useEclipticOwnerStore from './useEclipticOwnerStore';
8import useEclipticOwnerStore from './useEclipticOwnerStore';
9+import useResidents from './useResidentsStore';
9
10
10export default function usePointStore() {
11export default function usePointStore() {
11 const { syncDetails, ...details } = useDetailsStore();
12 const { syncDetails, ...details } = useDetailsStore();
@@ -16,6 +17,7 @@ export default function usePointStore() {
16 syncControlledPoints,
17 syncControlledPoints,
17 ...controlledPoints
18 ...controlledPoints
18 } = useControlledPointsStore();
19 } = useControlledPointsStore();
20+ const { syncResidents, syncResidentCount, ...residents } = useResidents();
19 const ecliptic = useEclipticOwnerStore();
21 const ecliptic = useEclipticOwnerStore();
20
22
21 // sync all of the on-chain info required to display a known point
23 // sync all of the on-chain info required to display a known point
@@ -34,10 +36,17 @@ export default function usePointStore() {
34 syncForeignPoint(point),
36 syncForeignPoint(point),
35 syncKnownPoint(point),
37 syncKnownPoint(point),
36 //
38 //
39+ syncResidentCount(point),
37 syncDetails(point),
40 syncDetails(point),
38 syncInvites(point),
41 syncInvites(point),
39 ]),
42 ]),
43+ [
40− [syncForeignPoint, syncKnownPoint, syncDetails, syncInvites]
44+ syncForeignPoint,
45+ syncKnownPoint,
46+ syncDetails,
47+ syncInvites,
48+ syncResidentCount,
49+ ]
41 );
50 );
42
51
43 return {
52 return {
@@ -47,6 +56,7 @@ export default function usePointStore() {
47 ...invites,
56 ...invites,
48 ...controlledPoints,
57 ...controlledPoints,
49 ...ecliptic,
58 ...ecliptic,
59+ ...residents,
50 syncDetails,
60 syncDetails,
51 syncRekeyDate,
61 syncRekeyDate,
52 syncInvites,
62 syncInvites,
@@ -54,5 +64,6 @@ export default function usePointStore() {
54 syncKnownPoint,
64 syncKnownPoint,
55 syncOwnedPoint,
65 syncOwnedPoint,
56 syncForeignPoint,
66 syncForeignPoint,
67+ syncResidents,
57 };
68 };
58}
69}
src/store/lib/useResidentsStore.jsnew file+83
@@ -0,0 +1,83 @@
1+import { useState, useCallback, useEffect } from 'react';
2+import { Just, Nothing } from 'folktale/maybe';
3+
4+import { azimuth } from 'azimuth-js';
5+
6+import { useNetwork } from 'store/network';
7+
8+import useCurrentPermissions from 'lib/useCurrentPermissions';
9+import * as need from 'lib/need';
10+
11+const emptyCacheEntry = {
12+ residentCount: Nothing(),
13+ requestCount: Nothing(),
14+ residents: Nothing(),
15+ requests: Nothing(),
16+};
17+
18+export default function useResidents() {
19+ const [residentCache, _setResidentCache] = useState({});
20+
21+ const addToResidentCache = useCallback(
22+ (point, entry) =>
23+ _setResidentCache(cache => ({ ...cache, [point]: entry })),
24+ [_setResidentCache]
25+ );
26+
27+ const getResidents = useCallback(
28+ point => residentCache[point] || emptyCacheEntry,
29+ [residentCache]
30+ );
31+
32+ const { contracts, web3 } = useNetwork();
33+ const _contracts = need.contracts(contracts);
34+
35+ const syncResidentCount = useCallback(
36+ async point => {
37+ // Do nothing if we've already fetched in full
38+ if (Just.hasInstance(getResidents(point).residents)) {
39+ return;
40+ }
41+
42+ const isGalaxy = azimuth.getPointSize(point) === azimuth.PointSize.Galaxy;
43+ const [residentCount, requestCount] = await Promise.all([
44+ azimuth.getSponsoringCount(_contracts, point),
45+ azimuth.getEscapeRequestsCount(_contracts, point),
46+ ]);
47+
48+ const _residentCount = isGalaxy
49+ ? residentCount.toNumber() - 1
50+ : residentCount.toNumber();
51+
52+ addToResidentCache(point, {
53+ residentCount: Just(_residentCount),
54+ requestCount: Just(requestCount.toNumber()),
55+ residents: Nothing(),
56+ requests: Nothing(),
57+ });
58+ },
59+ [addToResidentCache, _contracts, getResidents]
60+ );
61+
62+ const syncResidents = useCallback(
63+ async point => {
64+ // Galaxies sponsor themselves
65+ const [residents, requests] = await Promise.all([
66+ azimuth.getSponsoring(_contracts, point),
67+ azimuth.getEscapeRequests(_contracts, point),
68+ ]);
69+
70+ const _residents = residents.filter(r => r !== point);
71+
72+ addToResidentCache(point, {
73+ residentCount: Just(_residents.length),
74+ requestCount: Just(requests.length),
75+ residents: Just(_residents),
76+ requests: Just(requests),
77+ });
78+ },
79+ [addToResidentCache, _contracts]
80+ );
81+
82+ return { getResidents, syncResidentCount, syncResidents };
83+}
src/views/Point.js+16−5
@@ -25,9 +25,9 @@ import useInvites from 'lib/useInvites';
25import { useSyncOwnedPoints } from 'lib/useSyncPoints';
25import { useSyncOwnedPoints } from 'lib/useSyncPoints';
26import useCurrentPermissions from 'lib/useCurrentPermissions';
26import useCurrentPermissions from 'lib/useCurrentPermissions';
27import { useLocalRouter } from 'lib/LocalRouter';
27import { useLocalRouter } from 'lib/LocalRouter';
28−import { useResidents } from 'lib/useResidents';
29
28
30import Inviter from 'views/Invite/Inviter';
29import Inviter from 'views/Invite/Inviter';
30+import { usePointCache } from 'store/pointCache';
31
31
32export default function Point() {
32export default function Point() {
33 const { pop, push, names } = useLocalRouter();
33 const { pop, push, names } = useLocalRouter();
@@ -36,7 +36,9 @@ export default function Point() {
36 const { wallet } = useWallet();
36 const { wallet } = useWallet();
37 const point = need.point(pointCursor);
37 const point = need.point(pointCursor);
38
38
39+ const { getResidents } = usePointCache();
40+
39− const { residentCount } = useResidents(point);
41+ const { residentCount, requestCount } = getResidents(point);
40
42
41 const {
43 const {
42 isParent,
44 isParent,
@@ -214,7 +216,7 @@ export default function Point() {
214 );
216 );
215 });
217 });
216
218
217− console.log(residentCount);
219+ const _requestCount = requestCount.getOrElse(0);
218
220
219 return (
221 return (
220 <View pop={pop} inset>
222 <View pop={pop} inset>
@@ -226,12 +228,21 @@ export default function Point() {
226 />
228 />
227 <Grid gap={3}>
229 <Grid gap={3}>
228 {isParent && (
230 {isParent && (
231+ <Grid.Item
232+ full
233+ as={Flex}
234+ justify="between"
229− <Grid.Item full as={Flex} justify="between" onClick={goResidents}>
235+ onClick={goResidents}
236+ className="mv1">
230 <Flex.Item>
237 <Flex.Item>
231 Residents{' '}
238 Residents{' '}
232 <span className="gray3">{matchBlinky(residentCount)}</span>
239 <span className="gray3">{matchBlinky(residentCount)}</span>
233 </Flex.Item>
240 </Flex.Item>
241+ {_requestCount !== 0 && (
242+ <Flex.Item className="f7 bg-gray2 h3 pv1 ph2 br-full r-full text-center">
243+ {_requestCount} PENDING
234− <Flex.Item>N/A</Flex.Item>
244+ </Flex.Item>
245+ )}
235 </Grid.Item>
246 </Grid.Item>
236 )}
247 )}
237 {isPlanet && hasInvites && <InviteForm />}
248 {isPlanet && hasInvites && <InviteForm />}
src/views/Residents.js+20−21
@@ -10,10 +10,10 @@ import Sigil from 'components/Sigil';
10
10
11import { useLocalRouter } from 'lib/LocalRouter';
11import { useLocalRouter } from 'lib/LocalRouter';
12import useCurrentPointName from 'lib/useCurrentPointName';
12import useCurrentPointName from 'lib/useCurrentPointName';
13−import { useResidents } from 'lib/useResidents';
14import * as need from 'lib/need';
13import * as need from 'lib/need';
15
14
16import { usePointCursor } from 'store/pointCursor';
15import { usePointCursor } from 'store/pointCursor';
16+import { usePointCache } from 'store/pointCache';
17
17
18const NAMES = {
18const NAMES = {
19 REQUESTS: 'REQUESTS',
19 REQUESTS: 'REQUESTS',
@@ -30,14 +30,8 @@ const VIEWS = {
30 [NAMES.ALL]: AllResidents,
30 [NAMES.ALL]: AllResidents,
31};
31};
32
32
33−function Requests({ className }) {
33+function Requests({ className, requests }) {
34 const onThing = () => {};
34 const onThing = () => {};
35− const { pointCursor } = usePointCursor();
36− const point = need.point(pointCursor);
37− const { requests, syncRequests } = useResidents(point);
38− useEffect(() => {
39− syncRequests();
40− }, [syncRequests]);
41
35
42 if (Nothing.hasInstance(requests)) {
36 if (Nothing.hasInstance(requests)) {
43 return (
37 return (
@@ -86,11 +80,13 @@ function Resident({ point, onAccept, onDecline }) {
86 </Grid.Item>
80 </Grid.Item>
87 {isRequest && (
81 {isRequest && (
88 <>
82 <>
83+ <Grid.Item
89− <Grid.Item className="flex-row align-center underline" cols={[7, 10]}>
84+ className="flex-row-r align-center underline green3"
85+ cols={[7, 10]}>
90 Accept
86 Accept
91 </Grid.Item>
87 </Grid.Item>
92 <Grid.Item
88 <Grid.Item
93− className="flex-row align-center underline"
89+ className="flex-row-r align-center underline red4"
94 cols={[10, 13]}>
90 cols={[10, 13]}>
95 Decline
91 Decline
96 </Grid.Item>
92 </Grid.Item>
@@ -101,14 +97,7 @@ function Resident({ point, onAccept, onDecline }) {
101 );
97 );
102}
98}
103
99
104−function AllResidents({ className }) {
100+function AllResidents({ className, residents }) {
105− const { pointCursor } = usePointCursor();
106− const point = need.point(pointCursor);
107− const { syncResidents, residents } = useResidents(point);
108− useEffect(() => {
109− syncResidents();
110− }, [syncResidents]);
111−
112 if (Nothing.hasInstance(residents)) {
101 if (Nothing.hasInstance(residents)) {
113 return (
102 return (
114 <Grid className={className}>
103 <Grid className={className}>
@@ -132,11 +121,17 @@ export default function Residents() {
132 const { pop } = useLocalRouter();
121 const { pop } = useLocalRouter();
133 const name = useCurrentPointName();
122 const name = useCurrentPointName();
134
123
135− // const { pointCursor } = usePointCursor();
124+ const { pointCursor } = usePointCursor();
125+ const point = need.point(pointCursor);
126+ const { getResidents, syncResidents } = usePointCache();
136
127
137− const [currentTab, setCurrentTab] = useState(NAMES.ALL);
128+ useEffect(() => {
129+ syncResidents(point);
130+ }, [syncResidents, point]);
131+
132+ const { residents, requests } = getResidents(point);
138
133
139− const [req, selectRequest] = useState();
134+ const [currentTab, setCurrentTab] = useState(NAMES.ALL);
140
135
141 return (
136 return (
142 <View pop={pop}>
137 <View pop={pop}>
@@ -153,10 +148,14 @@ export default function Residents() {
153 full
148 full
154 className="mt1"
149 className="mt1"
155 as={Tabs}
150 as={Tabs}
151+ // Tabs
156 views={VIEWS}
152 views={VIEWS}
157 options={OPTIONS}
153 options={OPTIONS}
158 currentTab={currentTab}
154 currentTab={currentTab}
159 onTabChange={setCurrentTab}
155 onTabChange={setCurrentTab}
156+ // Props for tab
157+ residents={residents}
158+ requests={requests}
160 />
159 />
161 </Grid>
160 </Grid>
162 </View>
161 </View>