From 77b8da5e6c413f8dd42ab9185183eee58ae7753c Mon Sep 17 00:00:00 2001 From: kj16609 Date: Sun, 15 Dec 2024 14:21:09 -0500 Subject: [PATCH 1/5] Implements loading indicator when Kaspa's balance is undefined --- src/components/TotalWalletValue.tsx | 17 ++++++++++++++--- src/contexts/kaspa/KaspaContext.ts | 1 + src/contexts/kaspa/KaspaProvider.tsx | 3 +++ src/contexts/kaspa/types.ts | 1 + src/wallet/Account.ts | 4 ++++ src/wallet/messaging/RequestMappings.ts | 2 ++ src/wallet/messaging/ResponseMappings.ts | 1 + src/wallet/messaging/Router.ts | 1 + 8 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/components/TotalWalletValue.tsx b/src/components/TotalWalletValue.tsx index 43dbfbb..f6474ac 100644 --- a/src/components/TotalWalletValue.tsx +++ b/src/components/TotalWalletValue.tsx @@ -1,5 +1,6 @@ import React from 'react' import { formatNumberAbbreviated } from '@/utils/formatting' +import useKaspa from '@/hooks/contexts/useKaspa' interface TotalValueProps { totalValue: number @@ -8,10 +9,20 @@ interface TotalValueProps { const TotalWalletValue: React.FC = ({ totalValue }) => { const formattedCurrencyValue = formatNumberAbbreviated(totalValue, true) + const { kaspa } = useKaspa() + return ( -

- {formattedCurrencyValue} -

