diff --git a/app/components/track-last-visit.tsx b/app/components/track-last-visit.tsx index 96f35d9a..29b7a451 100644 --- a/app/components/track-last-visit.tsx +++ b/app/components/track-last-visit.tsx @@ -1,6 +1,6 @@ "use client" -import { useEffect } from "react" +import React from "react" import { useLocalStorage } from "usehooks-ts" @@ -20,9 +20,9 @@ export function useLastVisit() { export function TrackLastVisit() { const { setLastVisit } = useLastVisit() - useEffect(() => { + React.useEffect(() => { const handleBeforeUnload = () => { - // setLastVisit(Date.now()) + setLastVisit(Date.now()) } window.addEventListener("beforeunload", handleBeforeUnload) diff --git a/app/components/wallet-sidebar/assets-menu-item.tsx b/app/components/wallet-sidebar/assets-menu-item.tsx index 15500b1e..c95134e3 100644 --- a/app/components/wallet-sidebar/assets-menu-item.tsx +++ b/app/components/wallet-sidebar/assets-menu-item.tsx @@ -41,7 +41,6 @@ export function AssetsMenuItem() { - {/* */} Assets {formatCurrency(totalRenegadeBalanceUsd)} diff --git a/app/components/wallet-sidebar/hooks/use-filtered-fills.ts b/app/components/wallet-sidebar/hooks/use-filtered-fills.ts deleted file mode 100644 index ddaf9231..00000000 --- a/app/components/wallet-sidebar/hooks/use-filtered-fills.ts +++ /dev/null @@ -1,62 +0,0 @@ -import React from "react" - -import { OrderState, useOrderHistory } from "@renegade-fi/react" - -import { useLastVisit } from "@/app/components/track-last-visit" -import { - useViewedFills, - generateFillIdentifier, -} from "@/app/components/wallet-sidebar/hooks/use-viewed-fills" - -export function useFilteredFills() { - const { lastVisit } = useLastVisit() - const { data: orders } = useOrderHistory({ - query: { - select: (data) => { - return Array.from(data.values()).filter((order) => { - return order.state !== OrderState.Cancelled - }) - }, - }, - }) - const { isFillViewed } = useViewedFills() - - const ordersWithRecentFills = React.useMemo(() => { - if (!orders || !lastVisit) return [] - - return orders - .map((order) => ({ - ...order, - fills: order.fills.filter((fill) => { - const lastVisitBigInt = BigInt(lastVisit) - return fill.price.timestamp > lastVisitBigInt - }), - })) - .filter((order) => order.fills.length > 0) - .sort((a, b) => { - const latestFillA = a.fills[a.fills.length - 1].price.timestamp - const latestFillB = b.fills[b.fills.length - 1].price.timestamp - return Number(latestFillB - latestFillA) - }) - }, [orders, lastVisit]) - - const filteredOrders = ordersWithRecentFills - .map((order) => ({ - ...order, - fills: order.fills.filter( - (fill) => - !isFillViewed(generateFillIdentifier(order.id, fill.price.timestamp)), - ), - })) - .filter((order) => order.fills.length > 0) - - const totalUnviewedFills = filteredOrders.reduce( - (acc, order) => acc + order.fills.length, - 0, - ) - - return { - filteredOrders, - totalUnviewedFills, - } -} diff --git a/app/components/wallet-sidebar/hooks/use-unviewed-fills.ts b/app/components/wallet-sidebar/hooks/use-unviewed-fills.ts new file mode 100644 index 00000000..6dcc06f3 --- /dev/null +++ b/app/components/wallet-sidebar/hooks/use-unviewed-fills.ts @@ -0,0 +1,79 @@ +import React from "react" + +import { OrderMetadata, useOrderHistory } from "@renegade-fi/react" + +import { useLastVisit } from "@/app/components/track-last-visit" +import { + useViewedFills, + generateFillIdentifier, +} from "@/app/components/wallet-sidebar/hooks/use-viewed-fills" + +export function useRecentUnviewedFills() { + const { lastVisit } = useLastVisit() + const lastVisitBigInt = React.useMemo( + () => (lastVisit ? BigInt(lastVisit) : null), + [lastVisit], + ) + + const { data: orders } = useOrderHistory({ + query: { + select: (data) => { + if (!lastVisitBigInt) return [] + + const filteredOrders: OrderMetadata[] = [] + + for (const order of data.values()) { + const latestFill = order.fills[order.fills.length - 1] + if (!latestFill || latestFill.price.timestamp <= lastVisitBigInt) { + continue + } + + const recentFills = order.fills.filter( + (fill) => fill.price.timestamp > lastVisitBigInt, + ) + + if (recentFills.length > 0) { + filteredOrders.push({ + ...order, + fills: recentFills, + }) + } + } + + return filteredOrders.sort((a, b) => { + const latestFillA = a.fills[a.fills.length - 1].price.timestamp + const latestFillB = b.fills[b.fills.length - 1].price.timestamp + return Number(latestFillB - latestFillA) + }) + }, + }, + }) + + const { isFillViewed } = useViewedFills() + + const filteredOrders = React.useMemo(() => { + if (!orders) return [] + + return orders + .map((order) => ({ + ...order, + fills: order.fills.filter( + (fill) => + !isFillViewed( + generateFillIdentifier(order.id, fill.price.timestamp), + ), + ), + })) + .filter((order) => order.fills.length > 0) + }, [orders, isFillViewed]) + + const totalUnviewedFills = React.useMemo( + () => filteredOrders.reduce((acc, order) => acc + order.fills.length, 0), + [filteredOrders], + ) + + return { + filteredOrders, + totalUnviewedFills, + } +} diff --git a/app/components/wallet-sidebar/hooks/use-viewed-fills.ts b/app/components/wallet-sidebar/hooks/use-viewed-fills.ts index 7bf174c3..8ff8b5b9 100644 --- a/app/components/wallet-sidebar/hooks/use-viewed-fills.ts +++ b/app/components/wallet-sidebar/hooks/use-viewed-fills.ts @@ -18,36 +18,16 @@ export function useViewedFills() { ) const markFillAsViewed = (fillId: FillIdentifier) => { - console.debug(`[useViewedFills] Marking fill as viewed:`, { - fillId, - wasAlreadyViewed: viewedFills.includes(fillId), - currentViewedFills: viewedFills, - }) - if (!viewedFills.includes(fillId)) { setViewedFills([...viewedFills, fillId]) - console.debug(`[useViewedFills] Updated viewed fills:`, [ - ...viewedFills, - fillId, - ]) } } const isFillViewed = (fillId: FillIdentifier) => { const isViewed = viewedFills.includes(fillId) - console.debug(`[useViewedFills] Checking if fill is viewed:`, { - fillId, - isViewed, - currentViewedFills: viewedFills, - }) return isViewed } - console.debug( - `[useViewedFills] Hook rendered with viewed fills:`, - viewedFills, - ) - return { viewedFills, markFillAsViewed, diff --git a/app/components/wallet-sidebar/index.tsx b/app/components/wallet-sidebar/index.tsx index 4a6ccf18..fa9d2b3f 100644 --- a/app/components/wallet-sidebar/index.tsx +++ b/app/components/wallet-sidebar/index.tsx @@ -82,7 +82,6 @@ export function WalletSidebar({ - {/* Renegade */} diff --git a/app/components/wallet-sidebar/recent-fills-menu-item.tsx b/app/components/wallet-sidebar/recent-fills-menu-item.tsx index 5a6c8fae..50a6e2b9 100644 --- a/app/components/wallet-sidebar/recent-fills-menu-item.tsx +++ b/app/components/wallet-sidebar/recent-fills-menu-item.tsx @@ -1,11 +1,9 @@ import React from "react" import { Token } from "@renegade-fi/react" -import { useQueryClient } from "@tanstack/react-query" import { ChevronRight } from "lucide-react" import { formatUnits } from "viem" -import { useViewedFills } from "@/app/components/wallet-sidebar/hooks/use-viewed-fills" import { OrderDetailsSheet } from "@/app/trade/[base]/components/order-details/order-details-sheet" import { @@ -20,18 +18,21 @@ import { SidebarMenuSubButton, SidebarMenuSubItem, } from "@/components/ui/sidebar" +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip" import { amountTimesPrice } from "@/hooks/use-usd-price" -import { formatCurrencyFromString } from "@/lib/format" -import { createPriceQueryKey } from "@/lib/query" +import { formatCurrencyFromString, formatRelativeTimestamp } from "@/lib/format" +import { decimalNormalizePrice } from "@/lib/utils" -import { useFilteredFills } from "./hooks/use-filtered-fills" +import { useRecentUnviewedFills } from "./hooks/use-unviewed-fills" import { generateFillIdentifier } from "./hooks/use-viewed-fills" export function RecentFillsMenuItem() { - const { filteredOrders, totalUnviewedFills } = useFilteredFills() - const { markFillAsViewed } = useViewedFills() - const queryClient = useQueryClient() + const { filteredOrders, totalUnviewedFills } = useRecentUnviewedFills() if (!totalUnviewedFills) { return null @@ -54,40 +55,46 @@ export function RecentFillsMenuItem() { {filteredOrders.map((order) => ( - {order.fills.map((fill, index) => { + {order.fills.map((fill) => { const isBuy = order.data.side === "Buy" const token = Token.findByAddress(order.data.base_mint) + const quoteToken = Token.findByAddress(order.data.quote_mint) const fillId = generateFillIdentifier( order.id, fill.price.timestamp, ) - const priceKey = createPriceQueryKey( - "binance", - order.data.base_mint, - ) - const price = queryClient.getQueryData(priceKey) ?? 0 - - const usdValue = amountTimesPrice(fill.amount, price) - const formattedUsdValue = formatCurrencyFromString( - formatUnits(usdValue, token.decimals), + const value = amountTimesPrice( + fill.amount, + decimalNormalizePrice( + fill.price.price, + token.decimals, + quoteToken.decimals, + ), ) + const formattedValue = formatUnits(value, token.decimals) + const formattedUsdValue = + formatCurrencyFromString(formattedValue) return ( - { - if (!isOpen) { - markFillAsViewed(fillId) - } - }} - > - - {`${isBuy ? "Bought" : "Sold"} ${formattedUsdValue} of ${token?.ticker}`} - - + + + + + {`${isBuy ? "Bought" : "Sold"} ${formattedUsdValue} of ${token?.ticker}`} + + + + + {formatRelativeTimestamp( + Number(fill.price.timestamp), + )} + + ) })} diff --git a/app/trade/[base]/components/order-details/order-details-sheet.tsx b/app/trade/[base]/components/order-details/order-details-sheet.tsx index 3625c8ef..fa122584 100644 --- a/app/trade/[base]/components/order-details/order-details-sheet.tsx +++ b/app/trade/[base]/components/order-details/order-details-sheet.tsx @@ -27,21 +27,17 @@ import { import { useMediaQuery } from "@/hooks/use-media-query" -interface OrderDetailsSheetProps { - order: OrderMetadata - children: React.ReactNode - onOpenChange?: (open: boolean) => void -} - export function OrderDetailsSheet({ children, order, - onOpenChange, -}: OrderDetailsSheetProps) { +}: { + children: React.ReactNode + order: OrderMetadata +}) { const isDesktop = useMediaQuery("(min-width: 1024px)") if (isDesktop) { return ( - + {children}