@@ -9,7 +9,7 @@ import { Spinner } from "@/components/ui/spinner";
99import { Switch } from "@/components/ui/switch" ;
1010import { Avatar , AvatarFallback , AvatarImage } from "@/components/ui/avatar" ;
1111import { ConstsTransactionKind , type DomainInvitationItem , type DomainTransactionLog } from "@/api/Api" ;
12- import { Item , ItemContent , ItemGroup , ItemTitle } from "@/components/ui/item" ;
12+ import { Item , ItemContent , ItemGroup , ItemSeparator , ItemTitle } from "@/components/ui/item" ;
1313import dayjs from "dayjs" ;
1414import { cn } from "@/lib/utils" ;
1515import {
@@ -57,6 +57,7 @@ export default function NavBalance({ variant = "sidebar" }: NavBalanceProps) {
5757 const [ hasNextPage , setHasNextPage ] = useState ( false ) ;
5858 const [ isLoadingMore , setIsLoadingMore ] = useState ( false ) ;
5959 const loadMoreRef = useRef < HTMLDivElement > ( null ) ;
60+ const contentScrollRef = useRef < HTMLDivElement > ( null ) ;
6061 const { balance, dailyBalance, loadingSubscription, reloadSubscription, reloadWallet, subscription, user } = useCommonData ( ) ;
6162
6263 const positiveKinds = new Set < string > ( [
@@ -172,7 +173,7 @@ export default function NavBalance({ variant = "sidebar" }: NavBalanceProps) {
172173 const fetchTranscations = useCallback ( async ( pageToLoad : number , replace = false ) => {
173174 setIsLoadingMore ( true ) ;
174175 await apiRequest ( 'v1UsersWalletTransactionList' , {
175- size : 10 ,
176+ size : 20 ,
176177 page : pageToLoad ,
177178 } , [ ] , ( resp ) => {
178179 if ( resp . code === 0 ) {
@@ -285,26 +286,36 @@ export default function NavBalance({ variant = "sidebar" }: NavBalanceProps) {
285286 }
286287
287288 useEffect ( ( ) => {
289+ if ( ! dialogOpen || activeSection !== "usage" ) {
290+ return ;
291+ }
292+
293+ const currentRef = loadMoreRef . current ;
294+ const rootRef = contentScrollRef . current ;
295+ if ( ! currentRef || ! rootRef ) {
296+ return ;
297+ }
298+
288299 const observer = new IntersectionObserver (
289300 ( entries ) => {
290301 if ( entries [ 0 ] . isIntersecting ) {
291302 loadMore ( ) ;
292303 }
293304 } ,
294- { threshold : 0.1 }
305+ {
306+ root : rootRef ,
307+ threshold : 0 ,
308+ rootMargin : "0px 0px 120px 0px" ,
309+ }
295310 ) ;
296311
297- const currentRef = loadMoreRef . current ;
298- if ( currentRef ) {
299- observer . observe ( currentRef ) ;
300- }
312+ observer . observe ( currentRef ) ;
301313
302314 return ( ) => {
303- if ( currentRef ) {
304- observer . unobserve ( currentRef ) ;
305- }
315+ observer . unobserve ( currentRef ) ;
316+ observer . disconnect ( ) ;
306317 } ;
307- } , [ loadMore ] ) ;
318+ } , [ activeSection , dialogOpen , hasNextPage , loadMore , transcations . length ] ) ;
308319
309320 const openDialog = useCallback ( ( section : BalanceSectionId = "balance" ) => {
310321 setActiveSection ( section )
@@ -651,23 +662,39 @@ export default function NavBalance({ variant = "sidebar" }: NavBalanceProps) {
651662 )
652663
653664 const usageContent = (
654- < ItemGroup className = "flex max-h-full flex-col gap-2 overflow-y-auto " >
665+ < ItemGroup className = "flex flex-col" >
655666 { transcations . map ( ( transaction , index ) => (
656- < Item key = { `${ transaction . created_at || 0 } -${ transaction . kind || "unknown" } -${ index } ` } variant = "outline" size = "sm" >
657- < ItemContent >
658- < ItemTitle className = "flex flex-row w-full" >
659- < div className = { cn ( "flex flex-1 flex-row items-center" , positiveKinds . has ( transaction . kind || ConstsTransactionKind . TransactionKindVMConsumption ) ? "text-primary" : "" ) } >
660- { formatSignedAmount ( transaction . amount || ( ( transaction . amount_balance || 0 ) + ( transaction . amount_daily || 0 ) ) , transaction . kind ) }
661- </ div >
662- < div className = "flex flex-row items-center gap-1 text-muted-foreground text-xs font-normal" >
663- { transaction . remark || getTransactionLabel ( transaction . kind ) }
664- </ div >
665- < div className = "text-muted-foreground text-xs ml-4" >
666- { dayjs ( ( transaction . created_at || 0 ) * 1000 ) . format ( "YYYY-MM-DD HH:mm:ss" ) }
667- </ div >
668- </ ItemTitle >
669- </ ItemContent >
670- </ Item >
667+ < div key = { `${ transaction . created_at || 0 } -${ transaction . kind || "unknown" } -${ index } ` } >
668+ < Item
669+ variant = "default"
670+ size = "sm"
671+ className = "px-2 py-2"
672+ >
673+ < ItemContent >
674+ < ItemTitle className = "grid w-full grid-cols-[minmax(0,1fr)_auto] items-center gap-4" >
675+ < div className = "min-w-0" >
676+ < div className = "truncate text-sm text-foreground font-normal" >
677+ { transaction . remark || getTransactionLabel ( transaction . kind ) }
678+ </ div >
679+ < div className = "mt-0.5 text-xs text-muted-foreground" >
680+ { dayjs ( ( transaction . created_at || 0 ) * 1000 ) . format ( "YYYY-MM-DD HH:mm:ss" ) }
681+ </ div >
682+ </ div >
683+ < div
684+ className = { cn (
685+ "text-right tabular-nums" ,
686+ positiveKinds . has ( transaction . kind || ConstsTransactionKind . TransactionKindVMConsumption )
687+ ? "text-green-600"
688+ : "text-red-600" ,
689+ ) }
690+ >
691+ { formatSignedAmount ( transaction . amount || ( ( transaction . amount_balance || 0 ) + ( transaction . amount_daily || 0 ) ) , transaction . kind ) }
692+ </ div >
693+ </ ItemTitle >
694+ </ ItemContent >
695+ </ Item >
696+ { index < transcations . length - 1 && < ItemSeparator /> }
697+ </ div >
671698 ) ) }
672699 { hasNextPage && (
673700 < div ref = { loadMoreRef } className = "flex justify-center py-2" >
@@ -735,7 +762,7 @@ export default function NavBalance({ variant = "sidebar" }: NavBalanceProps) {
735762 < div className = "text-sm font-medium" > { sectionMeta . title } </ div >
736763 < div className = "mt-1 text-xs text-muted-foreground" > { sectionMeta . description } </ div >
737764 </ div >
738- < div className = "flex min-h-0 flex-1 flex-col overflow-y-auto p-4" >
765+ < div ref = { contentScrollRef } className = "flex min-h-0 flex-1 flex-col overflow-y-auto p-4" >
739766 { activeSection === "balance"
740767 ? balanceContent
741768 : activeSection === "earn"
0 commit comments