Skip to content

Commit

Permalink
tweak: add "waiting" state for buttons that decrypts wallet (password…
Browse files Browse the repository at this point in the history
… modal, unlock, import wallet)
  • Loading branch information
brusherru committed Aug 22, 2024
1 parent a4ec14f commit f9d65d2
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
14 changes: 11 additions & 3 deletions src/components/PasswordAlert.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef } from 'react';
import { useRef, useState } from 'react';
import { Form } from 'react-hook-form';

import {
Expand All @@ -21,12 +21,19 @@ import usePassword from '../store/usePassword';
import PasswordInput from './PasswordInput';

function PasswordAlert(): JSX.Element {
const [isLoading, setIsLoading] = useState(false);
const { form } = usePassword();
const cancelRef = useRef<HTMLButtonElement>(null);
if (!form.register.password || !form.register.remember) {
throw new Error('PasswordAlert: password or remember is not registered');
}

const onSubmit = async () => {
setIsLoading(true);
await form.onSubmit();
setIsLoading(false);
};

return (
<AlertDialog
leastDestructiveRef={cancelRef}
Expand Down Expand Up @@ -75,10 +82,11 @@ function PasswordAlert(): JSX.Element {
<Button
type="submit"
colorScheme="purple"
onClick={form.onSubmit}
onClick={onSubmit}
ml={3}
disabled={isLoading}
>
{form.actionLabel}
{isLoading ? 'Checking password...' : form.actionLabel}
</Button>
</AlertDialogFooter>
</Form>
Expand Down
14 changes: 12 additions & 2 deletions src/screens/UnlockScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useState } from 'react';
import { Form, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom';

Expand Down Expand Up @@ -32,15 +33,18 @@ function UnlockScreen(): JSX.Element {
reset,
formState: { errors },
} = useForm<FormValues>();
const [isLoading, setIsLoading] = useState(false);

const submit = handleSubmit(async (data) => {
setIsLoading(true);
const success = await unlockWallet(data.password);
if (!success) {
setError('password', { type: 'value', message: 'Invalid password' });
return;
}
setValue('password', '');
reset();
setIsLoading(false);
navigate('/wallet');
});

Expand All @@ -64,8 +68,14 @@ function UnlockScreen(): JSX.Element {
<PasswordInput register={register('password')} />
<FormErrorMessage>{errors.password?.message}</FormErrorMessage>
</FormControl>
<Button type="submit" mt={4} onClick={() => submit()} size="lg">
Unlock
<Button
type="submit"
mt={4}
onClick={() => submit()}
size="lg"
disabled={isLoading}
>
{isLoading ? 'Unlocking...' : 'Unlock'}
</Button>
</Form>
</Flex>
Expand Down
14 changes: 12 additions & 2 deletions src/screens/welcome/ImportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import BackButton from '../../components/BackButton';
import PasswordInput from '../../components/PasswordInput';
import useWallet from '../../store/useWallet';
import { WalletFile } from '../../types/wallet';
import { postpone } from '../../utils/promises';

type FormValues = {
password: string;
Expand All @@ -38,6 +39,7 @@ function ImportScreen(): JSX.Element {
} = useForm<FormValues>();
const { openWallet } = useWallet();
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState(false);

const readFile = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
Expand Down Expand Up @@ -75,11 +77,18 @@ function ImportScreen(): JSX.Element {
setError('root', { type: 'manual', message: 'No wallet file loaded' });
return;
}
const success = await openWallet(walletFileContent, password);
setIsLoading(true);
const success = await postpone(
// We need to postpone it for one tick
// to allow component to re-render
() => openWallet(walletFileContent, password),
1
);
if (!success) {
setError('password', { type: 'value', message: 'Invalid password' });
return;
}
setIsLoading(false);
navigate('/wallet');
});

Expand Down Expand Up @@ -135,8 +144,9 @@ function ImportScreen(): JSX.Element {
mt={4}
width="100%"
onClick={onSubmit}
disabled={isLoading}
>
Import wallet
{isLoading ? 'Importing...' : 'Import wallet'}
</Button>
</Form>
</CardBody>
Expand Down
25 changes: 15 additions & 10 deletions src/store/usePassword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useDisclosure } from '@chakra-ui/react';

import { MINUTE } from '../utils/constants';
import { noop } from '../utils/func';
import { postpone } from '../utils/promises';

const REMEMBER_PASSWORD_TIME = 5 * MINUTE;

Expand Down Expand Up @@ -123,16 +124,20 @@ const usePassword = (): UsePasswordReturnType => {
);
return;
}
try {
const res = await passwordCallback(password);
setPassword(password, remember);
_onClose();
setValue('password', '');
reset();
eventEmitter.emit('success', res);
} catch (err) {
setError('password', { message: 'Incorrect password' });
}
await postpone(async () => {
// We need to postpone it for one tick to allow
// the form to re-render before start checking the password
try {
const res = await passwordCallback(password);
setPassword(password, remember);
_onClose();
setValue('password', '');
reset();
eventEmitter.emit('success', res);
} catch (err) {
setError('password', { message: 'Incorrect password' });
}
}, 1);
});

const onClose = () => {
Expand Down
11 changes: 11 additions & 0 deletions src/utils/promises.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const delay = (ms: number) =>
new Promise((resolve) => {
setTimeout(resolve, ms);
});

export const postpone = <T>(fn: () => T, ms: number): Promise<T> =>
new Promise((resolve) => {
setTimeout(async () => {
resolve(await fn());
}, ms);
});

0 comments on commit f9d65d2

Please sign in to comment.