Spaces:
Runtime error
Runtime error
File size: 5,080 Bytes
0971cc4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
import React, { useEffect, useRef } from "react";
import Image from "next/image";
import OllamaLogo from "../../../public/ollama.png";
import CodeDisplayBlock from "../code-display-block";
import { Message } from "ai";
interface ChatListProps {
messages: Message[];
isLoading: boolean;
}
const MessageToolbar = () => (
<div className="mt-1 flex gap-3 empty:hidden juice:flex-row-reverse">
<div className="text-gray-400 flex self-end lg:self-center items-center justify-center lg:justify-start mt-0 -ml-1 h-7 gap-[2px] invisible">
<span>Regenerate</span>
<span>Edit</span>
</div>
</div>
);
export default function ChatList({ messages, isLoading }: ChatListProps) {
const bottomRef = useRef<HTMLDivElement>(null);
const scrollToBottom = () => {
bottomRef.current?.scrollIntoView({ behavior: "auto", block: "end" });
};
useEffect(() => {
if (isLoading) {
return;
}
// if user scrolls up, disable auto-scroll
scrollToBottom();
}, [messages, isLoading]);
if (messages.length === 0) {
return (
<div className="w-full h-full flex justify-center items-center">
<div className="flex flex-col gap-4 items-center">
<Image
src={OllamaLogo}
alt="AI"
width={60}
height={60}
className="h-20 w-14 object-contain dark:invert"
/>
<p className="text-center text-xl text-muted-foreground">
How can I help you today?
</p>
</div>
</div>
);
}
return (
<div
id="scroller"
className="w-[800px] overflow-y-scroll overflow-x-hidden h-full justify-center m-auto"
>
<div className="px-4 py-2 justify-center text-base md:gap-6 m-auto">
{messages
.filter((message) => message.role !== "system")
.map((message, index) => (
<div
key={index}
className="flex flex-1 text-base mx-auto gap-3 juice:gap-4 juice:md:gap-6 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem]"
>
<div className="flex flex-1 text-base mx-auto gap-3 juice:gap-4 juice:md:gap-6 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem]">
<div className="flex-shrink-0 flex flex-col relative items-end">
<div className="pt-0.5">
<div className="gizmo-shadow-stroke flex h-6 w-6 items-center justify-center overflow-hidden rounded-full">
{message.role === "user" ? (
<div className="dark:invert h-full w-full bg-black" />
) : (
<Image
src={OllamaLogo}
alt="AI"
className="object-contain dark:invert aspect-square h-full w-full"
/>
)}
</div>
</div>
</div>
{message.role === "user" && (
<div className="relative flex w-full min-w-0 flex-col">
<div className="font-semibold pb-2">You</div>
<div className="flex-col gap-1 md:gap-3">
{message.content}
</div>
<MessageToolbar />
</div>
)}
{message.role === "assistant" && (
<div className="relative flex w-full min-w-0 flex-col">
<div className="font-semibold pb-2">Assistant</div>
<div className="flex-col gap-1 md:gap-3">
<span className="whitespace-pre-wrap">
{/* Check if the message content contains a code block */}
{message.content.split("```").map((part, index) => {
if (index % 2 === 0) {
return (
<React.Fragment key={index}>
{part}
</React.Fragment>
);
} else {
return (
<CodeDisplayBlock
key={index}
code={part.trim()}
lang=""
/>
);
}
})}
{isLoading &&
messages.indexOf(message) === messages.length - 1 && (
<span className="animate-pulse" aria-label="Typing">
...
</span>
)}
</span>
</div>
<MessageToolbar />
</div>
)}
</div>
</div>
))}
</div>
<div id="anchor" ref={bottomRef}></div>
</div>
);
}
|