diff --git a/src/lib/components/IntentListDetailRow.svelte b/src/lib/components/IntentListDetailRow.svelte index 8763ada..fb11892 100644 --- a/src/lib/components/IntentListDetailRow.svelte +++ b/src/lib/components/IntentListDetailRow.svelte @@ -1,5 +1,6 @@
@@ -56,7 +77,21 @@ {#each row.protocolBadges as badge (badge)} {badge} {/each} - Order {row.orderIdShort} + {copied ? "Copied!" : `Order ${row.orderIdShort}`} User {row.userShort} {row.inputCount} inputs • {row.outputCount} outputs + (b.submitTime ?? 0) - (a.submitTime ?? 0) || a.fillDeadline - b.fillDeadline; + +export const compareExpiredRows = (a: BaseIntentRow, b: BaseIntentRow) => + (b.submitTime ?? 0) - (a.submitTime ?? 0) || b.fillDeadline - a.fillDeadline; + function flattenInputs(inputs: { chainId: bigint; inputs: [bigint, bigint][] }[]) { return inputs.flatMap((chainInput) => { return chainInput.inputs.map((input) => ({ @@ -211,6 +224,9 @@ export function buildBaseIntentRow(orderContainer: OrderContainer): BaseIntentRo orderIdShort: shortAddress(orderId, 10, 4), userShort: shortAddress(order.user, 8, 4), fillDeadline: order.fillDeadline, + submitTime: ((orderContainer as any).submitTime ?? (orderContainer as any).createdAt) as + | number + | undefined, inputCount: inputChipsRaw.length, outputCount: outputChipsRaw.length, chainScope, diff --git a/src/lib/libraries/orderServer.ts b/src/lib/libraries/orderServer.ts index 213a506..15d563b 100644 --- a/src/lib/libraries/orderServer.ts +++ b/src/lib/libraries/orderServer.ts @@ -244,12 +244,23 @@ export function parseOrderStatusPayload(payload: unknown): OrderContainer { ? normalizeStandardOrder(rawOrder) : normalizeMultichainOrder(rawOrder); - return { + const container: OrderContainer = { inputSettler: toHexString(envelope.inputSettler, "inputSettler"), order, sponsorSignature: normalizeSignature(envelope.sponsorSignature), allocatorSignature: normalizeSignature(envelope.allocatorSignature) }; + + // Capture the order-server submit time so the intent list can sort by it. + // Normalize ms -> s defensively (the field is only typed as `number`). + const meta = (envelope as Record).meta as { submitTime?: unknown } | undefined; + const rawSubmit = typeof meta?.submitTime === "number" ? meta.submitTime : undefined; + if (rawSubmit !== undefined) { + (container as { submitTime?: number }).submitTime = + rawSubmit > 1e12 ? Math.floor(rawSubmit / 1000) : rawSubmit; + } + + return container; } export class OrderServer { diff --git a/src/lib/screens/IntentList.svelte b/src/lib/screens/IntentList.svelte index 4b292ab..34b422e 100644 --- a/src/lib/screens/IntentList.svelte +++ b/src/lib/screens/IntentList.svelte @@ -8,6 +8,8 @@ withTiming, formatRelativeDeadline, formatRemaining, + compareActiveRows, + compareExpiredRows, type TimedIntentRow } from "$lib/libraries/intentList"; import ScreenFrame from "$lib/components/ui/ScreenFrame.svelte"; @@ -86,21 +88,37 @@ }, 1000); onDestroy(() => clearInterval(clock)); + async function handleSelectActive(row: TimedIntentRow) { + selectedOrder = row.orderContainer; + await tick(); + scroll(3)(); + } + + function toggleExpired(orderId: string) { + expandedExpiredOrderId = expandedExpiredOrderId === orderId ? undefined : orderId; + } + + // The card wrappers use role="button" (not a native +
+ {#if expandedExpiredOrderId === row.orderId}