diff --git a/desktop/src/features/market/lib/marketTimeline.test.mjs b/desktop/src/features/market/lib/marketTimeline.test.mjs index ef01e3833e..97ae8cc433 100644 --- a/desktop/src/features/market/lib/marketTimeline.test.mjs +++ b/desktop/src/features/market/lib/marketTimeline.test.mjs @@ -3,6 +3,7 @@ import test from "node:test"; import { isMarketProtocolMessage, + marketBidsAfterAnchor, marketTimelineAnchor, selectMarketTimelineMessages, } from "./marketTimeline.ts"; @@ -74,6 +75,18 @@ test("the market board anchors to channel creation, not above history", () => { ); assert.equal(isMarketProtocolMessage(contract), true); assert.equal(isMarketProtocolMessage(created), false); + assert.deepEqual( + marketBidsAfterAnchor( + [ + { createdAt: 9, eventId: "9".repeat(64) }, + { createdAt: 11, eventId: "1".repeat(64) }, + { createdAt: 11, eventId: "3".repeat(64) }, + { createdAt: 12, eventId: "0".repeat(64) }, + ], + created, + ).map(({ eventId }) => eventId), + ["3".repeat(64), "0".repeat(64)], + ); }); test("market timeline hides protocol events but leaves negotiation in its bid thread", () => { diff --git a/desktop/src/features/market/lib/marketTimeline.ts b/desktop/src/features/market/lib/marketTimeline.ts index 57860ce681..bbd78443c1 100644 --- a/desktop/src/features/market/lib/marketTimeline.ts +++ b/desktop/src/features/market/lib/marketTimeline.ts @@ -1,6 +1,9 @@ import * as React from "react"; import { useMarketChannel } from "@/features/market/lib/MarketChannelContext"; -import type { MarketProjection } from "@/features/market/lib/marketProtocol"; +import type { + MarketBid, + MarketProjection, +} from "@/features/market/lib/marketProtocol"; import { parseMarketEnvelope } from "@/features/market/lib/marketProtocol"; import type { TimelineMessage } from "@/features/messages/types"; @@ -21,6 +24,18 @@ export function marketTimelineAnchor( ); } +export function marketBidsAfterAnchor( + bids: MarketBid[], + anchor: Pick, +): MarketBid[] { + return bids.filter( + (bid) => + bid.createdAt > anchor.createdAt || + (bid.createdAt === anchor.createdAt && + bid.eventId.localeCompare(anchor.id) > 0), + ); +} + /** Keep protocol state out of the market's main chat; negotiation stays in threads. */ export function selectMarketTimelineMessages( messages: TimelineMessage[], diff --git a/desktop/src/features/market/lib/useMarketChannelTimeline.tsx b/desktop/src/features/market/lib/useMarketChannelTimeline.tsx index e346d34da2..8760bcfbaa 100644 --- a/desktop/src/features/market/lib/useMarketChannelTimeline.tsx +++ b/desktop/src/features/market/lib/useMarketChannelTimeline.tsx @@ -20,10 +20,15 @@ export function useMarketChannelTimeline(messages: TimelineMessage[]) { () => anchor ? { - [anchor.id]: , + [anchor.id]: ( + + ), } : undefined, - [anchor], + [anchor, projection?.bids], ); return { diff --git a/desktop/src/features/market/ui/MarketChannelIntro.tsx b/desktop/src/features/market/ui/MarketChannelIntro.tsx index 8f78c1efba..cdaf52e35f 100644 --- a/desktop/src/features/market/ui/MarketChannelIntro.tsx +++ b/desktop/src/features/market/ui/MarketChannelIntro.tsx @@ -5,7 +5,10 @@ import { MessageCircle } from "lucide-react"; import { useMarketChannel } from "@/features/market/lib/MarketChannelContext"; import type { MarketBid } from "@/features/market/lib/marketProtocol"; -import { isMarketProtocolMessage } from "@/features/market/lib/marketTimeline"; +import { + isMarketProtocolMessage, + marketBidsAfterAnchor, +} from "@/features/market/lib/marketTimeline"; import { MarketContractCard } from "@/features/market/ui/MarketContractCard"; import type { TimelineMessage } from "@/features/messages/types"; import { Button } from "@/shared/ui/button"; @@ -79,21 +82,18 @@ function BidList({ export function MarketChannelIntro({ anchorMessage, + bids, }: { anchorMessage: Pick; + bids: MarketBid[]; }): React.ReactNode { const projection = useMarketChannel(); if (!projection || isMarketProtocolMessage(anchorMessage)) return undefined; - const bids = projection.bids.filter( - (bid) => - bid.createdAt > anchorMessage.createdAt || - (bid.createdAt === anchorMessage.createdAt && - bid.eventId.localeCompare(anchorMessage.id) > 0), - ); + const visibleBids = marketBidsAfterAnchor(bids, anchorMessage); return (
- +
); }