diff --git a/components/dataViews/HashView.tsx b/components/dataViews/HashView.tsx index 2f17c62..a9417f9 100644 --- a/components/dataViews/HashView.tsx +++ b/components/dataViews/HashView.tsx @@ -1,6 +1,4 @@ -import React from "react"; - -import { abbreviateLongString } from "../../lib/displayHelpers"; +import { ellideMiddle } from "../../lib/displayHelpers"; import CopyAndPaste from "./CopyAndPaste"; interface Props { @@ -10,7 +8,7 @@ interface Props { const HashView = (props: Props) => (
-
{props.abbreviate ? abbreviateLongString(props.hash) : props.hash}
+
{props.abbreviate ? ellideMiddle(props.hash, 12) : props.hash}
diff --git a/lib/displayHelpers.ts b/lib/displayHelpers.ts index 97a90ae..1155cc9 100644 --- a/lib/displayHelpers.ts +++ b/lib/displayHelpers.ts @@ -4,21 +4,15 @@ import { fromBase64, fromBech32, toBase64, toBech32 } from "@cosmjs/encoding"; import { Decimal } from "@cosmjs/math"; import { ChainInfo } from "../types"; -/** - * Abbreviates long strings, typically used for - * addresses and transaction hashes. - * - * @param {string} longString The string to abbreviate. - * @return {string} The abbreviated string. - */ -const abbreviateLongString = (longString: string) => { - if (longString.length < 13) { - // no need to abbreviate - return longString; +function ellideMiddle(str: string, maxOutLen: number): string { + if (str.length <= maxOutLen) { + return str; } - - return longString.slice(0, 5) + "..." + longString.slice(-5); -}; + const ellide = "…"; + const frontLen = Math.ceil((maxOutLen - ellide.length) / 2); + const tailLen = Math.floor((maxOutLen - ellide.length) / 2); + return str.slice(0, frontLen) + ellide + str.slice(str.length - tailLen, str.length); +} // NARROW NO-BREAK SPACE (U+202F) const thinSpace = "\u202F"; @@ -49,12 +43,21 @@ const printableCoin = (coin: Coin, chainInfo: ChainInfo) => { } // Auto-convert leading "u"s - if (coin.denom?.startsWith("u")) { + if (coin.denom.startsWith("u")) { const value = Decimal.fromAtomics(coin.amount ?? "0", 6).toString(); const ticker = coin.denom.slice(1).toUpperCase(); return value + thinSpace + ticker; } + // Ellide IBC tokens + if (coin.denom.startsWith("ibc/")) { + const value = coin.amount; + const hash = coin.denom.slice(4); + const ellidedHash = ellideMiddle(hash, 11); + const ticker = `ibc/${ellidedHash}`; + return value + thinSpace + ticker; + } + // Fallback to plain coin display return coin.amount + thinSpace + coin.denom; }; @@ -150,7 +153,7 @@ const explorerLinkTx = (link: string, hash: string) => { }; export { - abbreviateLongString, + ellideMiddle, printableCoin, printableCoins, exampleAddress, diff --git a/pages/multi/[address]/index.tsx b/pages/multi/[address]/index.tsx index 8fc3b5f..6e4484c 100644 --- a/pages/multi/[address]/index.tsx +++ b/pages/multi/[address]/index.tsx @@ -29,7 +29,7 @@ function participantPubkeysFromMultisig( const Multipage = () => { const { state } = useAppContext(); const [txView, setTxView] = useState(null); - const [holdings, setHoldings] = useState(null); + const [holdings, setHoldings] = useState([]); const [multisigAddress, setMultisigAddress] = useState(""); const [accountOnChain, setAccountOnChain] = useState(null); const [pubkey, setPubkey] = useState(); @@ -47,7 +47,7 @@ const Multipage = () => { assert(state.chain.nodeAddress, "Node address missing"); const client = await StargateClient.connect(state.chain.nodeAddress); assert(state.chain.denom, "denom missing"); - const tempHoldings = await client.getBalance(address, state.chain.denom); + const tempHoldings = await client.getAllBalances(address); setHoldings(tempHoldings); const result = await getMultisigAccount(address, client); setPubkey(result[0]);