From ac30fac7fe1fbcb76aa9f68b12a8a8e196add94f Mon Sep 17 00:00:00 2001
From: 0age <37939117+0age@users.noreply.github.com>
Date: Tue, 10 Dec 2024 22:45:28 -0800
Subject: [PATCH] solve the rerendering fiasco
---
frontend/src/App.tsx | 4 +-
frontend/src/components/BalanceDisplay.tsx | 410 ++++++++++--------
.../src/components/FinalizationThreshold.tsx | 4 +-
frontend/src/components/HealthCheck.tsx | 4 +-
.../src/components/WithdrawalCountdown.tsx | 64 +--
frontend/src/context/NotificationProvider.tsx | 87 ++--
frontend/src/hooks/useBalanceDisplay.ts | 182 ++++----
frontend/src/hooks/useBalances.ts | 6 +-
frontend/src/hooks/useCompact.ts | 2 +-
frontend/src/hooks/useGraphQL.ts | 8 +-
frontend/src/hooks/useResourceLocks.ts | 6 +-
11 files changed, 408 insertions(+), 369 deletions(-)
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index a1d6ea7..4f35e75 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -94,9 +94,7 @@ function AppContent() {
{/* Health Check Status */}
-
+
{/* Only show these components if the server is healthy */}
diff --git a/frontend/src/components/BalanceDisplay.tsx b/frontend/src/components/BalanceDisplay.tsx
index d8bc3ac..76ab93e 100644
--- a/frontend/src/components/BalanceDisplay.tsx
+++ b/frontend/src/components/BalanceDisplay.tsx
@@ -12,10 +12,12 @@ import {
formatLockId,
getChainName,
} from '../hooks/useBalanceDisplay';
+import type { Balance } from '../hooks/useBalances';
+import type { ResourceLockBalance } from '../hooks/useResourceLocks';
interface BalanceItemProps {
- balance: any;
- resourceLock: any;
+ balance: Balance;
+ resourceLock: ResourceLockBalance | undefined;
onInitiateWithdrawal: (lockId: string) => void;
onDisableWithdrawal: (chainId: string, lockId: string) => void;
onExecuteWithdrawal: (
@@ -30,30 +32,38 @@ interface BalanceItemProps {
}
// Memoized balance value component
-const BalanceValue = memo(function BalanceValue({
- balance,
- decimals
-}: {
- balance: string,
- decimals: number
-}) {
- const formattedValue = useMemo(() => {
- return formatUnits(BigInt(balance), decimals);
- }, [balance, decimals]);
+const BalanceValue = memo(
+ function BalanceValue({
+ balance,
+ decimals,
+ }: {
+ balance: string;
+ decimals: number;
+ }) {
+ const formattedValue = useMemo(() => {
+ return formatUnits(BigInt(balance), decimals);
+ }, [balance, decimals]);
- return formattedValue;
-}, (prev, next) => prev.balance === next.balance && prev.decimals === next.decimals);
+ return formattedValue;
+ },
+ (prev, next) =>
+ prev.balance === next.balance && prev.decimals === next.decimals
+);
// Helper function to compare resourceLock objects
-const areResourceLocksEqual = (prev: any, next: any) => {
+const areResourceLocksEqual = (
+ prev: ResourceLockBalance | undefined,
+ next: ResourceLockBalance | undefined
+) => {
if (!prev || !next) return prev === next;
-
+
// Compare critical fields that affect rendering
- const tokenEqual =
+ const tokenEqual =
prev.resourceLock.token.name === next.resourceLock.token.name &&
prev.resourceLock.token.symbol === next.resourceLock.token.symbol &&
prev.resourceLock.token.decimals === next.resourceLock.token.decimals &&
- prev.resourceLock.token.tokenAddress === next.resourceLock.token.tokenAddress;
+ prev.resourceLock.token.tokenAddress ===
+ next.resourceLock.token.tokenAddress;
const resourceLockEqual =
prev.balance === next.balance &&
@@ -61,137 +71,158 @@ const areResourceLocksEqual = (prev: any, next: any) => {
prev.withdrawableAt === next.withdrawableAt &&
prev.resourceLock.resetPeriod === next.resourceLock.resetPeriod &&
prev.resourceLock.isMultichain === next.resourceLock.isMultichain &&
- prev.resourceLock.lockId === next.resourceLock.lockId &&
+ prev.resourceLock.token.tokenAddress ===
+ next.resourceLock.token.tokenAddress &&
prev.chainId === next.chainId;
return tokenEqual && resourceLockEqual;
};
-const BalanceItem = memo(function BalanceItem({
- balance,
- resourceLock,
- onInitiateWithdrawal,
- onDisableWithdrawal,
- onExecuteWithdrawal,
- sessionToken,
-}: BalanceItemProps) {
- const withdrawableAt = parseInt(balance.withdrawableAt || '0');
- const canExecuteWithdrawal = useMemo(() => {
- const currentTime = Math.floor(Date.now() / 1000);
- return parseInt(balance.withdrawalStatus.toString()) !== 0 && withdrawableAt <= currentTime;
- }, [balance.withdrawalStatus, withdrawableAt]);
+const BalanceItem = memo(
+ function BalanceItem({
+ balance,
+ resourceLock,
+ onInitiateWithdrawal,
+ onDisableWithdrawal,
+ onExecuteWithdrawal,
+ sessionToken,
+ }: BalanceItemProps) {
+ const withdrawableAt = parseInt(balance.withdrawableAt || '0');
+ const canExecuteWithdrawal = useMemo(() => {
+ const currentTime = Math.floor(Date.now() / 1000);
+ return (
+ parseInt(balance.withdrawalStatus.toString()) !== 0 &&
+ withdrawableAt <= currentTime
+ );
+ }, [balance.withdrawalStatus, withdrawableAt]);
- // Memoize handlers
- const handleForceWithdraw = useCallback(() => {
- onInitiateWithdrawal(balance.lockId);
- }, [balance.lockId, onInitiateWithdrawal]);
+ // Memoize handlers
+ const handleForceWithdraw = useCallback(() => {
+ onInitiateWithdrawal(balance.lockId);
+ }, [balance.lockId, onInitiateWithdrawal]);
- const handleDisableForceWithdraw = useCallback(() => {
- onDisableWithdrawal(balance.chainId, balance.lockId);
- }, [balance.chainId, balance.lockId, onDisableWithdrawal]);
+ const handleDisableForceWithdraw = useCallback(() => {
+ onDisableWithdrawal(balance.chainId, balance.lockId);
+ }, [balance.chainId, balance.lockId, onDisableWithdrawal]);
- const handleExecuteWithdrawal = useCallback(() => {
- onExecuteWithdrawal(
+ const handleExecuteWithdrawal = useCallback(() => {
+ onExecuteWithdrawal(
+ balance.chainId,
+ balance.lockId,
+ resourceLock?.balance || '0',
+ balance.token?.name || 'Token',
+ balance.token?.decimals || 18,
+ balance.token?.symbol || ''
+ );
+ }, [
balance.chainId,
balance.lockId,
- resourceLock?.balance || '0',
- balance.token?.name || 'Token',
- balance.token?.decimals || 18,
- balance.token?.symbol || ''
- );
- }, [
- balance.chainId,
- balance.lockId,
- balance.token?.decimals,
- balance.token?.name,
- balance.token?.symbol,
- onExecuteWithdrawal,
- resourceLock?.balance,
- ]);
+ balance.token?.decimals,
+ balance.token?.name,
+ balance.token?.symbol,
+ onExecuteWithdrawal,
+ resourceLock?.balance,
+ ]);
- return (
-
- {/* Header with Token Info and Chain Name */}
-
-
- {balance.token?.name} ({balance.token?.symbol})
-
-
-
Chain: {getChainName(balance.chainId)}
-
- Lock ID:{' '}
-
{formatLockId(balance.lockId)}
+ return (
+
+ {/* Header with Token Info and Chain Name */}
+
+
+ {balance.token?.name} ({balance.token?.symbol})
+
+
+
Chain: {getChainName(balance.chainId)}
+
+ Lock ID:{' '}
+ {formatLockId(balance.lockId)}
+
-
- {/* Resource Lock Properties */}
-
- {balance.resourceLock?.resetPeriod &&
- balance.resourceLock.resetPeriod > 0 && (
+ {/* Resource Lock Properties */}
+
+ {balance.resourceLock?.resetPeriod &&
+ balance.resourceLock.resetPeriod > 0 && (
+
+ Reset Period:{' '}
+ {formatResetPeriod(balance.resourceLock.resetPeriod)}
+
+ )}
+
+ {balance.resourceLock?.isMultichain && (
- Reset Period: {formatResetPeriod(balance.resourceLock.resetPeriod)}
+ Multichain
)}
-
- {balance.resourceLock?.isMultichain && (
-
- Multichain
-
- )}
- {balance.withdrawalStatus === 0 && (
-
- Active
-
- )}
- {balance.withdrawalStatus !== 0 && (
-
- )}
-
+ {balance.withdrawalStatus === 0 && (
+
+ Active
+
+ )}
+ {balance.withdrawalStatus !== 0 && (
+
+ )}
+
- {/* Balances Grid */}
-
- {/* Left side - Current, Allocatable, and Allocated */}
-
-
-
Current Balance
-
- {resourceLock && (
-
- )}
- {balance.token?.symbol && (
-
- {balance.token.symbol}
-
- )}
+ {/* Balances Grid */}
+
+ {/* Left side - Current, Allocatable, and Allocated */}
+
+
+
Current Balance
+
+ {resourceLock && (
+
+ )}
+ {balance.token?.symbol && (
+
+ {balance.token.symbol}
+
+ )}
+
-
-
-
Finalized Balance
-
- {balance.formattedAllocatableBalance ||
- balance.allocatableBalance}
- {balance.token?.symbol && (
-
- {balance.token.symbol}
-
- )}
+
+
Finalized Balance
+
+ {balance.formattedAllocatableBalance ||
+ balance.allocatableBalance}
+ {balance.token?.symbol && (
+
+ {balance.token.symbol}
+
+ )}
+
+
+
+
+
Currently Allocated
+
+ {balance.formattedAllocatedBalance || balance.allocatedBalance}
+ {balance.token?.symbol && (
+
+ {balance.token.symbol}
+
+ )}
+
-
-
Currently Allocated
-
- {balance.formattedAllocatedBalance || balance.allocatedBalance}
+ {/* Right side - Emphasized available to allocate */}
+
+
Available to Allocate
+
+ {balance.formattedAvailableBalance ||
+ balance.balanceAvailableToAllocate}
{balance.token?.symbol && (
-
+
{balance.token.symbol}
)}
@@ -199,76 +230,70 @@ const BalanceItem = memo(function BalanceItem({
- {/* Right side - Emphasized available to allocate */}
-
-
Available to Allocate
-
- {balance.formattedAvailableBalance ||
- balance.balanceAvailableToAllocate}
- {balance.token?.symbol && (
-
- {balance.token.symbol}
-
- )}
+ {/* Transfer and Withdrawal Actions */}
+ {resourceLock && (
+
+
+
+ {canExecuteWithdrawal && (
+
+ )}
+
-
+ )}
+ );
+ },
+ (prevProps, nextProps) => {
+ // Enhanced comparison function for memo
+ const balanceEqual =
+ prevProps.balance.lockId === nextProps.balance.lockId &&
+ prevProps.balance.chainId === nextProps.balance.chainId &&
+ prevProps.balance.withdrawalStatus ===
+ nextProps.balance.withdrawalStatus &&
+ prevProps.balance.withdrawableAt === nextProps.balance.withdrawableAt &&
+ prevProps.balance.formattedAllocatableBalance ===
+ nextProps.balance.formattedAllocatableBalance &&
+ prevProps.balance.formattedAllocatedBalance ===
+ nextProps.balance.formattedAllocatedBalance &&
+ prevProps.balance.formattedAvailableBalance ===
+ nextProps.balance.formattedAvailableBalance;
- {/* Transfer and Withdrawal Actions */}
- {resourceLock && (
-
-
-
- {canExecuteWithdrawal && (
-
- )}
-
-
- )}
-
- );
-}, (prevProps, nextProps) => {
- // Enhanced comparison function for memo
- const balanceEqual =
- prevProps.balance.lockId === nextProps.balance.lockId &&
- prevProps.balance.chainId === nextProps.balance.chainId &&
- prevProps.balance.withdrawalStatus === nextProps.balance.withdrawalStatus &&
- prevProps.balance.withdrawableAt === nextProps.balance.withdrawableAt &&
- prevProps.balance.formattedAllocatableBalance === nextProps.balance.formattedAllocatableBalance &&
- prevProps.balance.formattedAllocatedBalance === nextProps.balance.formattedAllocatedBalance &&
- prevProps.balance.formattedAvailableBalance === nextProps.balance.formattedAvailableBalance;
-
- // Use the helper function to deeply compare resourceLocks
- const resourceLockEqual = areResourceLocksEqual(prevProps.resourceLock, nextProps.resourceLock);
+ // Use the helper function to deeply compare resourceLocks
+ const resourceLockEqual = areResourceLocksEqual(
+ prevProps.resourceLock,
+ nextProps.resourceLock
+ );
- return (
- balanceEqual &&
- resourceLockEqual &&
- prevProps.sessionToken === nextProps.sessionToken
- );
-});
+ return (
+ balanceEqual &&
+ resourceLockEqual &&
+ prevProps.sessionToken === nextProps.sessionToken
+ );
+ }
+);
export function BalanceDisplay({
sessionToken,
@@ -370,7 +395,8 @@ export function BalanceDisplay({
- {localStorage.getItem(`session-${address}`) || 'No session found'}
+ {localStorage.getItem(`session-${address}`) ||
+ 'No session found'}