From a69a2233abe0612006436579f5115d2354d1e2ce Mon Sep 17 00:00:00 2001 From: mawkone Date: Mon, 15 Jun 2026 14:57:34 -0700 Subject: [PATCH] Simplify chat by removing V avatar icon --- .../components/vibn-chat/chat-panel.tsx | 143 ++++++++++++++++-- 1 file changed, 127 insertions(+), 16 deletions(-) diff --git a/vibn-frontend/components/vibn-chat/chat-panel.tsx b/vibn-frontend/components/vibn-chat/chat-panel.tsx index 81ee9d2e..559e8fd2 100644 --- a/vibn-frontend/components/vibn-chat/chat-panel.tsx +++ b/vibn-frontend/components/vibn-chat/chat-panel.tsx @@ -9,7 +9,7 @@ import React, { type CSSProperties, } from "react"; import Link from "next/link"; -import { useSession } from "next-auth/react"; +import { ArrowDown, useSession } from "next-auth/react"; import { useParams, usePathname } from "next/navigation"; import { MessageSquare, @@ -520,28 +520,21 @@ const MessageBubble = React.memo(function MessageBubble({ style={{ width: 24, height: 24, - borderRadius: "50%", - background: "#f4f4f5", // Zinc-100 instead of black display: "flex", alignItems: "center", justifyContent: "center", marginRight: 8, flexShrink: 0, marginTop: 2, - border: "1px solid #e4e4e7", }} > - - V. - + + + + + + + )}
{ const isLast = i === items.length - 1; if (item.kind === "thought") { - return ; + return ; } if (item.kind === "text") { return ; @@ -668,6 +661,89 @@ function Timeline({ entries, isActiveStream }: { entries: TimelineEntry[], isAct * bubble so each round of multi-tool-loop output reads as a discrete * step instead of concatenating into a wall of text. */ + +function TimelineThought({ text, isStreaming }: { text: string; isStreaming?: boolean }) { + const [expanded, setExpanded] = React.useState(true); + + // Auto-collapse when streaming stops + const textLenRef = React.useRef(text.length); + React.useEffect(() => { + let t = setTimeout(() => { + if (text.length === textLenRef.current && !isStreaming) { + setExpanded(false); + } + }, 1500); + return () => clearTimeout(t); + }, [text, isStreaming]); + + React.useEffect(() => { + textLenRef.current = text.length; + }, [text]); + + return ( +
+ + + {expanded && ( +
+ ` : ""), + }} + /> +
+ )} +
+ ); +} + function TimelineText({ text, isStreaming }: { text: string; isStreaming?: boolean }) { const proseWrap: React.CSSProperties = { overflowWrap: "anywhere", @@ -1068,6 +1144,8 @@ export function ChatPanel({ ); const [showThreads, setShowThreads] = useState(false); const [mcpToken, setMcpToken] = useState(null); + const [showScrollButton, setShowScrollButton] = useState(false); + const scrollContainerRef = useRef(null); const [isChatMinimized, setIsChatMinimized] = useState(false); // Auto-minimize when navigating to dashboard, auto-open when navigating to preview @@ -2920,3 +2998,36 @@ export function ChatPanel({ ); } + + + + +function ScrollToBottomButton({ onClick, visible }: { onClick: () => void, visible: boolean }) { + if (!visible) return null; + return ( + + ); +}