1import React, { useMemo } from 'react';
2import cn from 'classnames';
3import { Just, Nothing } from 'folktale/maybe';
4import ob from 'urbit-ob';
5import { Grid, Flex, Text } from 'indigo-react';
6import { times } from 'lodash';
8import * as need from 'lib/need';
9import usePointBirthday from 'lib/usePointBirthday';
13 INTERSTITIAL_CHARACTER,
16import Sigil from './Sigil';
17import MaybeSigil from './MaybeSigil';
18import usePermissionsForPoint from 'lib/usePermissionsForPoint';
19import { useWallet } from 'store/wallet';
20import { useSyncOwnedPoints } from 'lib/useSyncPoints';
22const TICKET_CHAR_LENGTH = 30;
23const TICKET = times(TICKET_CHAR_LENGTH, i =>
24 i % 2 === 0 ? LOADING_CHARACTER : INTERSTITIAL_CHARACTER
26const PENDING_TICKET = TICKET;
27const VALID_TICKET = `${TICKET} ◆`;
29const VISIBLE_ADDRESS_CHAR_COUNT = 20;
30const EMPTY_ADDRESS = times(VISIBLE_ADDRESS_CHAR_COUNT, () => '<').join('');
31const ADDRESS_BUFFER_CHARS = times(40, () => '<').join('');
33const INVERTED_COLORWAY = ['#fff', '#000'];
35const buildKeyType = permissions => {
36 if (permissions.isOwner) {
38 } else if (permissions.isManagementProxy) {
40 } else if (permissions.isSpawnProxy) {
42 } else if (permissions.isVotingProxy) {
44 } else if (permissions.isTransferProxy) {
50 * point is Maybe<number>
51 * ticket is null | boolean
52 * address is null | Maybe<string>
61 const birthday = usePointBirthday(point.getOrElse(null));
62 const visualBirthday = matchBlinkyDate(birthday);
64 const name = point.matchWith({
65 Nothing: () => Nothing(),
66 Just: p => Just(ob.patp(p.value)),
68 const visualName = name.matchWith({
73 const showTicket = ticket !== null;
74 const isValidTicket = !!ticket;
75 const visibleTicket = isValidTicket ? VALID_TICKET : PENDING_TICKET;
76 const visibleAddress = `${address.matchWith({
77 Nothing: () => EMPTY_ADDRESS,
78 Just: p => p.value.slice(0, VISIBLE_ADDRESS_CHAR_COUNT),
79 })}${ADDRESS_BUFFER_CHARS}`;
82 <Grid onClick={onClick} gap={4} className={cn('bg-black r8 p7', className)}>
83 <Grid.Item cols={[1, 4]}>
84 <MaybeSigil patp={name} size={64} />
86 <Grid.Item as={Flex} cols={[4, 13]} col justify="between">
87 <Flex.Item className="mono white f5 pb2">{visualName}</Flex.Item>
88 <Flex.Item as={Flex} col>
89 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
92 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
98 <Grid.Item full className="mv3" as={Flex} col>
99 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
104 className={cn('arial f6 f5-ns wrap', {
105 gray4: !isValidTicket,
106 green3: isValidTicket,
110 <Flex.Item as={Text} className="mono f6 f5-ns gray4 wrap">
119// TODO: Passport.Mini should probably accept Maybe<> for point
120// in order to display a pretty skeleton loading view
121// but that requires making usePermissionsForPoint accept a Maybe<point>
122// and I don't feel like that refactor is worth it right now, and the spec
123// doesn't call for it, hence the TODO
124Passport.Mini = function MiniPassport({ point, className, inverted, ...rest }) {
125 useSyncOwnedPoints([point]);
127 const { wallet } = useWallet();
128 const address = need.addressFromWallet(wallet);
130 const permissions = usePermissionsForPoint(address, point);
131 const keyType = buildKeyType(permissions);
132 const name = useMemo(() => ob.patp(point), [point]);
140 'bg-black': !inverted,
141 'bg-white b-gray4 b1': inverted,
146 <Grid.Item cols={[1, 4]}>
150 colors={inverted ? INVERTED_COLORWAY : undefined}
153 <Grid.Item as={Flex} cols={[4, 13]} col justify="between">
155 className={cn('mono f6 pb2', {
161 <Flex.Item as={Flex} col className={cn('mono f6 uppercase')}>
176 {keyType || <Blinky />}
184export default Passport;
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