diff --git a/apps/mobile/src/components/TokenDetailPopup/BottomSheetModalTokenDetail.tsx b/apps/mobile/src/components/TokenDetailPopup/BottomSheetModalTokenDetail.tsx index b65f8d9cc..efbe57b54 100644 --- a/apps/mobile/src/components/TokenDetailPopup/BottomSheetModalTokenDetail.tsx +++ b/apps/mobile/src/components/TokenDetailPopup/BottomSheetModalTokenDetail.tsx @@ -30,7 +30,7 @@ import { HistoryItem } from '@/components/TokenDetailPopup/HistoryItem'; import { makeDebugBorder } from '@/utils/styles'; import { BottomSheetHandlableView } from '@/components/customized/BottomSheetHandle'; -import { SMALL_TOKEN_ID } from '@/utils/token'; +import { SMALL_TOKEN_ID, abstractTokenToTokenItem } from '@/utils/token'; import { AppBottomSheetModal, AssetAvatar, Button, Tip } from '@/components'; import { ChainIconFastImage } from '@/components/Chain/ChainIconImage'; import { @@ -384,7 +384,7 @@ export const BottomSheetModalTokenDetail = React.forwardRef< if (!tokenInfo || tokenInfo.id !== token._tokenId) return token; return ensureAbstractPortfolioToken({ - ...token, + ...abstractTokenToTokenItem(token), amount: tokenInfo?.amount, }); }, [token, tokenLoad]); @@ -404,18 +404,19 @@ export const BottomSheetModalTokenDetail = React.forwardRef< // Customized and not added const isHiddenButton = !token?.is_core && !isAdded; - const [latestData, setLatestData] = React.useState({ - last: null, - list: [], - }); + // const [latestData, setLatestData] = React.useState({ + // last: null, + // list: [], + // }); type LoadData = { last?: TxDisplayItem['time_at'] | null; + tokenId?: AbstractPortfolioToken['_tokenId'] | null; list: TxDisplayItem[]; }; const { - // data, - loading: isLoading, + data: latestData, + loading: isLoadingFirst, loadingMore: isLoadingMore, loadMore, reloadAsync, @@ -423,11 +424,11 @@ export const BottomSheetModalTokenDetail = React.forwardRef< async (currentData?) => { const tickResult: LoadData = { last: null, + tokenId: token?._tokenId, list: [], }; if (!token) { - setLatestData(tickResult); return tickResult; } @@ -458,11 +459,6 @@ export const BottomSheetModalTokenDetail = React.forwardRef< tickResult.last = last(displayList)?.time_at ?? null; tickResult.list = displayList; - setLatestData(prev => ({ - last: tickResult.last, - list: [...prev.list, ...tickResult.list], - })); - return tickResult; } catch (error) { console.error(error); @@ -470,6 +466,7 @@ export const BottomSheetModalTokenDetail = React.forwardRef< } }, { + manual: true, // reloadDeps: [token], isNoMore: d => { return !d?.last || (d?.list.length || 0) < PAGE_COUNT; @@ -478,13 +475,23 @@ export const BottomSheetModalTokenDetail = React.forwardRef< }, ); - const { dataList, isRefreshing } = useMemo(() => { + useEffect(() => { + if (token) { + resetHistoryListPosition(); + } + + // though no token, trigger it to make latestData to be empty + reloadAsync(); + }, [token, reloadAsync, resetHistoryListPosition]); + + const { dataList, shouldRenderLoadingOnEmpty } = useMemo(() => { const res = { - isRefreshing: isLoading && !isLoadingMore, dataList: [] as TxDisplayItem[], + shouldRenderLoadingOnEmpty: false, }; - // is reloading - if (res.isRefreshing) return res; + + res.dataList = + latestData?.tokenId === token?._tokenId ? latestData?.list || [] : []; // // TODO: leave here for debug // if (__DEV__) { @@ -493,47 +500,35 @@ export const BottomSheetModalTokenDetail = React.forwardRef< // data.list = data.list.slice(0, 5); // } // } - res.dataList = latestData?.list || []; + res.shouldRenderLoadingOnEmpty = + isLoadingFirst || (!res.dataList?.length && isLoadingMore); return res; - }, [isLoading, isLoadingMore, latestData?.list]); + }, [ + latestData?.tokenId, + token?._tokenId, + isLoadingFirst, + isLoadingMore, + latestData?.list, + ]); const onEndReached = React.useCallback(() => { loadMore(); }, [loadMore]); - const refresh = useCallback( - async (options?: { resetPrevious?: boolean }) => { - __DEV__ && console.debug('handle refreshing'); - const { resetPrevious = true } = options || {}; - if (resetPrevious) { - setLatestData({ last: null, list: [] }); - } - await reloadAsync(); - }, - [reloadAsync], - ); - - useEffect(() => { - if (token) { - resetHistoryListPosition(); - refresh(); - } - }, [token, refresh, resetHistoryListPosition]); - const renderItem = useCallback( ({ item }: { item: TxDisplayItem }) => { return ( ); }, - [canClickToken], + [isLoadingFirst, canClickToken], ); const keyExtractor = useCallback((item: TxDisplayItem, idx: number) => { @@ -679,7 +674,7 @@ export const BottomSheetModalTokenDetail = React.forwardRef< }, [styles, isLoadingMore, safeOffBottom]); const ListEmptyComponent = React.useMemo(() => { - return isRefreshing ? ( + return shouldRenderLoadingOnEmpty ? ( ) : ( @@ -690,7 +685,7 @@ export const BottomSheetModalTokenDetail = React.forwardRef< /> ); - }, [t, styles.emptyHolderContainer, isRefreshing]); + }, [t, styles.emptyHolderContainer, shouldRenderLoadingOnEmpty]); const { onHardwareBackHandler } = useHandleBackPressClosable( useCallback(() => { @@ -723,16 +718,16 @@ export const BottomSheetModalTokenDetail = React.forwardRef< - + {(data.tx && data.tx?.eth_gas_fee) || isFailed ? ( diff --git a/apps/mobile/src/screens/Transaction/components/TokenChange.tsx b/apps/mobile/src/screens/Transaction/components/TokenChange.tsx index 1d70a98fe..b997cb164 100644 --- a/apps/mobile/src/screens/Transaction/components/TokenChange.tsx +++ b/apps/mobile/src/screens/Transaction/components/TokenChange.tsx @@ -20,6 +20,7 @@ import { numberWithCommasIsLtOne } from '@/utils/number'; import { useThemeColors } from '@/hooks/theme'; import { AppColorsVariants } from '@/constant/theme'; import TokenLabel from './TokenLabel'; +import { makeDebugBorder } from '@/utils/styles'; const TxChangeItem = ({ item, @@ -69,13 +70,15 @@ const TxChangeItem = ({ )} - + {isSend ? '-' : '+'}{' '} {isNft ? item.amount : numberWithCommasIsLtOne(item.amount, 2)} @@ -119,6 +122,9 @@ export const TxChange = ({ ); }; +const ChangeSizes = { + gap: 6, +}; const getStyles = (colors: AppColorsVariants) => StyleSheet.create({ container: { @@ -131,37 +137,32 @@ const getStyles = (colors: AppColorsVariants) => }, item: { flexDirection: 'row', + justifyContent: 'flex-end', alignItems: 'center', - gap: 6, - }, - image: { - width: 14, - height: 14, - borderRadius: 14, + gap: ChangeSizes.gap, + // ...makeDebugBorder() }, media: { width: 14, height: 14, borderRadius: 2, + // ...makeDebugBorder('red') }, text: { fontSize: 13, lineHeight: 15, color: colors['green-default'], - // flex: 1, minWidth: 0, - flexGrow: 1, + // flexGrow: 1, flexShrink: 1, + textAlign: 'right', + }, + tokenChangeDelta: { + justifyContent: 'flex-end', }, textNegative: { color: colors['neutral-body'], }, - // tokenChangeTextWrapper: { - // flexDirection: 'row', - // alignItems: 'center', - // justifyContent: 'flex-start', - // flexShrink: 0, - // }, tokenLabel: { position: 'relative', top: 0,