ghost-portal/packages/app-accounts/src/Editor.tsx
Marni e08e21a74d Marni wip 219 forget confirmation (#277)
* WIP: Not sure if this is proper use of Link / Button

* remove console log

* remove space

* trying to create a forgetting modal

* first commit with new forgetting file - unsure this is right

* hopefully fixed the incorrect use of translate?

* fixed other requested changes with translate
2018-09-05 12:09:45 +02:00

255 lines
5.8 KiB
TypeScript

// Copyright 2017-2018 @polkadot/app-accounts authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { KeyringPair } from '@polkadot/util-keyring/types';
import { I18nProps } from '@polkadot/ui-app/types';
import React from 'react';
import Button from '@polkadot/ui-app/Button';
import Input from '@polkadot/ui-app/Input';
import InputAddress from '@polkadot/ui-app/InputAddress';
import keyring from '@polkadot/ui-keyring/index';
import accountObservable from '@polkadot/ui-keyring/observable/accounts';
import withObservableBase from '@polkadot/ui-react-rx/with/observableBase';
import Forgetting from './Forgetting';
import AddressSummary from '@polkadot/ui-app/AddressSummary';
import translate from './translate';
type Props = I18nProps & {
accountAll?: Array<any>,
onBack: () => void
};
type State = {
current: KeyringPair | null,
editedName: string,
isEdited: boolean,
isForgetOpen: boolean
};
class Editor extends React.PureComponent<Props, State> {
state: State;
constructor (props: Props) {
super(props);
this.state = this.createState(null);
}
render () {
const { isForgetOpen } = this.state;
return (
<div className='accounts--Editor'>
<Forgetting
isOpen={isForgetOpen}
onClose={this.toggleForget}
doForget={this.onForget}
/>
{this.renderData()}
{this.renderButtons()}
</div>
);
}
renderButtons () {
const { t } = this.props;
const { current, isEdited } = this.state;
if (!current) {
return null;
}
return (
<Button.Group>
<Button
isNegative
onClick={this.toggleForget}
text={t('editor.forget', {
defaultValue: 'Forget'
})}
/>
<Button.Group.Divider />
<Button
isDisabled={!isEdited}
onClick={this.onDiscard}
text={t('editor.reset', {
defaultValue: 'Reset'
})}
/>
<Button.Or />
<Button
isDisabled={!isEdited}
isPrimary
onClick={this.onCommit}
text={t('editor.save', {
defaultValue: 'Save'
})}
/>
</Button.Group>
);
}
renderData () {
const { accountAll, t } = this.props;
const { current, editedName } = this.state;
if (!accountAll || !Object.keys(accountAll).length) {
return t('editor.none', {
defaultValue: 'There are no saved accounts. Add some first.'
});
}
const address = current
? current.address()
: undefined;
return (
<div className='ui--grid'>
<AddressSummary
className='shrink'
value={address || ''}
/>
<div className='grow'>
<div className='ui--row'>
<InputAddress
className='full'
hideAddress
isInput={false}
label={t('editor.select', {
defaultValue: 'using my account'
})}
onChange={this.onChangeAccount}
type='account'
value={address}
/>
</div>
<div className='ui--row'>
<Input
className='full'
isEditable
label={t('editor.name', {
defaultValue: 'identified by the name'
})}
onChange={this.onChangeName}
value={editedName}
/>
</div>
</div>
</div>
);
}
createState (current: KeyringPair | null): State {
return {
current,
editedName: current
? current.getMeta().name || ''
: '',
isEdited: false,
isForgetOpen: false
};
}
nextState (newState: State = {} as State): void {
this.setState(
(prevState: State): State => {
let { current = prevState.current, editedName = prevState.editedName } = newState;
const previous = prevState.current || { address: () => undefined };
let isEdited = false;
if (current) {
if (current.address() !== previous.address()) {
editedName = current.getMeta().name || '';
} else if (editedName !== current.getMeta().name) {
isEdited = true;
}
} else {
editedName = '';
}
let isForgetOpen = false;
return {
current,
editedName,
isEdited,
isForgetOpen
};
}
);
}
onChangeAccount = (publicKey: Uint8Array): void => {
const current = publicKey && publicKey.length === 32
? keyring.getPair(publicKey)
: null;
this.nextState({
current
} as State);
}
onChangeName = (editedName: string): void => {
this.nextState({ editedName } as State);
}
onCommit = (): void => {
const { current, editedName } = this.state;
if (!current) {
return;
}
keyring.saveAccountMeta(current, {
name: editedName,
whenEdited: Date.now()
});
this.nextState({} as State);
}
onDiscard = (): void => {
const { current } = this.state;
if (!current) {
return;
}
this.nextState({
editedName: current.getMeta().name
} as State);
}
toggleForget = (): void => {
this.setState(
({ isForgetOpen }: State) => ({
isForgetOpen: !isForgetOpen
})
);
}
onForget = (): void => {
const { current } = this.state;
if (!current) {
return;
}
this.setState(
this.createState(null),
() => {
keyring.forgetAccount(
current.address()
);
}
);
}
}
export default withObservableBase(
accountObservable.subject, { propName: 'accountAll' }
)(translate(Editor));