on df0c310 help sign in
bridge/src/views/Activate/MasterKeyDownload.tsx
161 lines 4.8 kB history raw
1import React, { useCallback, useEffect, useMemo, useState } from 'react';
2import { Just, Nothing } from 'folktale/maybe';
3import * as need from 'lib/need';
5import { ActivateSteps } from './ActivateSteps';
6import { Box } from '@tlon/indigo-react';
7import { FadeableActivateButton as ActivateButton } from './ActivateButton';
8import { FadeableActivateHeader as ActivateHeader } from './ActivateHeader';
9import { FadeableActivateParagraph as ActivateParagraph } from './ActivateParagraph';
10import { FadeableDangerBox as DangerBox } from './DangerBox';
11import { FadeableMasterKeyCopy as MasterKeyCopy } from './MasterKeyCopy';
12import { FadeableMasterKeyPresenter as MasterKeyPresenter } from './MasterKeyPresenter';
13import { useActivateFlow } from './useActivateFlow';
14import ActivateView from './ActivateView';
15import { useLocalRouter } from 'lib/LocalRouter';
16import PaperBuilder from 'components/PaperBuilder';
17import { DEFAULT_FADE_TIMEOUT, MASTER_KEY_DURATION } from 'lib/constants';
18import { timeout } from 'lib/timeout';
19import { downloadWallet } from 'lib/invite';
20import View from 'components/View';
21import { useActivationKeyfileGenerator } from 'lib/useKeyfileGenerator';
23const MasterKeyDownload = () => {
24 const {
25 derivedPoint,
26 inviteMasterTicketWallet,
27 inviteWallet,
28 isIn,
29 setGenerated,
30 setIsIn,
31 }: any = useActivateFlow();
32 const { data, push, names }: any = useLocalRouter();
33 const point = need.point(derivedPoint);
34 const wallet = need.wallet(inviteMasterTicketWallet);
35 const ticket = wallet.ticket.replace('~', '');
37 const [paper, setPaper] = useState(Nothing());
38 const [triggerAnimation, setTriggerAnimation] = useState<boolean>(false);
40 const skipAnimationDelay = useMemo(() => {
41 return data?.skipAnimationDelay ? true : false;
42 }, [data]);
44 const pointAsString = derivedPoint.matchWith({
45 Nothing: () => '',
46 Just: (p: any) => p.value.toFixed(),
47 });
49 const { keyfile, filename } = useActivationKeyfileGenerator({
50 pointId: point,
51 wallets: [inviteWallet.value, inviteMasterTicketWallet.value],
52 });
54 // sync paper value to activation state
55 useEffect(
56 () =>
57 setGenerated(
58 paper.matchWith({
59 Nothing: () => false,
60 Just: () => true,
61 })
62 ),
63 [paper, setGenerated]
64 );
66 const download = useCallback(async () => {
67 await downloadWallet(paper.getOrElse([]), keyfile, filename);
68 }, [paper, keyfile, filename]);
70 const onDownloadClick = useCallback(async () => {
71 await download();
72 setIsIn(false);
73 await timeout(DEFAULT_FADE_TIMEOUT); // Pause for UI fade animation
74 push(names.CONFIRM);
75 }, [download, setIsIn, push, names.CONFIRM]);
77 const header = useMemo(() => {
78 return (
79 <Box>
80 <ActivateHeader content={'Back up your Master Ticket.'} />
81 <ActivateParagraph
82 copy={
83 'Download and store your backup somewhere safe, like a security deposit box or password manager.'
84 }
85 />
86 </Box>
87 );
88 }, []);
90 const footer = useMemo(() => {
91 return (
92 <ActivateButton onClick={onDownloadClick}>
93 {'Download Backup (Passport)'}
94 </ActivateButton>
95 );
96 }, [onDownloadClick]);
98 const fadeIn = useCallback(() => {
99 setTriggerAnimation(true);
100 setIsIn(true);
101 }, [setIsIn]);
103 const delayedFadeIn = useCallback(async () => {
104 setTimeout(() => {
105 fadeIn();
106 }, MASTER_KEY_DURATION);
107 }, [fadeIn]);
109 useEffect(() => {
110 if (skipAnimationDelay) {
111 fadeIn();
112 } else {
113 delayedFadeIn();
114 }
116 return () => {
117 setIsIn(false);
118 };
119 }, [delayedFadeIn, fadeIn, setIsIn, skipAnimationDelay]);
121 return (
122 <View inset hideBack>
123 <ActivateView
124 hideBack
125 header={triggerAnimation && header}
126 footer={triggerAnimation && footer}>
127 <Box
128 alignItems={'center'}
129 display={'flex'}
130 flexDirection={'column'}
131 flexWrap={'nowrap'}
132 height={'100%'}
133 justifyContent={'space-evenly'}>
134 <DangerBox
135 overrideFadeIn={triggerAnimation && isIn}
136 className={`mv8 ${!isIn ? 'hidden' : ''}`}>
137 Never share your Master Ticket with anyone.
138 </DangerBox>
139 {ticket && (
140 <MasterKeyPresenter ticket={ticket} overrideFadeIn={true} />
141 )}
142 <MasterKeyCopy
143 text={ticket}
144 overrideFadeIn={triggerAnimation && isIn}
145 className={`mv5 ${!isIn ? 'hidden' : ''}`}
146 />
147 </Box>
148 </ActivateView>
149 <ActivateSteps currentStep={1} totalSteps={4} />
150 <PaperBuilder
151 point={pointAsString}
152 wallets={[wallet]}
153 callback={(data: any) => {
154 setPaper(Just(data));
155 }}
156 />
157 </View>
158 );
159};
161export default MasterKeyDownload;