diff --git a/src/components/addresses/picker/Item.tsx b/src/components/addresses/picker/Item.tsx index 1467415..04ba315 100644 --- a/src/components/addresses/picker/Item.tsx +++ b/src/components/addresses/picker/Item.tsx @@ -66,6 +66,9 @@ // The wallet label is used for filtering the options "data-wallet-label": wallet?.label, + // The wallet itself is used for sorting the options + "data-wallet": wallet, + value: plainAddress }; } diff --git a/src/components/addresses/picker/options.ts b/src/components/addresses/picker/options.ts index efcf3c2..aca3732 100644 --- a/src/components/addresses/picker/options.ts +++ b/src/components/addresses/picker/options.ts @@ -3,11 +3,13 @@ // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt import { TFunction } from "react-i18next"; -import { WalletMap } from "@wallets"; +import { WalletMap, Wallet } from "@wallets"; import { getCategoryHeader } from "./Header"; import { getAddressItem } from "./Item"; +import { keyedNullSort } from "@utils"; + // Ant design's autocomplete/select/rc-select components don't seem to return // the proper types for these, so just provide our own types that are 'good // enough'. I have a feeling the AutoComplete/Select components just accept @@ -19,6 +21,7 @@ // For some reason, all these props get passed all the way to the DOM element! // Make this a 'valid' DOM prop "data-wallet-label"?: string; + "data-wallet"?: Wallet; value: string; } @@ -39,12 +42,24 @@ categoryCount: number; } +// Sort by balance descending, address ascending. Undefined values are pushed to +// the bottom by using keyedNullSort. Addresses are sorted ascending, though +// because of the implicit reversing behaviour of keyedNullSort, they need to +// be swapped here (i.e. sort with `b`, `a`). +const sortBalance = keyedNullSort("balance"); +const sortAddress = keyedNullSort("address", true); +const sortFn = (a: Wallet, b: Wallet): number => + sortBalance(a, b, "descend") || sortAddress(b, a); +const optionSortFn = (a: OptionValue, b: OptionValue): number => + sortFn(a["data-wallet"]!, b["data-wallet"]!); + /** Groups the wallets by category for autocompletion and generates their select * options. */ function getWalletOptions(wallets: WalletMap): WalletOptions { const categorised: Record = {}; const uncategorised: OptionValue[] = []; + // Go through all wallets and group them for (const id in wallets) { const wallet = wallets[id]; const { category } = wallet; @@ -61,7 +76,16 @@ } } - // TODO: sort the addresses too? + // Sort the wallets by balance descending, and then by address ascending. + // Since this uses keyedNullSort, which depends on ant-design's implicit + // reversing behaviour, the array is reversed after sorting here. As such, + // undefined balances will be pushed to the bottom. + for (const category in categorised) { + categorised[category].sort(optionSortFn); + categorised[category].reverse(); + } + uncategorised.sort(optionSortFn); + uncategorised.reverse(); return { categorised,