From 125f50a830b1bdfc19eb621819ec40c58aa4c335 Mon Sep 17 00:00:00 2001 From: Ben Wolski <570819+benwolski@users.noreply.github.com> Date: Sat, 9 Nov 2024 20:23:23 -0500 Subject: [PATCH 1/4] remove reload on portfolio when wallet not connected --- src/App/hooks/useAppChain.ts | 3 +- .../Portfolio/PortfolioTabs/PortfolioTabs.tsx | 74 ++++++++++++------- .../Trade/TradeTabs/Orders/Orders.tsx | 3 +- .../Trade/TradeTabs/Ranges/Ranges.tsx | 8 +- .../TradeTabs/Transactions/Transactions.tsx | 63 ++++++++-------- .../platformAmbient/Portfolio/Portfolio.tsx | 5 ++ src/utils/hooks/useLinkGen.ts | 2 + 7 files changed, 90 insertions(+), 68 deletions(-) diff --git a/src/App/hooks/useAppChain.ts b/src/App/hooks/useAppChain.ts index ad20b788d5..a03a8777bc 100644 --- a/src/App/hooks/useAppChain.ts +++ b/src/App/hooks/useAppChain.ts @@ -228,8 +228,7 @@ export const useAppChain = (): { linkGenCurrent.navigate(`chain=${network.chainId}`); } else if (isPathUserAddress || isPathUserXpOrLeaderboard) { // this one is specific to user account pages - // !IMPORTANT: not this one - window.location.reload(); + // linkGenCurrent.reload(); } else { linkGenCurrent.navigate(); } diff --git a/src/components/Portfolio/PortfolioTabs/PortfolioTabs.tsx b/src/components/Portfolio/PortfolioTabs/PortfolioTabs.tsx index cbcee1f51e..252a0db623 100644 --- a/src/components/Portfolio/PortfolioTabs/PortfolioTabs.tsx +++ b/src/components/Portfolio/PortfolioTabs/PortfolioTabs.tsx @@ -3,6 +3,7 @@ import { useEffect, useState, useContext, + useMemo, } from 'react'; // START: Import JSX Functional Components import Wallet from '../../Global/Account/AccountTabs/Wallet/Wallet'; @@ -131,6 +132,7 @@ export default function PortfolioTabs(props: propsIF) { .then((response) => response?.json()) .then((json) => { const userPositions = json?.data; + console.log({ userPositions, crocEnv, provider }); // temporarily skip ENS fetch const skipENSFetch = true; if (userPositions && crocEnv && provider) { @@ -151,6 +153,7 @@ export default function PortfolioTabs(props: propsIF) { }), ) .then((updatedPositions) => { + console.log({ updatedPositions }); setLookupAccountPositionData( updatedPositions.filter( (p) => p.positionLiq > 0, @@ -176,7 +179,6 @@ export default function PortfolioTabs(props: propsIF) { ) .then((response) => response?.json()) .then((json) => { - // temporarily skip ENS fetch const userLimitOrderStates = json?.data; if (userLimitOrderStates && crocEnv && provider) { Promise.all( @@ -241,6 +243,8 @@ export default function PortfolioTabs(props: propsIF) { useEffect(() => { (async () => { + if (!crocEnv || (await crocEnv.context).chain.chainId !== chainId) + return; if ( isServerEnabled && !connectedAccountActive && @@ -267,35 +271,53 @@ export default function PortfolioTabs(props: propsIF) { ? Math.floor(Date.now() / (2 * CACHE_UPDATE_FREQ_IN_MS)) : Math.floor(Date.now() / CACHE_UPDATE_FREQ_IN_MS), !!tokens.tokenUniv, - !!crocEnv, - !!provider, + crocEnv, + chainId, + provider, isServerEnabled, ]); - const activeAccountPositionData = connectedAccountActive - ? _positionsByUser - : lookupAccountPositionData; - // eslint-disable-next-line - const activeAccountLimitOrderData = connectedAccountActive - ? _limitsByUser - : lookupAccountLimitOrderData; - - const activeAccountTransactionData = connectedAccountActive - ? _txsByUser?.filter((tx) => { - if (tx.changeType !== 'fill' && tx.changeType !== 'cross') { - return true; - } else { - return false; - } - }) - : lookupAccountTransactionData?.filter((tx) => { - if (tx.changeType !== 'fill' && tx.changeType !== 'cross') { - return true; - } else { - return false; - } - }); + const activeAccountPositionData = useMemo( + () => + connectedAccountActive + ? _positionsByUser + : lookupAccountPositionData, + [connectedAccountActive, _positionsByUser, lookupAccountPositionData], + ); + const activeAccountLimitOrderData = useMemo( + () => + connectedAccountActive + ? _limitsByUser + : lookupAccountLimitOrderData, + [connectedAccountActive, _limitsByUser, lookupAccountLimitOrderData], + ); + + const activeAccountTransactionData = useMemo( + () => + connectedAccountActive + ? _txsByUser?.filter((tx) => { + if ( + tx.changeType !== 'fill' && + tx.changeType !== 'cross' + ) { + return true; + } else { + return false; + } + }) + : lookupAccountTransactionData?.filter((tx) => { + if ( + tx.changeType !== 'fill' && + tx.changeType !== 'cross' + ) { + return true; + } else { + return false; + } + }), + [connectedAccountActive, _txsByUser, lookupAccountTransactionData], + ); // props for React Element const walletProps = { diff --git a/src/components/Trade/TradeTabs/Orders/Orders.tsx b/src/components/Trade/TradeTabs/Orders/Orders.tsx index 8afc244b38..bdf63d173a 100644 --- a/src/components/Trade/TradeTabs/Orders/Orders.tsx +++ b/src/components/Trade/TradeTabs/Orders/Orders.tsx @@ -453,9 +453,8 @@ function Orders(props: propsIF) { showAllData, isAccountView, activeAccountLimitOrderData, - limitOrdersByPool, activeUserLimitOrdersByPool, - fetchedTransactions, // infinite scroll + fetchedTransactions.limitOrders, // infinite scroll ], ); diff --git a/src/components/Trade/TradeTabs/Ranges/Ranges.tsx b/src/components/Trade/TradeTabs/Ranges/Ranges.tsx index 4695362f80..432e1c8fc1 100644 --- a/src/components/Trade/TradeTabs/Ranges/Ranges.tsx +++ b/src/components/Trade/TradeTabs/Ranges/Ranges.tsx @@ -618,17 +618,13 @@ function Ranges(props: propsIF) { ? activeAccountPositionData || [] : !showAllData ? activeUserPositionsByPool - : // : positionsByPool.positions.filter( - // (position) => position.positionLiq != 0, - // ), - fetchedTransactions.positions, + : fetchedTransactions.positions, [ showAllData, isAccountView, activeAccountPositionData, - positionsByPool, activeUserPositionsByPool, - fetchedTransactions, // infinite scroll + fetchedTransactions.positions, // infinite scroll ], ); diff --git a/src/components/Trade/TradeTabs/Transactions/Transactions.tsx b/src/components/Trade/TradeTabs/Transactions/Transactions.tsx index 312ee97e7b..722d3cf984 100644 --- a/src/components/Trade/TradeTabs/Transactions/Transactions.tsx +++ b/src/components/Trade/TradeTabs/Transactions/Transactions.tsx @@ -168,6 +168,13 @@ function Transactions(props: propsIF) { changes: [...getInitialChangesData()], }); + useEffect(() => { + setFetchedTransactions({ + dataReceived: false, + changes: [...getInitialChangesData()], + }); + }, [activeAccountTransactionData]); + const [hotTransactions, setHotTransactions] = useState([]); const fetchedTransactionsRef = useRef(); @@ -229,25 +236,40 @@ function Transactions(props: propsIF) { useEffect(() => { // clear fetched transactions when switching pools - if (!isAccountView && showAllData && transactionsByPool.changes.length === 0) { + if ( + !isAccountView && + showAllData && + transactionsByPool.changes.length === 0 + ) { setFetchedTransactions({ dataReceived: true, changes: [], }); - } - else if(!isAccountView && !showAllData && userAddressRef.current && userTransactionsByPool.changes.length === 0){ + } else if ( + !isAccountView && + !showAllData && + userAddressRef.current && + userTransactionsByPool.changes.length === 0 + ) { setFetchedTransactions({ dataReceived: true, changes: [], }); - } - else if(isAccountView && (accountAddressRef.current || userAddressRef.current) && activeAccountTransactionData?.length === 0){ + } else if ( + isAccountView && + (accountAddressRef.current || userAddressRef.current) && + activeAccountTransactionData?.length === 0 + ) { setFetchedTransactions({ dataReceived: true, changes: [], }); } - }, [transactionsByPool.changes, userTransactionsByPool.changes, activeAccountTransactionData]); + }, [ + transactionsByPool.changes, + userTransactionsByPool.changes, + activeAccountTransactionData, + ]); // const [showInfiniteScroll, setShowInfiniteScroll] = useState(!isAccountView && showAllData); // useEffect(() => { @@ -256,27 +278,9 @@ function Transactions(props: propsIF) { // ---------------------------------------------------------------------------------------------- - const transactionData = useMemo( - () => - isAccountView - ? // ? activeAccountTransactionData || [] - fetchedTransactions.changes - : !showAllData - ? fetchedTransactions.changes - : fetchedTransactions.changes, - [ - activeAccountTransactionData, - userTransactionsByPool, - transactionsByPool, - showAllData, - fetchedTransactions, - isAccountView, - ], - ); - const txDataToDisplay: TransactionIF[] = isCandleSelected ? candleTransactionData - : transactionData; + : fetchedTransactions.changes; const [ sortBy, @@ -373,18 +377,13 @@ function Transactions(props: propsIF) { }, [pagesVisible[0]]); const oldestTxTime = useMemo(() => { - const dataToFilter = transactionData; + const dataToFilter = fetchedTransactions.changes; return dataToFilter.length > 0 ? dataToFilter.reduce((min, transaction) => { return transaction.txTime < min ? transaction.txTime : min; }, dataToFilter[0].txTime) : 0; - }, [ - transactionData, - fetchedTransactions.changes, - showAllData, - isAccountView, - ]); + }, [fetchedTransactions.changes, showAllData, isAccountView]); const oldestTxTimeRef = useRef(oldestTxTime); oldestTxTimeRef.current = oldestTxTime; diff --git a/src/pages/platformAmbient/Portfolio/Portfolio.tsx b/src/pages/platformAmbient/Portfolio/Portfolio.tsx index 74d514b48b..4a148bcb53 100644 --- a/src/pages/platformAmbient/Portfolio/Portfolio.tsx +++ b/src/pages/platformAmbient/Portfolio/Portfolio.tsx @@ -293,6 +293,11 @@ function Portfolio(props: propsIF) { chainId && !connectedAccountActive ) { + if ( + !crocEnv || + (await crocEnv.context).chain.chainId !== chainId + ) + return; try { setResolvedAddressTokens([]); const combinedBalances: TokenIF[] = []; diff --git a/src/utils/hooks/useLinkGen.ts b/src/utils/hooks/useLinkGen.ts index 00ceac33d4..ef2858991e 100644 --- a/src/utils/hooks/useLinkGen.ts +++ b/src/utils/hooks/useLinkGen.ts @@ -84,6 +84,7 @@ export interface linkGenMethodsIF { getFullURL: (paramsObj?: anyParamsIF | string) => string; navigate: (paramsObj?: anyParamsIF | string) => void; redirect: (paramsObj?: anyParamsIF | string) => void; + reload: () => void; } // TODO: @Emily: it probably makes sense to expand this hook to @@ -178,5 +179,6 @@ export const useLinkGen = (page?: pageNames): linkGenMethodsIF => { getFullURL, navigate: navigateUser, redirect: redirectUser, + reload: () => navigate(pathname), }; }; From c9a896a1d88c433cbb089ce535424991b12f6faa Mon Sep 17 00:00:00 2001 From: Ben Wolski <570819+benwolski@users.noreply.github.com> Date: Mon, 11 Nov 2024 10:35:07 -0500 Subject: [PATCH 2/4] add loading indicator to portfolio on chain switch when viewing lookup user data --- .../Portfolio/PortfolioTabs/PortfolioTabs.tsx | 64 +++++++++++++------ 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/src/components/Portfolio/PortfolioTabs/PortfolioTabs.tsx b/src/components/Portfolio/PortfolioTabs/PortfolioTabs.tsx index 252a0db623..d011e310af 100644 --- a/src/components/Portfolio/PortfolioTabs/PortfolioTabs.tsx +++ b/src/components/Portfolio/PortfolioTabs/PortfolioTabs.tsx @@ -37,7 +37,6 @@ import Transactions from '../../Trade/TradeTabs/Transactions/Transactions'; import { CACHE_UPDATE_FREQ_IN_MS, GCGO_OVERRIDE_URL, - IS_LOCAL_ENV, } from '../../../ambient-utils/constants'; import { CrocEnvContext } from '../../../contexts/CrocEnvContext'; import { TokenContext } from '../../../contexts/TokenContext'; @@ -121,7 +120,7 @@ export default function PortfolioTabs(props: propsIF) { ? GCGO_OVERRIDE_URL + '/user_limit_orders?' : graphCacheUrl + '/user_limit_orders?'; - const getLookupUserPositions = async (accountToSearch: string) => + const getLookupUserPositions = async (accountToSearch: string) => { fetch( userPositionsCacheEndpoint + new URLSearchParams({ @@ -132,7 +131,6 @@ export default function PortfolioTabs(props: propsIF) { .then((response) => response?.json()) .then((json) => { const userPositions = json?.data; - console.log({ userPositions, crocEnv, provider }); // temporarily skip ENS fetch const skipENSFetch = true; if (userPositions && crocEnv && provider) { @@ -153,7 +151,6 @@ export default function PortfolioTabs(props: propsIF) { }), ) .then((updatedPositions) => { - console.log({ updatedPositions }); setLookupAccountPositionData( updatedPositions.filter( (p) => p.positionLiq > 0, @@ -168,8 +165,9 @@ export default function PortfolioTabs(props: propsIF) { }); } }); + }; - const getLookupUserLimitOrders = async (accountToSearch: string) => + const getLookupUserLimitOrders = async (accountToSearch: string) => { fetch( userLimitOrdersCacheEndpoint + new URLSearchParams({ @@ -212,6 +210,8 @@ export default function PortfolioTabs(props: propsIF) { }); } }); + }; + const getLookupUserTransactions = async (accountToSearch: string) => { if (crocEnv && provider) { fetchUserRecentChanges({ @@ -243,20 +243,26 @@ export default function PortfolioTabs(props: propsIF) { useEffect(() => { (async () => { - if (!crocEnv || (await crocEnv.context).chain.chainId !== chainId) - return; if ( - isServerEnabled && !connectedAccountActive && - !!tokens.tokenUniv && resolvedAddress && - !!crocEnv + isServerEnabled && + crocEnv && + (await crocEnv.context).chain.chainId === chainId && + !!tokens.tokenUniv ) { - IS_LOCAL_ENV && - console.debug( - 'querying user tx/order/positions because address changed', - ); - + setDataLoadingStatus({ + datasetName: 'isLookupUserRangeDataLoading', + loadingStatus: true, + }); + setDataLoadingStatus({ + datasetName: 'isLookupUserOrderDataLoading', + loadingStatus: true, + }); + setDataLoadingStatus({ + datasetName: 'isLookupUserTxDataLoading', + loadingStatus: true, + }); await Promise.all([ getLookupUserTransactions(resolvedAddress), getLookupUserLimitOrders(resolvedAddress), @@ -267,17 +273,37 @@ export default function PortfolioTabs(props: propsIF) { }, [ resolvedAddress, connectedAccountActive, - isUserIdle - ? Math.floor(Date.now() / (2 * CACHE_UPDATE_FREQ_IN_MS)) - : Math.floor(Date.now() / CACHE_UPDATE_FREQ_IN_MS), !!tokens.tokenUniv, crocEnv, chainId, provider, - isServerEnabled, ]); + // update without loading indicator on an interval + useEffect(() => { + (async () => { + if ( + !connectedAccountActive && + resolvedAddress && + isServerEnabled && + crocEnv && + (await crocEnv.context).chain.chainId === chainId && + !!tokens.tokenUniv + ) { + await Promise.all([ + getLookupUserTransactions(resolvedAddress), + getLookupUserLimitOrders(resolvedAddress), + getLookupUserPositions(resolvedAddress), + ]); + } + })(); + }, [ + isUserIdle + ? Math.floor(Date.now() / (2 * CACHE_UPDATE_FREQ_IN_MS)) + : Math.floor(Date.now() / CACHE_UPDATE_FREQ_IN_MS), + ]); + const activeAccountPositionData = useMemo( () => connectedAccountActive From cbe27085fd0ba9b5b2bc5c4d7b422e4d4ae712fc Mon Sep 17 00:00:00 2001 From: Ben Wolski <570819+benwolski@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:32:42 -0500 Subject: [PATCH 3/4] clean up chooseNetwork navigation code --- src/App/hooks/useAppChain.ts | 15 +++++++-------- src/utils/hooks/useLinkGen.ts | 2 -- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/App/hooks/useAppChain.ts b/src/App/hooks/useAppChain.ts index a03a8777bc..6c814aa2ba 100644 --- a/src/App/hooks/useAppChain.ts +++ b/src/App/hooks/useAppChain.ts @@ -210,13 +210,16 @@ export const useAppChain = (): { // ... else in this file responds to changes in the browser environment function chooseNetwork(network: NetworkIF): void { localStorage.setItem(CHAIN_LS_KEY, network.chainId); - const { pathname } = window.location; - setActiveNetwork(network); + + const { pathname } = window.location; const isPathENS = pathname.slice(1)?.includes('.eth'); const isPathHexEoaAddress = checkEoaHexAddress(pathname); const isPathUserAddress = isPathENS || isPathHexEoaAddress; const isPathUserXpOrLeaderboard = pathname.includes('/xp'); + const shouldStayOnCurrentExactPath = + isPathUserAddress || isPathUserXpOrLeaderboard; + if ( linkGenCurrent.currentPage === 'initpool' || linkGenCurrent.currentPage === 'reposition' @@ -226,15 +229,11 @@ export const useAppChain = (): { linkGenSwap.navigate(`chain=${network.chainId}`); } else if (pathname.includes('chain')) { linkGenCurrent.navigate(`chain=${network.chainId}`); - } else if (isPathUserAddress || isPathUserXpOrLeaderboard) { - // this one is specific to user account pages - // linkGenCurrent.reload(); + } else if (shouldStayOnCurrentExactPath) { + // do not navigate away from current path } else { linkGenCurrent.navigate(); } - // this one seems to be necessary for chain switching, when disabled - // ... the app appears to switch chains but doesn't get any pool data - // window.location.reload(); } return { diff --git a/src/utils/hooks/useLinkGen.ts b/src/utils/hooks/useLinkGen.ts index ef2858991e..00ceac33d4 100644 --- a/src/utils/hooks/useLinkGen.ts +++ b/src/utils/hooks/useLinkGen.ts @@ -84,7 +84,6 @@ export interface linkGenMethodsIF { getFullURL: (paramsObj?: anyParamsIF | string) => string; navigate: (paramsObj?: anyParamsIF | string) => void; redirect: (paramsObj?: anyParamsIF | string) => void; - reload: () => void; } // TODO: @Emily: it probably makes sense to expand this hook to @@ -179,6 +178,5 @@ export const useLinkGen = (page?: pageNames): linkGenMethodsIF => { getFullURL, navigate: navigateUser, redirect: redirectUser, - reload: () => navigate(pathname), }; }; From b6649acd67c4f607cddecaf25bf9fc9905aedaa2 Mon Sep 17 00:00:00 2001 From: Ben Wolski <570819+benwolski@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:58:23 -0500 Subject: [PATCH 4/4] fix missing page titles for XP and Leaderboard --- src/App/components/PageHeader/PageHeader.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/App/components/PageHeader/PageHeader.tsx b/src/App/components/PageHeader/PageHeader.tsx index b9ee01f819..cc676b6376 100644 --- a/src/App/components/PageHeader/PageHeader.tsx +++ b/src/App/components/PageHeader/PageHeader.tsx @@ -230,6 +230,8 @@ const PageHeader = function () { document.title = `${ensNameOrAddressTruncated} Wallet Balances ~ Ambient`; } else if (pathNoLeadingSlash.includes('exchange-balances')) { document.title = `${ensNameOrAddressTruncated} Exchange Balances ~ Ambient`; + } else if (pathNoLeadingSlash.includes('xp')) { + document.title = `${ensNameOrAddressTruncated} XP ~ Ambient`; } else { document.title = `${ensNameOrAddressTruncated} ~ Ambient`; } @@ -252,6 +254,8 @@ const PageHeader = function () { } else { document.title = 'Explore ~ Ambient'; } + } else if (pathNoLeadingSlash.includes('xp-leaderboard')) { + document.title = 'XP Leaderboard ~ Ambient'; } else if (location.pathname.includes('404')) { document.title = '404 ~ Ambient'; } else {