@@ -1,6 +1,7 @@
1−import React from 'react';
1+import React, { useCallback } from 'react';
22import { Just, Nothing } from 'folktale/maybe';
33import { Grid, H5, H1, HelpText, LinkButton, Flex } from 'indigo-react';
4+import { get } from 'lodash';
45
56import { useHistory } from 'store/history';
67import { useWallet } from 'store/wallet';
@@ -8,34 +9,33 @@ import { usePointCache } from 'store/pointCache';
89import { usePointCursor } from 'store/pointCursor';
910
1011import * as need from 'lib/need';
11−import { ROUTE_NAMES } from 'lib/routeNames';
1212import { isZeroAddress, abbreviateAddress } from 'lib/wallet';
1313import useIsEclipticOwner from 'lib/useIsEclipticOwner';
1414import { useSyncKnownPoints } from 'lib/useSyncPoints';
1515
1616import View from 'components/View';
17−import FooterButton from 'components/FooterButton';
1817import Blinky from 'components/Blinky';
1918import Passport from 'components/Passport';
2019import useRejectedIncomingPointTransfers from 'lib/useRejectedIncomingPointTransfers';
2120import pluralize from 'lib/pluralize';
21+import Footer from 'components/Footer';
22+import { ForwardButton } from 'components/Buttons';
2223
23−const getFromMaybe = (obj, key, defaultValue) =>
24+const maybeGetResult = (obj, key, defaultValue) =>
2425 obj.matchWith({
2526 Nothing: () => defaultValue,
2627 Just: p =>
2728 p.value.matchWith({
28− Ok: r => r.value[key],
29+ Ok: r => get(r.value, key, defaultValue),
2930 Error: e => defaultValue,
3031 }),
3132 });
3233
33−const hasTransferProxy = (details, point) =>
34− !isZeroAddress(details.transferProxy);
34+const hasTransferProxy = details => !isZeroAddress(details.transferProxy);
3535
3636const PointList = function({ points, className, actions, ...rest }) {
3737 const { setPointCursor } = usePointCursor();
38− const history = useHistory();
38+ const { push, names } = useHistory();
3939
4040 return (
4141 <Grid gap={3} className={className}>
@@ -47,7 +47,7 @@ const PointList = function({ points, className, actions, ...rest }) {
4747 className="clickable"
4848 onClick={() => {
4949 setPointCursor(Just(point));
50− history.push(history.names.POINT);
50+ push(names.POINT);
5151 }}
5252 {...rest}
5353 />
@@ -79,7 +79,7 @@ function ActionButtons({ actions = [] }) {
7979
8080export default function Points() {
8181 const { wallet } = useWallet();
82− const history = useHistory();
82+ const { pop, push, names } = useHistory();
8383 const { setPointCursor } = usePointCursor();
8484 const { controlledPoints, getDetails } = usePointCache();
8585 const isEclipticOwner = useIsEclipticOwner();
@@ -92,15 +92,15 @@ export default function Points() {
9292
9393 const loading = Nothing.hasInstance(controlledPoints);
9494
95− const ownedPoints = getFromMaybe(controlledPoints, 'ownedPoints', []);
96− const incomingPoints = getFromMaybe(
95+ const ownedPoints = maybeGetResult(controlledPoints, 'ownedPoints', []);
96+ const incomingPoints = maybeGetResult(
9797 controlledPoints,
9898 'incomingPoints',
9999 []
100100 ).filter(point => !rejectedPoints.includes(point));
101− const managingPoints = getFromMaybe(controlledPoints, 'managingPoints', []);
102− const votingPoints = getFromMaybe(controlledPoints, 'votingPoints', []);
103− const spawningPoints = getFromMaybe(controlledPoints, 'spawningPoints', []);
101+ const managingPoints = maybeGetResult(controlledPoints, 'managingPoints', []);
102+ const votingPoints = maybeGetResult(controlledPoints, 'votingPoints', []);
103+ const spawningPoints = maybeGetResult(controlledPoints, 'spawningPoints', []);
104104 const outgoingPoints = ownedPoints.filter(point =>
105105 getDetails(point).matchWith({
106106 Nothing: () => false,
@@ -115,7 +115,8 @@ export default function Points() {
115115 ...spawningPoints,
116116 ];
117117
118− const isEmpty = incomingPoints.length === 0 && multipassPoints.length === 0;
118+ const displayEmptyState =
119+ !loading && incomingPoints.length === 0 && multipassPoints.length === 0;
119120
120121 // sync display details for known points
121122 useSyncKnownPoints([
@@ -126,9 +127,19 @@ export default function Points() {
126127 ...spawningPoints,
127128 ]);
128129
130+ const goCreateGalaxy = useCallback(() => push(names.CREATE_GALAXY), [
131+ names.CREATE_GALAXY,
132+ push,
133+ ]);
134+
135+ const goViewPoint = useCallback(() => push(names.VIEW_POINT), [
136+ names.VIEW_POINT,
137+ push,
138+ ]);
139+
129140 return (
130− <View>
131− <Grid className="mt6">
141+ <View pop={pop} inset>
142+ <Grid>
132143 <Grid.Item full as={H1} className="f6 mono gray4 mb4">
133144 {abbreviateAddress(address)}
134145 </Grid.Item>
@@ -139,7 +150,7 @@ export default function Points() {
139150 </Grid.Item>
140151 )}
141152
142− {isEmpty && (
153+ {displayEmptyState && (
143154 <Grid.Item full as={HelpText} className="mt8 t-center">
144155 No points to display. This wallet is not the owner or proxy for any
145156 points.
@@ -166,7 +177,7 @@ export default function Points() {
166177 text: 'Accept',
167178 onClick: () => {
168179 setPointCursor(Just(point));
169− history.push(history.names.ACCEPT_TRANSFER);
180+ push(names.ACCEPT_TRANSFER);
170181 },
171182 },
172183 {
@@ -204,7 +215,7 @@ export default function Points() {
204215 onClick: () => {
205216 setPointCursor(Just(point));
206217 // TODO: deep linking to fix this duplicate route
207− history.push(history.names.CANCEL_TRANSFER);
218+ push(names.CANCEL_TRANSFER);
208219 },
209220 },
210221 ]}
@@ -224,13 +235,30 @@ export default function Points() {
224235 </Grid.Item>
225236 )}
226237
227− {isEclipticOwner && (
228− <FooterButton
229− detail="You have the authority to create a new Galaxy."
230− onClick={() => history.push(ROUTE_NAMES.CREATE_GALAXY)}>
231− Create a galaxy
232− </FooterButton>
233− )}
238+ <Footer>
239+ <Grid>
240+ <Grid.Divider />
241+ {isEclipticOwner && (
242+ <>
243+ <Grid.Item
244+ full
245+ as={ForwardButton}
246+ detail="You have the authority to create a new Galaxy."
247+ onClick={goCreateGalaxy}>
248+ Create a galaxy
249+ </Grid.Item>
250+ <Grid.Divider />
251+ </>
252+ )}
253+ <Grid.Item
254+ full
255+ as={ForwardButton}
256+ detail="View a point"
257+ onClick={goViewPoint}>
258+ View a point
259+ </Grid.Item>
260+ </Grid>
261+ </Footer>
234262 </Grid>
235263 </View>
236264 );