Ensure InputAddress is de-deuped prior to display (#6934)

This commit is contained in:
Jaco 2022-02-07 14:27:36 +01:00 committed by GitHub
parent 58f7313f09
commit 4cc31fc856
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 12 deletions

View File

@ -1,5 +1,13 @@
# CHANGELOG
## master
Changes:
- Ensure `InputAddress` is de-deuped prior to display (address/accounts)
- Disable unreachable endpoints
## 0.105.1 Feb 7, 2022
Contributed:

View File

@ -116,6 +116,21 @@ function setLastValue (type: KeyringOption$Type = DEFAULT_TYPE, value: string):
store.set(STORAGE_KEY, options);
}
function dedupe (options: Option[]): Option[] {
return options.reduce<Option[]>((all, o, index) => {
const hasDupe = all.some(({ key }, eindex) =>
eindex !== index &&
key === o.key
);
if (!hasDupe) {
all.push(o);
}
return all;
}, []);
}
class InputAddress extends React.PureComponent<Props, State> {
public override state: State = {};
@ -161,7 +176,7 @@ class InputAddress extends React.PureComponent<Props, State> {
: (lastOption && lastOption.value)
);
const actualOptions: Option[] = options
? options.map((o): Option => createItem(o))
? dedupe(options.map((o) => createItem(o)))
: isDisabled && actualValue
? [createOption(actualValue)]
: this.getFiltered();
@ -228,7 +243,7 @@ class InputAddress extends React.PureComponent<Props, State> {
return !optionsAll
? []
: optionsAll[type].filter(({ value }) => !filter || (!!value && filter.includes(value)));
: dedupe(optionsAll[type]).filter(({ value }) => !filter || (!!value && filter.includes(value)));
}
private onChange = (address: string): void => {

View File

@ -1,6 +1,8 @@
// Copyright 2017-2022 @polkadot/react-hooks authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import { useEffect, useState } from 'react';
import { keyring } from '@polkadot/ui-keyring';
@ -20,21 +22,23 @@ export interface UseAccounts {
const EMPTY: UseAccounts = { allAccounts: [], allAccountsHex: [], areAccountsLoaded: false, hasAccounts: false, isAccount: () => false };
function extractAccounts (accounts: SubjectInfo = {}): UseAccounts {
const allAccounts = Object.keys(accounts);
const allAccountsHex = allAccounts.map((a) => u8aToHex(decodeAddress(a)));
const hasAccounts = allAccounts.length !== 0;
const isAccount = (address?: string | null) => !!address && allAccounts.includes(address);
return { allAccounts, allAccountsHex, areAccountsLoaded: true, hasAccounts, isAccount };
}
function useAccountsImpl (): UseAccounts {
const mountedRef = useIsMountedRef();
const [state, setState] = useState<UseAccounts>(EMPTY);
useEffect((): () => void => {
const subscription = keyring.accounts.subject.subscribe((accounts): void => {
if (mountedRef.current) {
const allAccounts = accounts ? Object.keys(accounts) : [];
const allAccountsHex = allAccounts.map((a) => u8aToHex(decodeAddress(a)));
const hasAccounts = allAccounts.length !== 0;
const isAccount = (address?: string | null) => !!address && allAccounts.includes(address);
setState({ allAccounts, allAccountsHex, areAccountsLoaded: true, hasAccounts, isAccount });
}
});
const subscription = keyring.accounts.subject.subscribe((accounts = {}) =>
mountedRef.current && setState(extractAccounts(accounts))
);
return (): void => {
setTimeout(() => subscription.unsubscribe(), 0);