diff --git a/src/components/RecoveryBanner.tsx b/src/components/RecoveryBanner.tsx index 32282763..cf6f7890 100644 --- a/src/components/RecoveryBanner.tsx +++ b/src/components/RecoveryBanner.tsx @@ -1,7 +1,11 @@ "use client"; import { useState } from "react"; +import { decodeEventLog } from "viem"; +import Link from "next/link"; import { EXPLORER_URL } from "../../lib/contracts/constants"; +import { storyFactoryAbi } from "../../lib/contracts/abi"; +import { publicClient } from "../../lib/rpc"; import type { PublishIntentData } from "../hooks/usePublishIntent"; import { MAX_RETRY_ATTEMPTS } from "../hooks/usePublishIntent"; @@ -17,14 +21,68 @@ export function RecoveryBanner({ onDismiss, }: RecoveryBannerProps) { const [retrying, setRetrying] = useState(false); + const [success, setSuccess] = useState(false); + const [storylineId, setStorylineId] = useState(null); const exhausted = intent.retryCount >= MAX_RETRY_ATTEMPTS; async function handleRetry() { setRetrying(true); - await onRetry(); + const result = await onRetry(); + if (result.success && intent.txHash) { + // Parse storylineId from tx receipt for the story link + try { + const receipt = await publicClient.getTransactionReceipt({ + hash: intent.txHash as `0x${string}`, + }); + for (const log of receipt.logs) { + try { + const decoded = decodeEventLog({ + abi: storyFactoryAbi, + data: log.data, + topics: log.topics, + }); + if (decoded.eventName === "StorylineCreated") { + setStorylineId(Number(decoded.args.storylineId)); + break; + } + if (decoded.eventName === "PlotChained") { + setStorylineId(Number(decoded.args.storylineId)); + break; + } + } catch { /* not our event */ } + } + } catch { /* receipt fetch failed, still show success */ } + setSuccess(true); + } setRetrying(false); } + if (success) { + return ( +
+

+ Storyline indexed successfully! +

+
+ {storylineId != null && ( + + View your story + + )} + + Go home + +
+
+ ); + } + return (

diff --git a/src/hooks/usePublishIntent.ts b/src/hooks/usePublishIntent.ts index e617a3c0..0d70247c 100644 --- a/src/hooks/usePublishIntent.ts +++ b/src/hooks/usePublishIntent.ts @@ -128,7 +128,8 @@ export function usePublishIntent() { // 409 = already indexed, treat as success if (response.ok || response.status === 409) { removeIntent(); - if (mountedRef.current) setPendingIntent(null); + // Don't setPendingIntent(null) here — let RecoveryBanner show + // the success state before unmounting return { success: true }; }