* 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>
143 lines
3.9 KiB
TypeScript
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;
|
|
}
|
|
}
|
|
`;
|