1import React, { useMemo } from 'react';
2import cn from 'classnames';
3import { Just, Nothing } from 'folktale/maybe';
4import * as 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>
54function Passport({ point, className, ticket = null, address = Nothing() }) {
55 const birthday = usePointBirthday(point.getOrElse(null));
56 const visualBirthday = matchBlinkyDate(birthday);
58 const name = point.matchWith({
59 Nothing: () => Nothing(),
60 Just: p => Just(ob.patp(p.value)),
62 const visualName = name.matchWith({
67 const showTicket = ticket !== null;
68 const isValidTicket = !!ticket;
69 const visibleTicket = isValidTicket ? VALID_TICKET : PENDING_TICKET;
70 const visibleAddress = `${address.matchWith({
71 Nothing: () => EMPTY_ADDRESS,
72 Just: p => p.value.slice(0, VISIBLE_ADDRESS_CHAR_COUNT),
73 })}${ADDRESS_BUFFER_CHARS}`;
76 <Grid gap={4} className={cn('bg-black r8 p7', className)}>
77 <Grid.Item cols={[1, 4]}>
78 <MaybeSigil patp={name} size={64} />
80 <Grid.Item as={Flex} cols={[4, 13]} col justify="between">
81 <Flex.Item className="mono white f5">{visualName}</Flex.Item>
82 <Flex.Item as={Flex} col>
83 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
86 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
92 <Grid.Item full className="mv3" as={Flex} col>
93 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
98 className={cn('arial f6 f5-ns wrap', {
99 gray4: !isValidTicket,
100 green3: isValidTicket,
104 <Flex.Item as={Text} className="mono f6 f5-ns gray4 wrap">
113// TODO: Passport.Mini should probably accept Maybe<> for point
114// in order to display a pretty skeleton loading view
115// but that requires making usePermissionsForPoint accept a Maybe<point>
116// and I don't feel like that refactor is worth it right now, and the spec
117// doesn't call for it, hence the TODO
118Passport.Mini = function MiniPassport({ point, className, inverted, ...rest }) {
119 useSyncOwnedPoints([point]);
121 const { wallet } = useWallet();
122 const address = need.addressFromWallet(wallet);
124 const permissions = usePermissionsForPoint(address, point);
125 const keyType = buildKeyType(permissions);
126 const name = useMemo(() => ob.patp(point), [point]);
134 'bg-black': !inverted,
135 'bg-white b-gray4 b1': inverted,
140 <Grid.Item cols={[1, 4]}>
144 colors={inverted ? INVERTED_COLORWAY : undefined}
147 <Grid.Item as={Flex} cols={[4, 13]} col justify="between">
149 className={cn('mono f6 pb2', {
155 <Flex.Item as={Flex} col className={cn('mono f6 uppercase')}>
170 {keyType || <Blinky />}
178export 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