on master help sign in
Sigil redesign and L1 sponsorship
commitf3eb79907d9b1b69127b290e1d658764b967dad8 authorWill Galebach <willbach@gmail.com> dateSat 4 Dec 2021, 16:10 (5 years ago) parenta3a8f64
16 files changed+199−142
src/components/Greeting.js+1−1 src/components/L2/Dropdowns/AccountsDropdown.tsx+6−1 src/components/L2/LoadingOverlay.tsx+1−1 src/lib/router.js+1−1 src/lib/types/Point.ts+4−5 src/views/Adopt.js → src/views/Ops/Adopt.tsx+42−27 src/views/Ops/Requests.tsx+40−14 src/views/Ops/ResidentRow.tsx+24−18 src/views/Point/IssueChild.tsx+1−2 src/views/Point/UrbitID.js+3−6 src/views/UrbitID/ResetKeys/ResetDownload.js+1−1 src/views/UrbitID/ResetKeys/ResetVerify.js+1−1 src/views/UrbitID/SetProxy.js+1−1 src/views/UrbitID/SigilGenerator.js+66−58 src/views/UrbitID/Transfer.js+3−2 src/views/UrbitOS/ChangeSponsor.js+4−3
src/components/Greeting.js+1−1
@@ -24,7 +24,7 @@ export default function ActivateDisclaimer({ point }) {
2424 <Grid gap={4} className="mb10">
2525 <Grid.Item full>
2626 <Text className={cn(TEXT_STYLE, 'block mb4')}>
27− Welcome <code>{pointName}</code>,
27+ Welcome <span className="mono">{pointName}</span>,
2828 </Text>
2929
3030 <Text className={cn(TEXT_STYLE, 'block mb2')}>
src/components/L2/Dropdowns/AccountsDropdown.tsx+6−1
@@ -76,6 +76,11 @@ const AccountsDropdown = ({ showMigrate = false }: AccountsDropdownProps) => {
7676 const displayText =
7777 point.value >= 0 ? point.patp : currentAddress.slice(0, 6);
7878
79+ const displayedPoints = useMemo(
80+ () => pointList.filter(({ ownManageSpawn }) => ownManageSpawn),
81+ [pointList]
82+ );
83+
7984 return (
8085 <Dropdown
8186 className="accounts-dropdown"
@@ -90,7 +95,7 @@ const AccountsDropdown = ({ showMigrate = false }: AccountsDropdownProps) => {
9095 </CopiableAddressWrap>
9196 <Box className="divider" />
9297 <Box className="points">
93− {pointList.map(({ value, layer, patp }) => (
98+ {displayedPoints.map(({ value, layer, patp }) => (
9499 <Row
95100 className={`entry point ${value === point.value ? 'selected' : ''}`}
96101 onClick={selectPoint(value)}
src/components/L2/LoadingOverlay.tsx+1−1
@@ -17,7 +17,7 @@ const LoadingOverlay = ({
1717 <Box className="loading-overlay">
1818 <Box className={`${text ? 'solid' : ''}`}>
1919 {!!text && <Box className="loader-text">{text}</Box>}
20− <LoadingSpinner foreground="rgba(0,0,0,0.3)" background="white" />
20+ <LoadingSpinner background="rgba(0,0,0,0.3)" foreground="white" />
2121 </Box>
2222 </Box>
2323 );
src/lib/router.js+1−1
@@ -22,7 +22,7 @@ import PartySetPoolSize from 'views/Party/PartySetPoolSize';
2222import InviteCohort from 'views/Invite/Cohort';
2323import AcceptTransfer from 'views/AcceptTransfer';
2424import CancelTransfer from 'views/CancelTransfer';
25−import Adopt from 'views/Adopt';
25+import Adopt from 'views/Ops/Adopt.tsx';
2626import Bitcoin from 'views/Bitcoin/Bitcoin';
2727import Xpub from 'views/Bitcoin/Xpub';
2828import SignTransaction from 'views/Bitcoin/SignTransaction';
src/lib/types/Point.ts+4−5
@@ -109,6 +109,7 @@ export default class Point {
109109 showInvites: boolean;
110110 isDefault: boolean;
111111 isPlaceholder: boolean;
112+ ownManageSpawn: boolean;
112113 shouldDisplay: boolean;
113114
114115 constructor({
@@ -174,13 +175,11 @@ export default class Point {
174175 this.showInvites = this.canManage || this.canSpawn;
175176 this.isDefault = value === -1;
176177 this.isPlaceholder = isPlaceholder;
177− this.shouldDisplay =
178+ this.ownManageSpawn =
178179 !this.isPlaceholder &&
179180 !this.isDefault &&
180− (this.isOwner ||
181− this.isSpawnProxy ||
182− this.isManagementProxy ||
183− this.isTransferProxy);
181+ (this.isOwner || this.isSpawnProxy || this.isManagementProxy);
182+ this.shouldDisplay = this.ownManageSpawn || this.isTransferProxy;
184183 }
185184
186185 equals = (point: Point) => {
src/views/Adopt.js → src/views/Ops/Adopt.tsxrenamed+42−27
@@ -3,31 +3,35 @@ import { Grid } from 'indigo-react';
33import * as ob from 'urbit-ob';
44import { ecliptic } from 'azimuth-js';
55
6−import View from 'components/View';
7−import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
8−import ViewHeader from 'components/ViewHeader';
9−
106import { useNetwork } from 'store/network';
117import { usePointCache } from 'store/pointCache';
128import { usePointCursor } from 'store/pointCursor';
139import { useHistory } from 'store/history';
1410
11+import * as need from 'lib/need';
1512import { GAS_LIMITS } from 'lib/constants';
1613import useEthereumTransaction from 'lib/useEthereumTransaction';
17−import * as need from 'lib/need';
14+
15+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
16+import Window from 'components/L2/Window/Window';
17+import HeaderPane from 'components/L2/Window/HeaderPane';
18+import BodyPane from 'components/L2/Window/BodyPane';
19+import View from 'components/View';
20+import L2BackHeader from 'components/L2/Headers/L2BackHeader';
21+import { Row } from '@tlon/indigo-react';
1822
1923function useAdopt() {
20− const { contracts } = useNetwork();
24+ const { contracts }: any = useNetwork();
2125 const _contracts = need.contracts(contracts);
2226
23− const { pointCursor } = usePointCursor();
27+ const { pointCursor }: any = usePointCursor();
2428 const point = need.point(pointCursor);
2529
26− const { syncResidents } = usePointCache();
30+ const { syncResidents }: any = usePointCache();
2731
2832 return useEthereumTransaction(
2933 useCallback(
30− (adoptee, denied) =>
34+ (adoptee: number, denied: boolean) =>
3135 denied
3236 ? ecliptic.reject(_contracts, adoptee)
3337 : ecliptic.adopt(_contracts, adoptee),
@@ -39,7 +43,7 @@ function useAdopt() {
3943}
4044
4145export default function Adopt() {
42− const { pop, data } = useHistory();
46+ const { pop, data }: any = useHistory();
4347
4448 const { adoptee, denied } = data;
4549
@@ -51,12 +55,12 @@ export default function Adopt() {
5155 () =>
5256 denied ? (
5357 <>
54− {completed ? 'Denied' : 'Denying'} adoption request to{' '}
58+ {completed ? 'Rejected' : 'Rejecting'} adoption request for{' '}
5559 <span className="mono">{patp}</span>
5660 </>
5761 ) : (
5862 <>
59− {completed ? 'Approved' : 'Approving'} adoption request to{' '}
63+ {completed ? 'Approved' : 'Approving'} adoption request for{' '}
6064 <span className="mono">{patp}</span>
6165 </>
6266 ),
@@ -67,22 +71,33 @@ export default function Adopt() {
6771 construct(adoptee, denied);
6872 }, [construct, adoptee, denied]);
6973
74+ const headerText = `${denied ? 'Reject' : 'Approve'} Adoption Request`;
75+
7076 return (
71− <View pop={() => pop()} inset>
72− <Grid>
73− <Grid.Item full as={ViewHeader} className="mb2">
74− Adopt
75− </Grid.Item>
76− <Grid.Item full className="gray4 f5 mv2">
77− {body}
78− </Grid.Item>
79− <Grid.Item
80− full
81− {...bind}
82− as={InlineEthereumTransaction}
83− onReturn={() => pop()}
84− />
85− </Grid>
77+ <View
78+ className="adopt-l1"
79+ pop={pop}
80+ inset
81+ hideBack
82+ header={<L2BackHeader hideBalance back={pop} />}>
83+ <Window>
84+ <HeaderPane>
85+ <Row className="header-row">
86+ <h5>{headerText}</h5>
87+ </Row>
88+ </HeaderPane>
89+ <BodyPane>
90+ <Grid.Item className="f5 mv2 w-full" style={{ fontSize: 14 }}>
91+ {body}
92+ </Grid.Item>
93+ <Grid.Item
94+ full
95+ {...bind}
96+ as={InlineEthereumTransaction}
97+ onReturn={() => pop()}
98+ />
99+ </BodyPane>
100+ </Window>
86101 </View>
87102 );
88103}
src/views/Ops/Requests.tsx+40−14
@@ -4,11 +4,11 @@ import { Ship } from '@urbit/roller-api';
44
55import { useRollerStore } from 'store/rollerStore';
66import useRoller from 'lib/useRoller';
7+import { useLocalRouter } from 'lib/LocalRouter';
78
89import Window from 'components/L2/Window/Window';
910import HeaderPane from 'components/L2/Window/HeaderPane';
1011import BodyPane from 'components/L2/Window/BodyPane';
11−import { useLocalRouter } from 'lib/LocalRouter';
1212import View from 'components/View';
1313import L2BackHeader from 'components/L2/Headers/L2BackHeader';
1414
@@ -16,7 +16,7 @@ import { RequestRow } from './RequestRow';
1616import './Requests.scss';
1717
1818export const Requests = () => {
19− const { pop }: any = useLocalRouter();
19+ const { pop, push, names }: any = useLocalRouter();
2020 const { point, setLoading } = useRollerStore();
2121 const { api, changeSponsorship } = useRoller();
2222 const [requestingPoints, setRequestingPoints] = useState<Ship[]>([]);
@@ -32,24 +32,50 @@ export const Requests = () => {
3232 setLoading(false);
3333 }, [api, point, setLoading]);
3434
35+ const acceptL1 = useCallback(
36+ adoptee =>
37+ push(names.ADOPT, {
38+ adoptee,
39+ denied: false,
40+ }),
41+ [push, names]
42+ );
43+
44+ const rejectL1 = useCallback(
45+ adoptee =>
46+ push(names.ADOPT, {
47+ adoptee,
48+ denied: true,
49+ }),
50+ [push, names]
51+ );
52+
3553 const handleAcceptClick = useCallback(
36− async (point: Ship) => {
37− setLoading(true);
38− await changeSponsorship(point, 'adopt');
39− await fetchRequests();
40− setLoading(false);
54+ async (ship: Ship) => {
55+ if (point.isL1) {
56+ acceptL1(ship);
57+ } else {
58+ setLoading(true);
59+ await changeSponsorship(ship, 'adopt');
60+ await fetchRequests();
61+ setLoading(false);
62+ }
4163 },
42− [changeSponsorship, fetchRequests, setLoading]
64+ [point, acceptL1, changeSponsorship, fetchRequests, setLoading]
4365 );
4466
4567 const handleRejectClick = useCallback(
46− async (point: Ship) => {
47− setLoading(true);
48− await changeSponsorship(point, 'reject');
49− await fetchRequests();
50− setLoading(false);
68+ async (ship: Ship) => {
69+ if (point.isL1) {
70+ rejectL1(ship);
71+ } else {
72+ setLoading(true);
73+ await changeSponsorship(ship, 'reject');
74+ await fetchRequests();
75+ setLoading(false);
76+ }
5177 },
52− [changeSponsorship, fetchRequests, setLoading]
78+ [point, rejectL1, changeSponsorship, fetchRequests, setLoading]
5379 );
5480
5581 useEffect(() => {
src/views/Ops/ResidentRow.tsx+24−18
@@ -4,6 +4,7 @@ import { Ship } from '@urbit/roller-api';
44import Sigil from 'components/Sigil';
55import { useCallback, useRef, useState } from 'react';
66import useOnClickOutside from 'lib/useOnClickOutside';
7+import { useRollerStore } from 'store/rollerStore';
78
89interface ResidentRowProps {
910 point: Ship;
@@ -11,6 +12,9 @@ interface ResidentRowProps {
1112}
1213
1314export const ResidentRow = ({ point, onKick }: ResidentRowProps) => {
15+ const {
16+ point: { isL2 },
17+ } = useRollerStore();
1418 const [showDropdown, setShowDropdown] = useState<boolean>(false);
1519 const dropdownRef = useRef<HTMLDivElement | null>(null);
1620
@@ -41,24 +45,26 @@ export const ResidentRow = ({ point, onKick }: ResidentRowProps) => {
4145 </Box>
4246 <Box className={'patp'}>{ob.patp(point)}</Box>
4347 </Box>
44− <Box className="button-wrapper" ref={dropdownRef}>
45− <Icon
46− icon="Ellipsis"
47− size="18px"
48− onClick={() => setShowDropdown(!showDropdown)}
49− />
50− {showDropdown && (
51− <>
52− <Box
53− className="close-background"
54− onClick={() => setShowDropdown(false)}
55− />
56− <Box className="kick-dropdown" onClick={handleKickClick}>
57− <Text>Kick</Text>
58− </Box>
59− </>
60− )}
61− </Box>
48+ {isL2 && (
49+ <Box className="button-wrapper" ref={dropdownRef}>
50+ <Icon
51+ icon="Ellipsis"
52+ size="18px"
53+ onClick={() => setShowDropdown(!showDropdown)}
54+ />
55+ {showDropdown && (
56+ <>
57+ <Box
58+ className="close-background"
59+ onClick={() => setShowDropdown(false)}
60+ />
61+ <Box className="kick-dropdown" onClick={handleKickClick}>
62+ <Text>Kick</Text>
63+ </Box>
64+ </>
65+ )}
66+ </Box>
67+ )}
6268 </li>
6369 );
6470};
src/views/Point/IssueChild.tsx+1−2
@@ -178,7 +178,6 @@ export default function IssueChild() {
178178 const onValues = useCallback(
179179 ({ valid, values }) => {
180180 if (valid) {
181− console.log('VALID')
182181 construct(patp2dec(values.point), values.owner);
183182 } else {
184183 unconstruct();
@@ -225,7 +224,7 @@ export default function IssueChild() {
225224 <BodyPane>
226225 <Box className="inner-container">
227226 <BridgeForm
228− style={{ width: '100%' }}
227+ className="w-full"
229228 validate={validate}
230229 onValues={onValues}>
231230 {({ handleSubmit, values }: any) => (
src/views/Point/UrbitID.js+3−6
@@ -1,6 +1,7 @@
11import React from 'react';
22
33import { useHistory } from 'store/history';
4+import { useRollerStore } from 'store/rollerStore';
45
56import useRouter from 'lib/useRouter';
67import { LocalRouterProvider } from 'lib/LocalRouter';
@@ -35,6 +36,7 @@ const VIEWS = {
3536
3637export default function UrbitID() {
3738 const history = useHistory();
39+ const { point } = useRollerStore();
3840
3941 const { Route, ...router } = useRouter({
4042 names: NAMES,
@@ -50,12 +52,7 @@ export default function UrbitID() {
5052 pop={onBack}
5153 inset
5254 hideBack
53− header={
54− <L2BackHeader
55− hideBalance={router.peek().key === NAMES.HOME}
56− back={onBack}
57− />
58− }
55+ header={<L2BackHeader hideBalance={point.isL2} back={onBack} />}
5956 className="urbit-id">
6057 <LocalRouterProvider value={router}>
6158 <Route />
src/views/UrbitID/ResetKeys/ResetDownload.js+1−1
@@ -20,7 +20,7 @@ export default function ReticketDownload({ newWallet }) {
2020 const goVerify = useCallback(() => push(names.VERIFY), [push, names]);
2121
2222 return (
23− <Grid className="mt4" style={{ width: '100%' }}>
23+ <Grid className="mt4 w-full">
2424 <Grid.Item full as={Text}>
2525 Download the new passport, and keep it somewhere safe!
2626 </Grid.Item>
src/views/UrbitID/ResetKeys/ResetVerify.js+1−1
@@ -37,7 +37,7 @@ export default function ResetVerify({ newWallet }) {
3737 const goExecute = useCallback(() => push(names.EXECUTE), [push, names]);
3838
3939 return (
40− <Grid className="mt4" style={{ width: '100%' }}>
40+ <Grid className="mt4 w-full">
4141 <Grid.Item full as={Text}>
4242 Verify New Master Ticket
4343 </Grid.Item>
src/views/UrbitID/SetProxy.js+1−1
@@ -239,7 +239,7 @@ export default function SetProxy() {
239239 </Row>
240240 </HeaderPane>
241241 <BodyPane>
242− <Grid style={{ width: '100%' }}>
242+ <Grid className="w-full">
243243 {!completed && (
244244 <>
245245 <Grid.Item full as={Text} className="mb4 f5 gray4">
src/views/UrbitID/SigilGenerator.js+66−58
@@ -17,6 +17,10 @@ import FormError from 'form/FormError';
1717import SubmitButton from 'form/SubmitButton';
1818import { NumberInput } from 'form/Inputs';
1919import ColorInput from 'form/ColorInput';
20+import Window from 'components/L2/Window/Window';
21+import HeaderPane from 'components/L2/Window/HeaderPane';
22+import BodyPane from 'components/L2/Window/BodyPane';
23+import { Row } from '@tlon/indigo-react';
2024
2125const BG_COLORS = [
2226 colors.black,
@@ -59,65 +63,69 @@ export default function SigilGenerator() {
5963 [point, downloadSigil]
6064 );
6165 return (
62− <>
63− <BridgeForm
64− validate={validate}
65− initialValues={{
66− size: 256,
67− fgColor: '#FFFFFF',
68− bgColor: '#000000',
69− }}
70− onSubmit={onSubmit}>
71− {({ handleSubmit, values }) => (
72− <Grid gap={6}>
73− <Grid.Item full className="f5">
74− Sigil
75− </Grid.Item>
76− <Grid.Item fourth={1}>
77− <Sigil
78− size={50}
79− patp={ob.patp(point)}
80− colors={[values.bgColor, values.fgColor]}
81− />
82− </Grid.Item>
66+ <Window className="id-home">
67+ <HeaderPane>
68+ <Row className="header-row">
69+ <h5>Sigil</h5>
70+ </Row>
71+ </HeaderPane>
72+ <BodyPane>
73+ <BridgeForm
74+ validate={validate}
75+ initialValues={{
76+ size: 256,
77+ fgColor: '#FFFFFF',
78+ bgColor: '#000000',
79+ }}
80+ onSubmit={onSubmit}>
81+ {({ handleSubmit, values }) => (
82+ <Grid gap={6}>
83+ <Grid.Item fourth={1}>
84+ <Sigil
85+ size={50}
86+ patp={ob.patp(point)}
87+ colors={[values.bgColor, values.fgColor]}
88+ />
89+ </Grid.Item>
8390
84− <Grid.Item full as={Flex} col>
85− <Flex.Item className="mb1">Urbit ID</Flex.Item>
86− <Flex.Item className="mono">{ob.patp(point)}</Flex.Item>
87− </Grid.Item>
88− <Grid.Item
89− fourth={1}
90− as={NumberInput}
91− name="size"
92− label="Size (px)"
93− />
94− <Grid.Item
95− full
96− as={ColorInput}
97− name="bgColor"
98− label="Background Color"
99− colors={BG_COLORS}
100− />
101− <Grid.Item
102− full
103− as={ColorInput}
104− name="fgColor"
105− label="Foreground Color"
106− colors={FG_COLORS}
107− />
108− <Grid.Item
109− full
110− as={SubmitButton}
111− handleSubmit={handleSubmit}
112− accessory="↓">
113− Download Sigil
114− </Grid.Item>
115− <Grid.Item full as={FormError} />
116− </Grid>
117− )}
118− </BridgeForm>
91+ <Grid.Item full as={Flex} col>
92+ <Flex.Item className="mb1">Urbit ID</Flex.Item>
93+ <Flex.Item className="mono">{ob.patp(point)}</Flex.Item>
94+ </Grid.Item>
95+ <Grid.Item
96+ fourth={1}
97+ as={NumberInput}
98+ name="size"
99+ label="Size (px)"
100+ />
101+ <Grid.Item
102+ full
103+ as={ColorInput}
104+ name="bgColor"
105+ label="Background Color"
106+ colors={BG_COLORS}
107+ />
108+ <Grid.Item
109+ full
110+ as={ColorInput}
111+ name="fgColor"
112+ label="Foreground Color"
113+ colors={FG_COLORS}
114+ />
115+ <Grid.Item
116+ full
117+ as={SubmitButton}
118+ handleSubmit={handleSubmit}
119+ center>
120+ Download Sigil
121+ </Grid.Item>
122+ <Grid.Item full as={FormError} />
123+ </Grid>
124+ )}
125+ </BridgeForm>
119126
120− <canvas style={{ display: 'none' }} ref={canvasRef} />
121− </>
127+ <canvas style={{ display: 'none' }} ref={canvasRef} />
128+ </BodyPane>
129+ </Window>
122130 );
123131}
src/views/UrbitID/Transfer.js+3−2
@@ -114,13 +114,14 @@ export default function AdminTransfer() {
114114 </Row>
115115 </HeaderPane>
116116 <BodyPane>
117− <Grid style={{ width: '100%' }} full gap={1}>
117+ <Grid className="w-full" full gap={1}>
118118 <BridgeForm validate={validate} onValues={onValues}>
119119 {({ handleSubmit, values }) => (
120120 <>
121121 {!completed && (
122122 <Grid.Item full as={Text} className={cn('f5 wrap')}>
123− Transfer <code>{name}</code> to a new owner.
123+ Transfer <span className="mono">{name}</span> to a new
124+ owner.
124125 </Grid.Item>
125126 )}
126127 {!completed && needLockupWarning && (
src/views/UrbitOS/ChangeSponsor.js+4−3
@@ -232,7 +232,7 @@ function CurrentEscape({ onDone }) {
232232 full
233233 center
234234 solid
235− style={{ width: '100%' }}
235+ className="w-full"
236236 onClick={cancelRequest}>
237237 {buttonText}
238238 </Grid.Item>
@@ -251,13 +251,14 @@ function CurrentEscape({ onDone }) {
251251}
252252
253253export default function UrbitOSChangeSponsor() {
254+ const { pop } = useHistory();
254255 const { point } = useRollerStore();
255256
256257 const [requested, setRequested] = useState(point.escapeRequested);
257258
258259 const onDone = useCallback(() => {
259− setRequested(point.escapeRequested);
260− }, [point, setRequested]);
260+ point.isL1 ? pop() : setRequested(!requested);
261+ }, [point, pop, requested, setRequested]);
261262
262263 return requested ? (
263264 <CurrentEscape onDone={onDone} />