Merge pull request #2 from polkadot-js/jg-refresh-create
Refresh accounts on create/import, add forget
This commit is contained in:
commit
014db3e86c
33
packages/extension-ui/src/Popup/Accounts/Account.tsx
Normal file
33
packages/extension-ui/src/Popup/Accounts/Account.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2019 @polkadot/extension-ui authors & contributors
|
||||||
|
// This software may be modified and distributed under the terms
|
||||||
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { ActionBar, Address } from '../../components';
|
||||||
|
import { forgetAccount } from '../../messaging';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
address: string,
|
||||||
|
name?: string,
|
||||||
|
onAction: () => void
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Account ({ address, name, onAction }: Props) {
|
||||||
|
const _onForget = (): void => {
|
||||||
|
forgetAccount(address)
|
||||||
|
.then(onAction)
|
||||||
|
.catch(console.error);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Address
|
||||||
|
address={address}
|
||||||
|
name={name}
|
||||||
|
>
|
||||||
|
<ActionBar>
|
||||||
|
<a onClick={_onForget}>Forget</a>
|
||||||
|
</ActionBar>
|
||||||
|
</Address>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -6,13 +6,15 @@ import { KeyringJson } from '@polkadot/ui-keyring/types';
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { Address, Button, Header, Tip } from '../components';
|
import { Button, Header, Tip } from '../../components';
|
||||||
|
import Account from './Account';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
accounts: Array<KeyringJson>
|
accounts: Array<KeyringJson>,
|
||||||
|
onAction: () => void
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Accounts ({ accounts }: Props) {
|
export default function Accounts ({ accounts, onAction }: Props) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Header label='accounts' />
|
<Header label='accounts' />
|
||||||
@ -20,10 +22,11 @@ export default function Accounts ({ accounts }: Props) {
|
|||||||
(accounts.length === 0)
|
(accounts.length === 0)
|
||||||
? <Tip header='add accounts' type='warn'>You currently don't have any accounts. Either create a new account or if you have an existing account you wish to use, import it with the seed phrase</Tip>
|
? <Tip header='add accounts' type='warn'>You currently don't have any accounts. Either create a new account or if you have an existing account you wish to use, import it with the seed phrase</Tip>
|
||||||
: accounts.map(({ address, meta: { name } }) => (
|
: accounts.map(({ address, meta: { name } }) => (
|
||||||
<Address
|
<Account
|
||||||
address={address}
|
address={address}
|
||||||
key={address}
|
key={address}
|
||||||
name={name}
|
name={name}
|
||||||
|
onAction={onAction}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -8,9 +8,11 @@ import { Address, Button, Header, Loading, TextArea } from '../components';
|
|||||||
import { createAccount, createSeed } from '../messaging';
|
import { createAccount, createSeed } from '../messaging';
|
||||||
import { Back, Name, Password } from '../partials';
|
import { Back, Name, Password } from '../partials';
|
||||||
|
|
||||||
type Props = {};
|
type Props = {
|
||||||
|
onAction: () => void
|
||||||
|
};
|
||||||
|
|
||||||
export default function Create (props: Props) {
|
export default function Create ({ onAction }: Props) {
|
||||||
const [account, setAccount] = useState(null as null | { address: string, seed: string });
|
const [account, setAccount] = useState(null as null | { address: string, seed: string });
|
||||||
const [name, setName] = useState(null as string | null);
|
const [name, setName] = useState(null as string | null);
|
||||||
const [password, setPassword] = useState(null as string | null);
|
const [password, setPassword] = useState(null as string | null);
|
||||||
@ -27,6 +29,7 @@ export default function Create (props: Props) {
|
|||||||
if (name && password && account) {
|
if (name && password && account) {
|
||||||
createAccount(name, password, account.seed)
|
createAccount(name, password, account.seed)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
onAction();
|
||||||
window.location.hash = '/';
|
window.location.hash = '/';
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
|
|||||||
@ -8,9 +8,11 @@ import { Address, Button, Header, TextArea } from '../components';
|
|||||||
import { createAccount, validateSeed } from '../messaging';
|
import { createAccount, validateSeed } from '../messaging';
|
||||||
import { Back, Name, Password } from '../partials';
|
import { Back, Name, Password } from '../partials';
|
||||||
|
|
||||||
type Props = {};
|
type Props = {
|
||||||
|
onAction: () => void
|
||||||
|
};
|
||||||
|
|
||||||
export default function Import (props: Props) {
|
export default function Import ({ onAction }: Props) {
|
||||||
const [account, setAccount] = useState(null as null | { address: string, seed: string });
|
const [account, setAccount] = useState(null as null | { address: string, seed: string });
|
||||||
const [name, setName] = useState(null as string | null);
|
const [name, setName] = useState(null as string | null);
|
||||||
const [password, setPassword] = useState(null as string | null);
|
const [password, setPassword] = useState(null as string | null);
|
||||||
@ -31,6 +33,7 @@ export default function Import (props: Props) {
|
|||||||
if (name && password && account) {
|
if (name && password && account) {
|
||||||
createAccount(name, password, account.seed)
|
createAccount(name, password, account.seed)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
onAction();
|
||||||
window.location.hash = '/';
|
window.location.hash = '/';
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
|
|||||||
@ -21,13 +21,8 @@ export default function Popup (props: Props) {
|
|||||||
const [accounts, setAccounts] = useState(null as null | Array<KeyringJson>);
|
const [accounts, setAccounts] = useState(null as null | Array<KeyringJson>);
|
||||||
const [requests, setRequests] = useState(null as null | Array<[number, MessageExtrinsicSign, string]>);
|
const [requests, setRequests] = useState(null as null | Array<[number, MessageExtrinsicSign, string]>);
|
||||||
|
|
||||||
const _onAction = (): void => {
|
const onAction = (): void => {
|
||||||
getRequests()
|
// loads all accounts & requests (this is passed through to children to trigger changes)
|
||||||
.then(setRequests)
|
|
||||||
.catch(console.error);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect((): void => {
|
|
||||||
Promise
|
Promise
|
||||||
.all([getAccounts(), getRequests()])
|
.all([getAccounts(), getRequests()])
|
||||||
.then(([accounts, requests]) => {
|
.then(([accounts, requests]) => {
|
||||||
@ -35,18 +30,28 @@ export default function Popup (props: Props) {
|
|||||||
setRequests(requests);
|
setRequests(requests);
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect((): void => {
|
||||||
|
// with an empty state, load the accounts & requests
|
||||||
|
onAction();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Loading>{accounts && requests && (
|
<Loading>{accounts && requests && (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path='/account/create' component={Create} />
|
<Route path='/account/create' component={() =>
|
||||||
<Route path='/account/import' component={Import} />
|
<Create onAction={onAction} />
|
||||||
<Route exact path='/' component={() => {
|
} />
|
||||||
return requests.length
|
<Route path='/account/import' component={() =>
|
||||||
? <Signing accounts={accounts} onAction={_onAction} requests={requests} />
|
<Import onAction={onAction} />
|
||||||
: <Accounts accounts={accounts} />;
|
} />
|
||||||
}} />
|
<Route
|
||||||
|
exact path='/' component={() =>
|
||||||
|
requests.length
|
||||||
|
? <Signing accounts={accounts} onAction={onAction} requests={requests} />
|
||||||
|
: <Accounts accounts={accounts} onAction={onAction} />
|
||||||
|
} />
|
||||||
</Switch>
|
</Switch>
|
||||||
)}</Loading>
|
)}</Loading>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -22,6 +22,10 @@ function sendMessage (message: MessageTypes, request: any = {}): Promise<any> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function forgetAccount (address: string): Promise<boolean> {
|
||||||
|
return sendMessage('accounts.forget', { address });
|
||||||
|
}
|
||||||
|
|
||||||
export async function getAccounts (): Promise<Array<KeyringJson>> {
|
export async function getAccounts (): Promise<Array<KeyringJson>> {
|
||||||
return sendMessage('accounts.list');
|
return sendMessage('accounts.list');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
import { KeyringJson } from '@polkadot/ui-keyring/types';
|
import { KeyringJson } from '@polkadot/ui-keyring/types';
|
||||||
import { MessageTypes, MessageAccountCreate, MessageExtrinsicSign, MessageExtrinsicSignApprove, MessageExtrinsicSignCancel, MessageSeedCreate, MessageSeedCreate$Response, MessageSeedValidate, MessageSeedValidate$Response } from '../types';
|
import { MessageTypes, MessageAccountCreate, MessageExtrinsicSign, MessageExtrinsicSignApprove, MessageExtrinsicSignCancel, MessageSeedCreate, MessageSeedCreate$Response, MessageSeedValidate, MessageSeedValidate$Response, MessageAccountForget } from '../types';
|
||||||
|
|
||||||
import keyring from '@polkadot/ui-keyring';
|
import keyring from '@polkadot/ui-keyring';
|
||||||
import accountsObservable from '@polkadot/ui-keyring/observable/accounts';
|
import accountsObservable from '@polkadot/ui-keyring/observable/accounts';
|
||||||
@ -29,6 +29,12 @@ export default class Extension {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private accountsForget ({ address }: MessageAccountForget): boolean {
|
||||||
|
keyring.forgetAccount(address);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private accountsList (): Array<KeyringJson> {
|
private accountsList (): Array<KeyringJson> {
|
||||||
return Object
|
return Object
|
||||||
.values(accountsObservable.subject.getValue())
|
.values(accountsObservable.subject.getValue())
|
||||||
@ -104,6 +110,9 @@ export default class Extension {
|
|||||||
case 'accounts.create':
|
case 'accounts.create':
|
||||||
return this.accountsCreate(request);
|
return this.accountsCreate(request);
|
||||||
|
|
||||||
|
case 'accounts.forget':
|
||||||
|
return this.accountsForget(request);
|
||||||
|
|
||||||
case 'accounts.list':
|
case 'accounts.list':
|
||||||
return this.accountsList();
|
return this.accountsList();
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||||
|
|
||||||
export type MessageTypes = 'accounts.create' | 'accounts.list' | 'extrinsic.sign' | 'seed.create' | 'seed.validate' | 'signing.approve' | 'signing.cancel' | 'signing.requests';
|
export type MessageTypes = 'accounts.create' | 'accounts.forget' | 'accounts.list' | 'extrinsic.sign' | 'seed.create' | 'seed.validate' | 'signing.approve' | 'signing.cancel' | 'signing.requests';
|
||||||
|
|
||||||
export type MessageRequest = {
|
export type MessageRequest = {
|
||||||
id: number,
|
id: number,
|
||||||
@ -25,6 +25,10 @@ export type MessageAccountCreate = {
|
|||||||
type?: KeypairType
|
type?: KeypairType
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MessageAccountForget = {
|
||||||
|
address: string
|
||||||
|
};
|
||||||
|
|
||||||
export type MessageExtrinsicSignApprove = {
|
export type MessageExtrinsicSignApprove = {
|
||||||
id: number,
|
id: number,
|
||||||
password: string
|
password: string
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user