feat: add hover preview tooltips to message sidebar

Enhanced YOU/ASST message navigation:
- Click scrolls to message (already implemented)
- Hover shows preview tooltip with:
  - Role label (You/Assistant)
  - Message number
  - First 100 chars of message content
- Smooth slide-in animation on hover
- Slightly larger buttons with scale effect on hover
This commit is contained in:
Gemini AI
2025-12-23 13:50:44 +04:00
Unverified
parent 55f5945b61
commit 37ff96f849

View File

@@ -634,28 +634,54 @@ export default function MultiTaskChat(props: MultiTaskChatProps) {
</div>
</div>
{/* Message Navigation Sidebar - YOU/ASST labels */}
{/* Message Navigation Sidebar - YOU/ASST labels with hover preview */}
<Show when={selectedTaskId() && filteredMessageIds().length > 0}>
<div class="w-12 shrink-0 bg-zinc-900/40 border-l border-white/5 overflow-y-auto py-2 px-1 flex flex-col items-center gap-1">
<div class="w-14 shrink-0 bg-zinc-900/40 border-l border-white/5 overflow-y-auto py-2 px-1.5 flex flex-col items-center gap-1">
<For each={filteredMessageIds()}>
{(messageId, index) => {
const msg = () => messageStore().getMessage(messageId);
const isUser = () => msg()?.role === "user";
const [showPreview, setShowPreview] = createSignal(false);
// Get message preview text (first 100 chars)
const previewText = () => {
const message = msg();
if (!message) return "";
const content = message.parts?.[0]?.content || message.content || "";
const text = typeof content === "string" ? content : JSON.stringify(content);
return text.length > 100 ? text.substring(0, 100) + "..." : text;
};
return (
<button
onClick={() => {
// Scroll to message
const element = document.getElementById(`msg-${messageId}`);
element?.scrollIntoView({ behavior: "smooth", block: "center" });
}}
class={`w-9 py-1 rounded text-[8px] font-black uppercase transition-all ${isUser()
? "bg-indigo-500/20 border border-indigo-500/40 text-indigo-400 hover:bg-indigo-500/30"
: "bg-emerald-500/20 border border-emerald-500/40 text-emerald-400 hover:bg-emerald-500/30"
}`}
title={`${isUser() ? "User" : "Assistant"} message ${index() + 1}`}
>
{isUser() ? "YOU" : "ASST"}
</button>
<div class="relative group">
<button
onClick={() => {
// Scroll to message
const element = document.getElementById(`msg-${messageId}`);
element?.scrollIntoView({ behavior: "smooth", block: "center" });
}}
onMouseEnter={() => setShowPreview(true)}
onMouseLeave={() => setShowPreview(false)}
class={`w-10 py-1.5 rounded text-[8px] font-black uppercase transition-all cursor-pointer ${isUser()
? "bg-indigo-500/20 border border-indigo-500/40 text-indigo-400 hover:bg-indigo-500/40 hover:scale-105"
: "bg-emerald-500/20 border border-emerald-500/40 text-emerald-400 hover:bg-emerald-500/40 hover:scale-105"
}`}
>
{isUser() ? "YOU" : "ASST"}
</button>
{/* Hover Preview Tooltip */}
<Show when={showPreview()}>
<div class="absolute right-full mr-2 top-0 w-64 max-h-32 overflow-hidden bg-zinc-900 border border-white/10 rounded-lg shadow-xl p-2 z-50 animate-in fade-in slide-in-from-right-2 duration-150">
<div class={`text-[9px] font-bold uppercase mb-1 ${isUser() ? "text-indigo-400" : "text-emerald-400"}`}>
{isUser() ? "You" : "Assistant"} Message {index() + 1}
</div>
<p class="text-[11px] text-zinc-300 leading-relaxed line-clamp-4">
{previewText()}
</p>
</div>
</Show>
</div>
);
}}
</For>