ghost-keychain/packages/extension-ui/src/Popup/Signing/Request/SignArea.tsx
Thibaut Sardan e7fb3651ab
Style component global cleanup (#518)
* ButtonArea

* List

* Box and Welcome screen

* Svg

* remove single used Title

* ValidateInput

* VerticalSpace

* View

* Export

* Forget

* DropdownAddress

* Accounts

* Request

* Authorize

* SelectParent

* Header

* Menu item spacing

* fix tests

* Apply suggestions from code review

Co-authored-by: Jaco Greeff <jacogr@gmail.com>

* Refactor Request into smaller components (#519)

* refactor into smaller components

* stray component

* Update packages/extension-ui/src/Popup/Signing/Request/SignArea.tsx

Co-authored-by: Jaco Greeff <jacogr@gmail.com>

* lint

Co-authored-by: Github Actions <action@github.com>
Co-authored-by: Jaco Greeff <jacogr@gmail.com>

Co-authored-by: Github Actions <action@github.com>
Co-authored-by: Jaco Greeff <jacogr@gmail.com>
2020-10-23 20:26:14 +02:00

143 lines
3.9 KiB
TypeScript

// Copyright 2019-2020 @polkadot/extension-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { PASSWORD_EXPIRY_MIN } from '@polkadot/extension-base/defaults';
import React, { useCallback, useContext, useEffect, useState } from 'react';
import styled from 'styled-components';
import { ActionBar, ActionContext, Button, ButtonArea, Checkbox, Link } from '../../../components';
import useTranslation from '../../../hooks/useTranslation';
import { approveSignPassword, cancelSignRequest, isSignLocked } from '../../../messaging';
import Unlock from '../Unlock';
interface Props {
buttonText: string;
className?: string;
error: string | null;
isExternal?: boolean;
isFirst: boolean;
setError: (value: string | null) => void;
signId: string;
}
function SignArea ({ buttonText, className, error, isExternal, isFirst, setError, signId } : Props): JSX.Element {
const [savePass, setSavePass] = useState(false);
const [isLocked, setIsLocked] = useState<boolean | null>(null);
const [password, setPassword] = useState('');
const [isBusy, setIsBusy] = useState(false);
const onAction = useContext(ActionContext);
const { t } = useTranslation();
useEffect(() => {
setIsLocked(null);
let timeout: number;
!isExternal && isSignLocked(signId)
.then(({ isLocked, remainingTime }) => {
setIsLocked(isLocked);
timeout = setTimeout(() => {
setIsLocked(true);
}, remainingTime);
// if the account was unlocked check the remember me
// automatically to prolong the unlock period
!isLocked && setSavePass(true);
})
.catch((error: Error) => console.error(error));
return () => { !!timeout && clearTimeout(timeout); };
}, [isExternal, signId]);
const _onSign = useCallback(
(): Promise<void> => {
setIsBusy(true);
return approveSignPassword(signId, savePass, password)
.then((): void => {
setIsBusy(false);
onAction();
})
.catch((error: Error): void => {
setIsBusy(false);
setError(error.message);
console.error(error);
});
},
[onAction, password, savePass, setError, setIsBusy, signId]
);
const _onCancel = useCallback(
(): Promise<void> => cancelSignRequest(signId)
.then(() => onAction())
.catch((error: Error) => console.error(error)),
[onAction, signId]
);
const RememberPasswordCheckbox = () => (
<Checkbox
checked={savePass}
label={ isLocked
? t<string>(
'Remember my password for the next {{expiration}} minutes',
{ replace: { expiration: PASSWORD_EXPIRY_MIN } }
)
: t<string>(
'Extend the period without password by {{expiration}} minutes',
{ replace: { expiration: PASSWORD_EXPIRY_MIN } }
)
}
onChange={setSavePass}
/>
);
return (
<ButtonArea className={className}>
{isFirst && !isExternal && (
<>
{ isLocked && (
<Unlock
error={error}
isBusy={isBusy}
onSign={_onSign}
password={password}
setError={setError}
setPassword={setPassword}
/>
)}
<RememberPasswordCheckbox />
<Button
isBusy={isBusy}
isDisabled={(!!isLocked && !password) || !!error}
onClick={_onSign}
>
{buttonText}
</Button>
</>
)}
<ActionBar className='cancelButton'>
<Link
isDanger
onClick={_onCancel}
>
{t<string>('Cancel')}
</Link>
</ActionBar>
</ButtonArea>
);
}
export default styled(SignArea)`
flex-direction: column;
padding: 6px 24px;
.cancelButton {
margin-top: 4px;
margin-bottom: 4px;
text-decoration: underline;
a {
margin: auto;
}
}
`;