@@ -1,272 +0,0 @@
1−import React, { useState, useEffect, useCallback, useMemo } from 'react';
2−import cn from 'classnames';
3−import { Grid, H4, HelpText } from 'indigo-react';
4−import { Just, Nothing } from 'folktale/maybe';
5−import * as ob from 'urbit-ob';
6−
7−import View from 'components/View';
8−import Tabs from 'components/Tabs';
9−import Crumbs from 'components/Crumbs';
10−import Sigil from 'components/Sigil';
11−import Blinky from 'components/Blinky';
12−import NavHeader from 'components/NavHeader';
13−import { ForwardButton } from 'components/Buttons';
14−
15−import { useLocalRouter } from 'lib/LocalRouter';
16−import useCurrentPointName from 'lib/useCurrentPointName';
17−import useCurrentPermissions from 'lib/useCurrentPermissions';
18−import * as need from 'lib/need';
19−
20−import { usePointCursor } from 'store/pointCursor';
21−import { usePointCache } from 'store/pointCache';
22−import Footer from 'components/Footer';
23−import { isGalaxy } from 'lib/utils/point';
24−
25−const NAMES = {
26− REQUESTS: 'REQUESTS',
27− ALL: 'ALL',
28−};
29−
30−const OPTIONS = [
31− { text: 'Requests', value: NAMES.REQUESTS },
32− { text: 'All', value: NAMES.ALL },
33−];
34−
35−const VIEWS = {
36− [NAMES.REQUESTS]: Tab,
37− [NAMES.ALL]: Tab,
38−};
39−
40−const PAGE_SIZE = 10;
41−
42−function Tab({ className, points, onAccept, onDecline, page, setPage }) {
43− const start = page * PAGE_SIZE;
44− const end = page * PAGE_SIZE + PAGE_SIZE;
45− const pointsCount = points.map(ps => ps.length).getOrElse(0);
46− const maxPage = Math.ceil(pointsCount / PAGE_SIZE) - 1;
47− const hasNext = page < maxPage;
48− const hasPrev = page > 0;
49− const _points = points.map(ps => ps.slice(start, end)).getOrElse([]);
50−
51− const onNext = useCallback(() => {
52− setPage(p => p + 1);
53− }, [setPage]);
54−
55− const onPrev = useCallback(() => {
56− setPage(p => p - 1);
57− }, [setPage]);
58−
59− if (Nothing.hasInstance(points)) {
60− return <Grid className={className}></Grid>;
61− }
62−
63− return (
64− <Grid className={cn('mt2', className)}>
65− {_points.length === 0 && (
66− <Grid.Item full as={HelpText} className="mt8 t-center">
67− {Just.hasInstance(points) ? (
68− 'No points to display'
69− ) : (
70− <>
71− <Blinky /> Loading...
72− </>
73− )}
74− </Grid.Item>
75− )}
76−
77− {_points.map(point => (
78− <Resident
79− key={point}
80− point={point}
81− onAccept={onAccept}
82− onDecline={onDecline}
83− />
84− ))}
85− <Grid.Item as={Footer}>
86− <Grid className="pb9">
87− {hasPrev && (
88− <Grid.Item
89− className="pointer underline mt4"
90− fourth={1}
91− onClick={onPrev}>
92− {'<-'}
93− </Grid.Item>
94− )}
95− {maxPage > 0 && (
96− <Grid.Item className="mt4 t-center gray3" cols={[4, 10]}>
97− <span className="black">Page {page + 1}</span> of {maxPage + 1}
98− </Grid.Item>
99− )}
100− {hasNext && (
101− <Grid.Item
102− className="pointer underline t-right mt4"
103− fourth={4}
104− onClick={onNext}>
105− {'->'}
106− </Grid.Item>
107− )}
108− </Grid>
109− </Grid.Item>
110− </Grid>
111− );
112−}
113−
114−function Resident({ point, onAccept, onDecline }) {
115− const patp = ob.patp(point);
116− const sigilSize = 50;
117−
118− const isRequest = onAccept && onDecline;
119−
120− return (
121− <>
122− <Grid.Item className="flex-row justify-center align-center" cols={[1, 3]}>
123− <div
124− style={{
125− display: 'inline-block',
126− height: `${sigilSize}px`,
127− width: `${sigilSize}px`,
128− }}>
129− <Sigil patp={patp} size={25} colors={['#FFFFFF', '#000000']} />
130− </div>
131− </Grid.Item>
132− <Grid.Item className="flex-row align-center mono" cols={[3, 7]}>
133− {patp}{' '}
134− </Grid.Item>
135− {isRequest && (
136− <>
137− <Grid.Item
138− className="flex-row-r align-center underline green3 pointer"
139− cols={[7, 10]}
140− onClick={() => onAccept(point)}>
141− Accept
142− </Grid.Item>
143− <Grid.Item
144− className="flex-row-r align-center underline red4 pointer"
145− cols={[10, 13]}
146− onClick={() => onDecline(point)}>
147− Decline
148− </Grid.Item>
149− </>
150− )}
151− <Grid.Divider />
152− </>
153− );
154−}
155−
156−export default function Residents() {
157− const { pop, push, names } = useLocalRouter();
158− const name = useCurrentPointName();
159−
160− const { pointCursor } = usePointCursor();
161− const point = need.point(pointCursor);
162− const { getResidents, syncResidents } = usePointCache();
163−
164− const goBack = useCallback(() => pop(), [pop]);
165− useEffect(() => {
166− syncResidents(point);
167− }, [syncResidents, point]);
168−
169− const { residents, requests } = getResidents(point);
170−
171− const [currentTab, _setCurrentTab] = useState(NAMES.ALL);
172− const [page, setPage] = useState(0);
173−
174− const goSenate = useCallback(() => push(names.SENATE), [push, names]);
175−
176− const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
177− names.ISSUE_CHILD,
178− push,
179− ]);
180−
181− const setCurrentTab = useCallback(
182− tab => {
183− setPage(0);
184− _setCurrentTab(tab);
185− },
186− [setPage, _setCurrentTab]
187− );
188−
189− const isRequests = useMemo(() => currentTab === NAMES.REQUESTS, [currentTab]);
190−
191− const _onAccept = useCallback(
192− adoptee =>
193− push(names.ADOPT, {
194− adoptee,
195− denied: false,
196− }),
197− [push, names]
198− );
199− const onAccept = isRequests && _onAccept;
200−
201− const _onDecline = useCallback(
202− adoptee =>
203− push(names.ADOPT, {
204− adoptee,
205− denied: true,
206− }),
207− [push, names]
208− );
209− const onDecline = isRequests && _onDecline;
210−
211− const points = isRequests ? requests : residents;
212− const { canSpawn, canVote, isStar } = useCurrentPermissions();
213−
214− const senateButton = (() => {
215− if (!isGalaxy(point)) {
216− return null;
217− }
218− return (
219− <>
220− <Grid.Item
221− full
222− as={ForwardButton}
223− disabled={!canVote}
224− onClick={goSenate}>
225− Senate
226− </Grid.Item>
227− <Grid.Divider />
228− </>
229− );
230− })();
231−
232− return (
233− <View pop={pop} inset>
234− <NavHeader>
235− <Crumbs
236− routes={[{ text: name, action: goBack }, { text: 'Residents' }]}
237− />
238− </NavHeader>
239− <Grid>
240− <Grid.Item full as={H4} className="mt4">
241− Residents
242− </Grid.Item>
243− <Grid.Divider />
244− <Grid.Item
245− full
246− as={ForwardButton}
247− disabled={!canSpawn}
248− onClick={goIssuePoint}>
249− Spawn {isStar ? ' Planets' : ' Stars'}
250− </Grid.Item>
251− <Grid.Divider />
252− {senateButton}
253− <Grid.Item
254− full
255− className="mt1"
256− as={Tabs}
257− // Tabs
258− views={VIEWS}
259− options={OPTIONS}
260− currentTab={currentTab}
261− onTabChange={setCurrentTab}
262− // Props for tab
263− points={points}
264− onAccept={onAccept}
265− onDecline={onDecline}
266− page={page}
267− setPage={setPage}
268− />
269− </Grid>
270− </View>
271− );
272−}