Skip to content

Commit

Permalink
Improve Address Book Search (#11350)
Browse files Browse the repository at this point in the history
* fix: improve address filtering logic for better visibility control

* feat: add visibility toggle for addresses in the contacts overview

* feat: enhance account name resolution with custom matchers
  • Loading branch information
ap211unitech authored Mar 3, 2025
1 parent db87ec3 commit e9de252
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 24 deletions.
51 changes: 32 additions & 19 deletions packages/page-addresses/src/Contacts/Address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { HexString } from '@polkadot/util/types';
import React, { useCallback, useEffect, useState } from 'react';

import { AddressInfo, AddressSmall, Button, ChainLock, Columar, Forget, LinkExternal, Menu, Popup, Table, Tags, TransferModal } from '@polkadot/react-components';
import { MATCHERS } from '@polkadot/react-components/AccountName';
import { useApi, useBalancesAll, useDeriveAccountInfo, useToggle } from '@polkadot/react-hooks';
import { keyring } from '@polkadot/ui-keyring';
import { isFunction } from '@polkadot/util';
Expand All @@ -19,7 +20,9 @@ interface Props {
className?: string;
filter: string;
isFavorite: boolean;
isVisible: boolean;
toggleFavorite: (address: string) => void;
toggleVisible: (address: string, isVisible: boolean) => void
}

const isEditable = true;
Expand Down Expand Up @@ -47,7 +50,7 @@ const BAL_OPTS_EXPANDED = {
vested: true
};

function Address ({ address, className = '', filter, isFavorite, toggleFavorite }: Props): React.ReactElement<Props> | null {
function Address ({ address, className = '', filter, isFavorite, isVisible, toggleFavorite, toggleVisible }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const api = useApi();
const info = useDeriveAccountInfo(address);
Expand All @@ -58,7 +61,6 @@ function Address ({ address, className = '', filter, isFavorite, toggleFavorite
const [genesisHash, setGenesisHash] = useState<string | null>(null);
const [isForgetOpen, setIsForgetOpen] = useState(false);
const [isTransferOpen, setIsTransferOpen] = useState(false);
const [isVisible, setIsVisible] = useState(true);
const [isExpanded, toggleIsExpanded] = useToggle(false);

const _setTags = useCallback(
Expand All @@ -75,16 +77,26 @@ function Address ({ address, className = '', filter, isFavorite, toggleFavorite
}, []);

useEffect((): void => {
const { identity, nickname } = info || {};
let known: string | null = null;

if (isFunction(api.apiIdentity.query.identity?.identityOf)) {
if (identity?.display) {
setAccName(identity.display);
for (let i = 0; known === null && i < MATCHERS.length; i++) {
known = MATCHERS[i](address);
}

if (known) {
setAccName(known);
} else {
const { identity, nickname } = info || {};

if (isFunction(api.apiIdentity.query.identity?.identityOf)) {
if (identity?.display) {
setAccName(identity.display);
}
} else if (nickname) {
setAccName(nickname);
}
} else if (nickname) {
setAccName(nickname);
}
}, [api, info]);
}, [address, api, info]);

useEffect((): void => {
const account = keyring.getAddress(address);
Expand All @@ -94,18 +106,19 @@ function Address ({ address, className = '', filter, isFavorite, toggleFavorite
}, [_setTags, address]);

useEffect((): void => {
if (filter.length === 0) {
setIsVisible(true);
} else {
const _filter = filter.toLowerCase();
const _filter = filter.trim().toLowerCase();
let isVisible = true;

setIsVisible(
tags.reduce((result: boolean, tag: string): boolean => {
return result || tag.toLowerCase().includes(_filter);
}, accName.toLowerCase().includes(_filter))
);
if (_filter.length !== 0) {
isVisible = keyring.encodeAddress(address, 0).toLowerCase().includes(_filter) ||
address.toLowerCase().includes(_filter) ||
tags.reduce((result: boolean, tag: string): boolean => {
return result || tag.toLowerCase().includes(_filter);
}, accName.toLowerCase().includes(_filter));
}
}, [accName, filter, tags]);

toggleVisible(address, isVisible);
}, [accName, address, filter, tags, toggleVisible]);

const _onGenesisChange = useCallback(
(genesisHash: HexString | null): void => {
Expand Down
17 changes: 13 additions & 4 deletions packages/page-addresses/src/Contacts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import type { ActionStatus } from '@polkadot/react-components/Status/types';

import React, { useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';

import { Button, FilterInput, styled, SummaryBox, Table } from '@polkadot/react-components';
import { useAddresses, useFavorites, useNextTick, useToggle } from '@polkadot/react-hooks';
Expand All @@ -12,7 +12,7 @@ import CreateModal from '../modals/Create.js';
import { useTranslation } from '../translate.js';
import Address from './Address.js';

interface SortedAddress { address: string; isFavorite: boolean }
interface SortedAddress { address: string; isFavorite: boolean, isVisible: boolean }

interface Props {
className?: string;
Expand All @@ -37,7 +37,7 @@ function Overview ({ className = '', onStatusChange }: Props): React.ReactElemen
useEffect((): void => {
setSortedAddresses(
allAddresses
.map((address): SortedAddress => ({ address, isFavorite: favorites.includes(address) }))
.map((address): SortedAddress => ({ address, isFavorite: favorites.includes(address), isVisible: true }))
.sort((a, b): number =>
a.isFavorite === b.isFavorite
? 0
Expand All @@ -48,6 +48,13 @@ function Overview ({ className = '', onStatusChange }: Props): React.ReactElemen
);
}, [allAddresses, favorites]);

const toggleVisible = useCallback((address: string, isVisible: boolean) => {
setSortedAddresses((account) => account
?.map((e) => e.address === address ? { ...e, isVisible } : e)
.sort((a, b) => a.isVisible === b.isVisible ? 0 : b.isVisible ? 1 : -1)
);
}, []);

return (
<StyledDiv className={className}>
{isCreateOpen && (
Expand Down Expand Up @@ -78,13 +85,15 @@ function Overview ({ className = '', onStatusChange }: Props): React.ReactElemen
header={headerRef.current}
isSplit
>
{isNextTick && sortedAddresses?.map(({ address, isFavorite }): React.ReactNode => (
{isNextTick && sortedAddresses?.map(({ address, isFavorite, isVisible }): React.ReactNode => (
<Address
address={address}
filter={filterOn}
isFavorite={isFavorite}
isVisible={isVisible}
key={address}
toggleFavorite={toggleFavorite}
toggleVisible={toggleVisible}
/>
))}
</Table>
Expand Down
2 changes: 1 addition & 1 deletion packages/react-components/src/AccountName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function createNumMatcher (prefix: string, name: string, add?: string): AddrMatc
};
}

const MATCHERS: AddrMatcher[] = [
export const MATCHERS: AddrMatcher[] = [
createAllMatcher('modlpy/socie', 'Society'),
createAllMatcher('modlpy/trsry', 'Treasury'),
createAllMatcher('modlpy/xcmch', 'XCM'),
Expand Down

0 comments on commit e9de252

Please sign in to comment.