From 6efc767ba79768050f54ad8cfd5ca7fefc181921 Mon Sep 17 00:00:00 2001 From: Peolite001 Date: Sun, 30 Aug 2026 08:36:10 +0100 Subject: [PATCH 1/2] Fix overlapping stream fetches by tracking request ids --- .../streams/[id]/stream-details-content.tsx | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/streams/[id]/stream-details-content.tsx b/frontend/src/app/streams/[id]/stream-details-content.tsx index 504385b9..7f8e668a 100644 --- a/frontend/src/app/streams/[id]/stream-details-content.tsx +++ b/frontend/src/app/streams/[id]/stream-details-content.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useState, useCallback, useMemo } from "react"; +import { useEffect, useState, useCallback, useMemo, useRef } from "react"; import Link from "next/link"; import { getApiBaseUrl } from "@/lib/api/_shared"; import { logger } from "@/lib/logger"; @@ -92,21 +92,29 @@ export default function StreamDetailsContent({ streamId }: { streamId: string }) autoReconnect: true, }); + const streamReqId = useRef(0); const fetchStream = useCallback(async (signal?: AbortSignal) => { if (!streamId) return; + const reqId = ++streamReqId.current; try { const response = await fetch(`${API_BASE_URL}/streams/${streamId}`, { signal }); if (!response.ok) throw new Error("Stream not found"); const data = await response.json(); - setStream(data); + if (reqId === streamReqId.current) { + setStream(data); + } } catch (err) { if (err instanceof Error && err.name === "AbortError") return; - setError(err instanceof Error ? err.message : "Failed to fetch stream"); + if (reqId === streamReqId.current) { + setError(err instanceof Error ? err.message : "Failed to fetch stream"); + } } }, [streamId]); + const eventsReqId = useRef(0); const fetchEvents = useCallback(async (page: number, signal?: AbortSignal) => { if (!streamId) return; + const reqId = ++eventsReqId.current; try { const response = await fetch( `${API_BASE_URL}/streams/${streamId}/events?page=${page}&limit=${EVENTS_PER_PAGE}`, @@ -114,8 +122,10 @@ export default function StreamDetailsContent({ streamId }: { streamId: string }) ); if (response.ok) { const data = await response.json(); - setEvents(data.events || []); - setEventsTotal(data.total || 0); + if (reqId === eventsReqId.current) { + setEvents(data.events || []); + setEventsTotal(data.total || 0); + } } } catch (err) { if (err instanceof Error && err.name === "AbortError") return; From 99b8a889d73dce74e302c10bf6e1e135a0ce282f Mon Sep 17 00:00:00 2001 From: Peolite001 Date: Sun, 30 Aug 2026 08:55:01 +0100 Subject: [PATCH 2/2] fix: disable closing stream creation wizard mid-transaction --- .../components/stream-creation/StreamCreationWizard.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/stream-creation/StreamCreationWizard.tsx b/frontend/src/components/stream-creation/StreamCreationWizard.tsx index 50aee5b6..385807b1 100644 --- a/frontend/src/components/stream-creation/StreamCreationWizard.tsx +++ b/frontend/src/components/stream-creation/StreamCreationWizard.tsx @@ -119,7 +119,10 @@ export const StreamCreationWizard: React.FC = ({ const router = useRouter(); - const dialogRef = useModalDialog({ onClose }); + const dialogRef = useModalDialog({ + onClose, + isCloseDisabled: isSubmitting || isPolling + }); const [walletBalance, setWalletBalance] = useState(null); const [walletBalanceLoading, setWalletBalanceLoading] = useState(false); @@ -627,7 +630,7 @@ export const StreamCreationWizard: React.FC = ({ )}
- {currentStep < STEPS.length ? (