From 4cc31fc8565cb0a075024e34f3ab15d82c2c75be Mon Sep 17 00:00:00 2001 From: Jaco Date: Mon, 7 Feb 2022 14:27:36 +0100 Subject: [PATCH] Ensure InputAddress is de-deuped prior to display (#6934) --- CHANGELOG.md | 8 +++++++ .../src/InputAddress/index.tsx | 19 +++++++++++++-- packages/react-hooks/src/useAccounts.ts | 24 +++++++++++-------- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82b0504950..9c7adb5d9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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: diff --git a/packages/react-components/src/InputAddress/index.tsx b/packages/react-components/src/InputAddress/index.tsx index 7f7158f895..4773a825ee 100644 --- a/packages/react-components/src/InputAddress/index.tsx +++ b/packages/react-components/src/InputAddress/index.tsx @@ -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((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 { public override state: State = {}; @@ -161,7 +176,7 @@ class InputAddress extends React.PureComponent { : (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 { 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 => { diff --git a/packages/react-hooks/src/useAccounts.ts b/packages/react-hooks/src/useAccounts.ts index 5d942bd565..9a29acb6ff 100644 --- a/packages/react-hooks/src/useAccounts.ts +++ b/packages/react-hooks/src/useAccounts.ts @@ -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(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);