1import React, { useState, useEffect, useCallback, useMemo } from 'react';
2import cn from 'classnames';
3import { Grid, H4, HelpText } from 'indigo-react';
4import { Just, Nothing } from 'folktale/maybe';
5import * as ob from 'urbit-ob';
7import View from 'components/View';
8import Tabs from 'components/Tabs';
9import Crumbs from 'components/Crumbs';
10import Sigil from 'components/Sigil';
11import Blinky from 'components/Blinky';
12import NavHeader from 'components/NavHeader';
13import { ForwardButton } from 'components/Buttons';
15import { useLocalRouter } from 'lib/LocalRouter';
16import useCurrentPointName from 'lib/useCurrentPointName';
17import useCurrentPermissions from 'lib/useCurrentPermissions';
18import * as need from 'lib/need';
20import { usePointCursor } from 'store/pointCursor';
21import { usePointCache } from 'store/pointCache';
22import Footer from 'components/Footer';
23import { isGalaxy } from 'lib/utils/point';
31 { text: 'Requests', value: NAMES.REQUESTS },
32 { text: 'All', value: NAMES.ALL },
36 [NAMES.REQUESTS]: Tab,
42function 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([]);
51 const onNext = useCallback(() => {
55 const onPrev = useCallback(() => {
59 if (Nothing.hasInstance(points)) {
60 return <Grid className={className}></Grid>;
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'
77 {_points.map(point => (
85 <Grid.Item as={Footer}>
86 <Grid className="pb9">
89 className="pointer underline mt4"
96 <Grid.Item className="mt4 t-center gray3" cols={[4, 10]}>
97 <span className="black">Page {page + 1}</span> of {maxPage + 1}
102 className="pointer underline t-right mt4"
114function Resident({ point, onAccept, onDecline }) {
115 const patp = ob.patp(point);
116 const sigilSize = 50;
118 const isRequest = onAccept && onDecline;
122 <Grid.Item className="flex-row justify-center align-center" cols={[1, 3]}>
125 display: 'inline-block',
126 height: `${sigilSize}px`,
127 width: `${sigilSize}px`,
129 <Sigil patp={patp} size={25} colors={['#FFFFFF', '#000000']} />
132 <Grid.Item className="flex-row align-center mono" cols={[3, 7]}>
138 className="flex-row-r align-center underline green3 pointer"
140 onClick={() => onAccept(point)}>
144 className="flex-row-r align-center underline red4 pointer"
146 onClick={() => onDecline(point)}>
156export default function Residents() {
157 const { pop, push, names } = useLocalRouter();
158 const name = useCurrentPointName();
160 const { pointCursor } = usePointCursor();
161 const point = need.point(pointCursor);
162 const { getResidents, syncResidents } = usePointCache();
164 const goBack = useCallback(() => pop(), [pop]);
166 syncResidents(point);
167 }, [syncResidents, point]);
169 const { residents, requests } = getResidents(point);
171 const [currentTab, _setCurrentTab] = useState(NAMES.ALL);
172 const [page, setPage] = useState(0);
174 const goSenate = useCallback(() => push(names.SENATE), [push, names]);
176 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
181 const setCurrentTab = useCallback(
186 [setPage, _setCurrentTab]
189 const isRequests = useMemo(() => currentTab === NAMES.REQUESTS, [currentTab]);
191 const _onAccept = useCallback(
199 const onAccept = isRequests && _onAccept;
201 const _onDecline = useCallback(
209 const onDecline = isRequests && _onDecline;
211 const points = isRequests ? requests : residents;
212 const { canSpawn, canVote, isStar } = useCurrentPermissions();
214 const senateButton = (() => {
215 if (!isGalaxy(point)) {
233 <View pop={pop} inset>
236 routes={[{ text: name, action: goBack }, { text: 'Residents' }]}
240 <Grid.Item full as={H4} className="mt4">
248 onClick={goIssuePoint}>
249 Spawn {isStar ? ' Planets' : ' Stars'}
260 currentTab={currentTab}
261 onTabChange={setCurrentTab}
265 onDecline={onDecline}
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list