diff --git a/ui/app/(prowler)/lighthouse/_components/chat/lighthouse-v2-chat-page.tsx b/ui/app/(prowler)/lighthouse/_components/chat/lighthouse-v2-chat-page.tsx index adc018e165..7caf5ba727 100644 --- a/ui/app/(prowler)/lighthouse/_components/chat/lighthouse-v2-chat-page.tsx +++ b/ui/app/(prowler)/lighthouse/_components/chat/lighthouse-v2-chat-page.tsx @@ -22,7 +22,10 @@ import { buildOptimisticMessage, buildSessionTitle, } from "@/app/(prowler)/lighthouse/_lib/messages"; -import { notifyLighthouseV2SessionsChanged } from "@/app/(prowler)/lighthouse/_lib/session-events"; +import { + LIGHTHOUSE_V2_NEW_CHAT_EVENT, + notifyLighthouseV2SessionsChanged, +} from "@/app/(prowler)/lighthouse/_lib/session-events"; import { parseStreamEvent } from "@/app/(prowler)/lighthouse/_lib/stream-event-parser"; import { buildLighthouseV2StreamUrl } from "@/app/(prowler)/lighthouse/_lib/stream-url"; import { @@ -305,6 +308,27 @@ export function LighthouseV2ChatPage({ } }); + // The sidebar "+" can't rely on routing to reset the latest conversation (its + // URL was set via replaceState, invisible to Next's router), so reset in place. + useMountEffect(() => { + const resetToNewChat = () => { + closeStream(); + setActiveSessionId(null); + setMessages([]); + setInput(""); + setFeedback(null); + setBlockedByConflict(false); + setIsSubmitting(false); + setLastSubmittedText(null); + setStreamState(createInitialLighthouseV2StreamState()); + window.history.replaceState(null, "", "/lighthouse"); + }; + + window.addEventListener(LIGHTHOUSE_V2_NEW_CHAT_EVENT, resetToNewChat); + return () => + window.removeEventListener(LIGHTHOUSE_V2_NEW_CHAT_EVENT, resetToNewChat); + }); + const hasLiveAssistantActivity = Boolean(streamState.activeTaskId) || Boolean(streamState.assistantText) || diff --git a/ui/app/(prowler)/lighthouse/_components/navigation/lighthouse-v2-sidebar-chat.tsx b/ui/app/(prowler)/lighthouse/_components/navigation/lighthouse-v2-sidebar-chat.tsx index 15b0293fbc..ef44ec4c15 100644 --- a/ui/app/(prowler)/lighthouse/_components/navigation/lighthouse-v2-sidebar-chat.tsx +++ b/ui/app/(prowler)/lighthouse/_components/navigation/lighthouse-v2-sidebar-chat.tsx @@ -8,7 +8,10 @@ import { archiveLighthouseV2Session, getLighthouseV2Sessions, } from "@/app/(prowler)/lighthouse/_actions"; -import { LIGHTHOUSE_V2_SESSIONS_CHANGED_EVENT } from "@/app/(prowler)/lighthouse/_lib/session-events"; +import { + LIGHTHOUSE_V2_SESSIONS_CHANGED_EVENT, + notifyLighthouseV2NewChat, +} from "@/app/(prowler)/lighthouse/_lib/session-events"; import type { LighthouseV2Session } from "@/app/(prowler)/lighthouse/_types"; import { Button } from "@/components/shadcn/button/button"; import { @@ -37,6 +40,8 @@ export function LighthouseV2SidebarChat({ isOpen }: { isOpen: boolean }) { }; const handleNewSession = () => { + // Reset an already-open chat in place, then route (covers other pages too). + notifyLighthouseV2NewChat(); router.push("/lighthouse"); }; diff --git a/ui/app/(prowler)/lighthouse/_lib/session-events.ts b/ui/app/(prowler)/lighthouse/_lib/session-events.ts index fabd378e9a..9f50b59762 100644 --- a/ui/app/(prowler)/lighthouse/_lib/session-events.ts +++ b/ui/app/(prowler)/lighthouse/_lib/session-events.ts @@ -5,3 +5,13 @@ export function notifyLighthouseV2SessionsChanged() { if (typeof window === "undefined") return; window.dispatchEvent(new Event(LIGHTHOUSE_V2_SESSIONS_CHANGED_EVENT)); } + +export const LIGHTHOUSE_V2_NEW_CHAT_EVENT = "lighthouse-v2:new-chat"; + +// Lets the sidebar reset an already-mounted chat page. router.push("/lighthouse") +// is a no-op when the URL was set via replaceState (Next's router never saw it), +// so the latest conversation needs a client-side reset signal. +export function notifyLighthouseV2NewChat() { + if (typeof window === "undefined") return; + window.dispatchEvent(new Event(LIGHTHOUSE_V2_NEW_CHAT_EVENT)); +}