+ <> + {kaspa.balanceValid ? ( +

+ {formattedCurrencyValue} +

+ ) : ( + + Tokens loading... + + )} + ) } diff --git a/src/contexts/kaspa/KaspaContext.ts b/src/contexts/kaspa/KaspaContext.ts index 5284ea1..8ee264f 100644 --- a/src/contexts/kaspa/KaspaContext.ts +++ b/src/contexts/kaspa/KaspaContext.ts @@ -9,6 +9,7 @@ export const defaultState: IKaspa = { connected: false, addresses: [], balance: 0, + balanceValid: false, utxos: [], provider: '', } diff --git a/src/contexts/kaspa/KaspaProvider.tsx b/src/contexts/kaspa/KaspaProvider.tsx index 75dc559..a1fa4d4 100644 --- a/src/contexts/kaspa/KaspaProvider.tsx +++ b/src/contexts/kaspa/KaspaProvider.tsx @@ -117,6 +117,7 @@ export function KaspaProvider({ children }: { children: ReactNode }) { case 'account:balance': dispatch({ type: 'balance', payload: message.data }) dispatch({ type: 'utxos', payload: await request('account:utxos', []) }) + dispatch({ type: 'balanceValid', payload: true }) break case 'account:addresses': dispatch({ @@ -140,6 +141,8 @@ export function KaspaProvider({ children }: { children: ReactNode }) { dispatch({ type: 'connected', payload: connected }) const balance = await request('account:balance', []) dispatch({ type: 'balance', payload: balance }) + const balanceValid = await request('account:balanceValid', []) + dispatch({ type: 'balanceValid', payload: balanceValid }) const utxos = await request('account:utxos', []) dispatch({ type: 'utxos', payload: utxos }) const addresses = await request('account:addresses', []) diff --git a/src/contexts/kaspa/types.ts b/src/contexts/kaspa/types.ts index ec93e37..7e71dee 100644 --- a/src/contexts/kaspa/types.ts +++ b/src/contexts/kaspa/types.ts @@ -8,6 +8,7 @@ export interface IKaspa { connected: boolean addresses: string[] balance: number + balanceValid: boolean utxos: UTXO[] provider: string } diff --git a/src/wallet/Account.ts b/src/wallet/Account.ts index 25a0ead..74e725a 100644 --- a/src/wallet/Account.ts +++ b/src/wallet/Account.ts @@ -59,6 +59,10 @@ export default class Account extends EventEmitter { return Number(this.context.balance?.mature ?? 0) / 1e8 } + get balanceValid() { + return this.context.balance != undefined + } + get UTXOs() { const mapUTXO = (utxo: UtxoEntryReference, mature: boolean) => ({ amount: Number(utxo.amount) / 1e8, diff --git a/src/wallet/messaging/RequestMappings.ts b/src/wallet/messaging/RequestMappings.ts index 91bc2d0..db66339 100644 --- a/src/wallet/messaging/RequestMappings.ts +++ b/src/wallet/messaging/RequestMappings.ts @@ -18,6 +18,7 @@ export interface RequestMappings { 'node:submit': [string[]] 'account:addresses': [] 'account:balance': [] + 'account:balanceValid': [] 'account:utxos': [] 'account:estimateKaspaTransactionFee': [[string, string][], number, string] 'account:create': [[string, string][], number, string, CustomInput[]?] @@ -45,6 +46,7 @@ export interface EventMappings { 'node:connection': boolean 'node:network': string 'account:balance': number + 'account:balanceValid': boolean 'account:addresses': string[] 'provider:connection': string } diff --git a/src/wallet/messaging/ResponseMappings.ts b/src/wallet/messaging/ResponseMappings.ts index 769c8f7..d99ab9b 100644 --- a/src/wallet/messaging/ResponseMappings.ts +++ b/src/wallet/messaging/ResponseMappings.ts @@ -18,6 +18,7 @@ export interface ResponseMappings { 'node:submit': string[] 'account:addresses': string[] 'account:balance': number + 'account:balanceValid': boolean 'account:utxos': UTXO[] 'account:estimateKaspaTransactionFee': string 'account:create': [string[], string] diff --git a/src/wallet/messaging/Router.ts b/src/wallet/messaging/Router.ts index e52da00..f757856 100644 --- a/src/wallet/messaging/Router.ts +++ b/src/wallet/messaging/Router.ts @@ -38,6 +38,7 @@ export default class Router { 'node:submit': (transactions) => node.submit(transactions), 'account:addresses': () => account.addresses.receiveAddresses, 'account:balance': () => account.balance, + 'account:balanceValid': () => account.balanceValid, 'account:utxos': () => account.UTXOs, 'account:estimateKaspaTransactionFee': (outputs, feeRate, fee) => account.transactions.estimateKaspaTransactionFee(outputs, feeRate, fee), From dc630ba77f3ee495d1241a34613462a784f320ba Mon Sep 17 00:00:00 2001 From: kj16609 Date: Fri, 20 Dec 2024 13:47:10 -0500 Subject: [PATCH 2/5] Replaces loading message with LoadingPlaceholder --- src/components/TotalWalletValue.tsx | 5 ++--- src/components/animations/LoadingPlaceholder.tsx | 7 +++++++ src/pages/Wallet/Mint/CreateMint/LoadingCreateMint.tsx | 5 +---- 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 src/components/animations/LoadingPlaceholder.tsx diff --git a/src/components/TotalWalletValue.tsx b/src/components/TotalWalletValue.tsx index f6474ac..000c4e0 100644 --- a/src/components/TotalWalletValue.tsx +++ b/src/components/TotalWalletValue.tsx @@ -1,6 +1,7 @@ import React from 'react' import { formatNumberAbbreviated } from '@/utils/formatting' import useKaspa from '@/hooks/contexts/useKaspa' +import LoadingPlaceholder from '@/components/animations/LoadingPlaceholder' interface TotalValueProps { totalValue: number @@ -18,9 +19,7 @@ const TotalWalletValue: React.FC = ({ totalValue }) => { {formattedCurrencyValue} ) : ( - - Tokens loading... - + )} ) diff --git a/src/components/animations/LoadingPlaceholder.tsx b/src/components/animations/LoadingPlaceholder.tsx new file mode 100644 index 0000000..b667cb2 --- /dev/null +++ b/src/components/animations/LoadingPlaceholder.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +const LoadingPlaceholder: React.FC<{ className: string }> = ({ className }) => ( +
+) + +export default LoadingPlaceholder \ No newline at end of file diff --git a/src/pages/Wallet/Mint/CreateMint/LoadingCreateMint.tsx b/src/pages/Wallet/Mint/CreateMint/LoadingCreateMint.tsx index cfbb913..2c6f8fd 100644 --- a/src/pages/Wallet/Mint/CreateMint/LoadingCreateMint.tsx +++ b/src/pages/Wallet/Mint/CreateMint/LoadingCreateMint.tsx @@ -1,8 +1,5 @@ import React from 'react' - -const LoadingPlaceholder: React.FC<{ className: string }> = ({ className }) => ( -
-) +import LoadingPlaceholder from '@/components/animations/LoadingPlaceholder' export default function LoadingCreateMint() { return ( From a8be299356629ba2d7c92ded781c3e3537bc3ee3 Mon Sep 17 00:00:00 2001 From: kj16609 Date: Fri, 20 Dec 2024 16:19:15 -0500 Subject: [PATCH 3/5] Makes crypto list hide with loading symbol when loading total balance --- src/pages/Wallet/CryptoList.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pages/Wallet/CryptoList.tsx b/src/pages/Wallet/CryptoList.tsx index 08e8f3b..b81324a 100644 --- a/src/pages/Wallet/CryptoList.tsx +++ b/src/pages/Wallet/CryptoList.tsx @@ -7,6 +7,8 @@ import ErrorMessage from '@/components/messages/ErrorMessage' import { useLocation, useNavigate } from 'react-router-dom' import { useKaspaPrice } from '@/hooks/ghost/usePrice' import useVisibleTokens from '@/hooks/wallet/useVisibleTokens' +import useKaspa from '@/hooks/contexts/useKaspa' +import Spinner from '@/components/loaders/Spinner' interface CryptoListProps { onTotalValueChange: (value: number) => void @@ -21,6 +23,7 @@ const CryptoList: React.FC = ({ onTotalValueChange }) => { const kasPrice = kaspaPrice.data ?? 0 const visibleTokens = useVisibleTokens(tokens) + const { kaspa } = useKaspa() useTotalValueCalculation(visibleTokens, kasPrice, onTotalValueChange) @@ -36,7 +39,7 @@ const CryptoList: React.FC = ({ onTotalValueChange }) => {
{visibleTokens.length === 0 ? (

None

- ) : ( + ) : kaspa.balanceValid ? (
    {visibleTokens.map((token) => (
  • = ({ onTotalValueChange }) => {
  • ))}
+ ) : ( + )} {walletError && ( From 644949601ad58d617202665b1c2a1d40b566016c Mon Sep 17 00:00:00 2001 From: kj16609 Date: Fri, 20 Dec 2024 16:19:53 -0500 Subject: [PATCH 4/5] Fixes loading effect for total balance to prevent items from jumping around --- src/components/TotalWalletValue.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/TotalWalletValue.tsx b/src/components/TotalWalletValue.tsx index 000c4e0..9e3edb2 100644 --- a/src/components/TotalWalletValue.tsx +++ b/src/components/TotalWalletValue.tsx @@ -14,13 +14,13 @@ const TotalWalletValue: React.FC = ({ totalValue }) => { return ( <> - {kaspa.balanceValid ? ( -

- {formattedCurrencyValue} -

- ) : ( - - )} +

+ {kaspa.balanceValid ? ( + <> {formattedCurrencyValue} + ) : ( + + )} +

) } From 6112a34f461b10b35048d498e5f756ce02673ff1 Mon Sep 17 00:00:00 2001 From: kj16609 Date: Fri, 20 Dec 2024 16:43:49 -0500 Subject: [PATCH 5/5] Changes loading spinner to loading placeholder for each item --- src/pages/Wallet/CryptoList.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pages/Wallet/CryptoList.tsx b/src/pages/Wallet/CryptoList.tsx index b81324a..c0ff7a6 100644 --- a/src/pages/Wallet/CryptoList.tsx +++ b/src/pages/Wallet/CryptoList.tsx @@ -8,7 +8,7 @@ import { useLocation, useNavigate } from 'react-router-dom' import { useKaspaPrice } from '@/hooks/ghost/usePrice' import useVisibleTokens from '@/hooks/wallet/useVisibleTokens' import useKaspa from '@/hooks/contexts/useKaspa' -import Spinner from '@/components/loaders/Spinner' +import LoadingPlaceholder from '@/components/animations/LoadingPlaceholder' interface CryptoListProps { onTotalValueChange: (value: number) => void @@ -39,7 +39,7 @@ const CryptoList: React.FC = ({ onTotalValueChange }) => {
{visibleTokens.length === 0 ? (

None

- ) : kaspa.balanceValid ? ( + ) : (
    {visibleTokens.map((token) => (
  • = ({ onTotalValueChange }) => { onClick={() => handleTokenClick(token)} className="w-full text-left transition-colors hover:cursor-pointer rounded-lg" > - + {kaspa.balanceValid ? ( + + ) : ( + + )}
  • ))}
- ) : ( - )} {walletError && (