Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 76 additions & 78 deletions app/classroom/[classroomId]/chat/MessageBox.tsx
Original file line number Diff line number Diff line change
@@ -1,116 +1,114 @@
"use client";
import { useState } from "react";
import {
ChatBubble,
ChatBubbleAvatar,
ChatBubbleMessage,
} from "@shared/components/ui/chat/chat-bubble";
import { ChatMessageList } from "@shared/components/ui/chat/chat-message-list";
import { ChatInput } from "@shared/components/ui/chat/chat-input";
import { Button } from "@/shared/components/ui/button";

import {
ChatClientWithSession,
RagFlowMessage,
RagFlowMessages,
sendMessage,
} from "@shared/lib/ragflow/chat/chat-client";
import { toast } from "@shared/hooks/use-toast";
import LogoComponent from "@/shared/components/Logo";
import { SendIcon } from "lucide-react";

function MessageBox(props: {
interface MessageBoxProps {
chatClient: ChatClientWithSession;
messageHistory: RagFlowMessages | null;
}) {
const [value, setValue] = useState("");
}

const [messages, setMessage] = useState<RagFlowMessages>(
props.messageHistory ? props.messageHistory : []
export default function MessageBox({
chatClient,
messageHistory,
}: MessageBoxProps) {
const [value, setValue] = useState("");
const [messages, setMessages] = useState<RagFlowMessages>(
messageHistory || []
);
const [isLoading, setIsLoading] = useState(false);

async function handle() {
const ownMessage = { role: "user", content: value } as RagFlowMessage;

setMessage((oldArray) => [...oldArray, ownMessage]);
async function handleSend() {
if (!value.trim()) return;

const userMessage: RagFlowMessage = { role: "user", content: value };
setMessages((prev) => [...prev, userMessage]);
setValue("");
setIsLoading(true);
const response = await sendMessage(chatClient, value);
setIsLoading(false);

const messageResponse = await sendMessage(props.chatClient, value);

if (!messageResponse.ragflowCallSuccess) {
if (!response.ragflowCallSuccess) {
toast({
title: "Error sending message",
description: `Please try refreshing the page`,
description: "Please try refreshing the page",
duration: 10000,
variant: "destructive",
});
return;
}

const messageData = {
const assistantMessage: RagFlowMessage = {
role: "assistant",
content: messageResponse.response,
} as RagFlowMessage;

setMessage((oldArray) => [...oldArray, messageData]);
// console.log("response thingy2", messages);
content: response.response,
};
setMessages((prev) => [...prev, assistantMessage]);
}

return (
<div className="min-h-screen w-1/2 flex-col justify-self-center p-4 text-gray-800 dark:text-white">
<h1 className="mb-4 text-2xl font-bold">Chat:</h1>

<div className="flex-col rounded-t-lg bg-gray-100 p-3">
{messages.map((aMessage, idx) => (
<div
key={idx}
className={`my-2 max-w-md rounded-lg p-3 shadow-md ${
aMessage.role != "assistant"
? "justify-self-end bg-green-200 hover:bg-green-300"
: "justify-self-start bg-blue-200 hover:bg-blue-300"
}`}
>
<p className="font-medium text-gray-800">{aMessage.content}</p>
</div>
))}
<div className="flex h-[600px] w-11/12 flex-col place-self-center rounded border p-4 text-gray-800 shadow dark:text-white">
<LogoComponent
className={"size-24 place-self-center stroke-black stroke-[10px]"}
/>
{/* doesn't seem like 400 px does much */}
<div className="h-[400px] flex-1 overflow-auto">
<ChatMessageList smooth>
{messages.map((msg, index) => (
<ChatBubble
key={index}
variant={msg.role === "assistant" ? "received" : "sent"}
>
{msg.role === "assistant" ? (
<ChatBubbleAvatar fallback="AI" />
) : (
<ChatBubbleAvatar fallback="Me" />
)}
<ChatBubbleMessage
variant={msg.role === "assistant" ? "received" : "sent"}
className="p-2"
>
{msg.content}
</ChatBubbleMessage>
</ChatBubble>
))}
{isLoading && (
<ChatBubble variant="received">
<ChatBubbleAvatar fallback="AI" />
<ChatBubbleMessage isLoading variant="received" />
</ChatBubble>
)}
</ChatMessageList>
</div>
{/* <div className="justify-self-end"> */}
<div className="flex items-center rounded-b-lg bg-gray-200 px-4 py-2 dark:bg-gray-700">
<textarea
id="chat"
rows={1}
className="mx-2 block w-full rounded-lg border border-gray-300 bg-white p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
placeholder="Your message..."
<div className="relative mt-4">
<ChatInput
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
></textarea>
<button
onClick={handle}
className="inline-flex cursor-pointer justify-center rounded-full p-2 text-blue-600 hover:bg-blue-100 dark:text-blue-500 dark:hover:bg-gray-600"
>
<svg
className="h-5 w-5 rotate-90 rtl:-rotate-90"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 18 20"
>
<path d="m17.914 18.594-8-18a1 1 0 0 0-1.828 0l-8 18a1 1 0 0 0 1.157 1.376L8 18.281V9a1 1 0 0 1 2 0v9.281l6.758 1.689a1 1 0 0 0 1.156-1.376Z" />
</svg>
<span className="sr-only">Send message</span>
</button>

{/* <input
type="text"
placeholder="Type your message here..."
className="w-100 rounded-md border border-gray-300 p-2 dark:bg-gray-700 dark:text-white"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
onChange={(e) => setValue(e.target.value)}
placeholder="Type your message..."
/>

<button
className="ml-4 mt-2 rounded-md bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"
onClick={handle}
<Button
onClick={handleSend}
size="default"
className="absolute right-2 top-1/2 -translate-y-1/2"
>
Send
</button> */}
Send <SendIcon />
</Button>
</div>
</div>
);
}

export default MessageBox;
14 changes: 10 additions & 4 deletions app/classroom/[classroomId]/chat/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "@shared/lib/ragflow/chat/chat-client";
import { personalChatConfigTemplate } from "@shared/lib/ragflow/chat/chat-configs";
import { Button } from "@shared/components/ui/button";
import { Upload } from "lucide-react";
import { SpeechIcon, Upload } from "lucide-react";

export default async function ChatPage({
params,
Expand All @@ -30,7 +30,7 @@ export default async function ChatPage({
const { classroomId } = await params;
const classroomIdNum = Number(classroomId);
const user = userAndClassData.userData;
const username = user.user_metadata?.full_name ?? "User Name";
// const username = user.user_metadata?.full_name ?? "User Name";

const classroomInfo = userAndClassData.classroomsData.find(
(x) => x.id === classroomIdNum
Expand Down Expand Up @@ -150,7 +150,7 @@ export default async function ChatPage({
<strong>Chat Assistant ID:</strong> {chatAssistantId} <br></br>
<strong>Chat Session ID:</strong> {chatSessionId}
</p> */}
<p>
{/* <p>
<strong>Welcome to: </strong>
{classroomInfo.name}, <strong>{username}</strong> <br />
<strong>Ragflow Dataset ID:</strong> {datasetClient.client.datasetId}{" "}
Expand All @@ -159,7 +159,13 @@ export default async function ChatPage({
<br />
<strong>Chat Session ID:</strong>{" "}
{(chatClient.client as ChatClientWithSession).sessionId}
</p>
</p> */}
<h2 className="text-3xl font-bold tracking-tight">
{classroomInfo.name}
</h2>
<h1 className="flex flex-row gap-4 text-2xl font-medium tracking-tight text-muted-foreground">
<SpeechIcon className="mb-8 self-center" /> Personal Assistant
</h1>

<MessageBox
chatClient={chatClient.client as ChatClientWithSession}
Expand Down
2 changes: 1 addition & 1 deletion shared/components/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const LogoComponent = ({ className }: { className: string }) => (
viewBox="0 0 892.69 723.06"
className={className}
>
<path d="m773.83 446.71-.12.12v-.12h.12zM382.15 419.42c-1.54 0-3.1-.17-4.64-.51-5.51-1.23-10.21-4.53-13.23-9.29l-27.94-43.98c-3.02-4.76-4.02-10.41-2.79-15.92 1.23-5.5 4.53-10.2 9.29-13.23l187.12-118.86c9.83-6.25 22.91-3.32 29.15 6.51l27.94 43.99a20.95 20.95 0 0 1 2.79 15.92c-1.23 5.5-4.53 10.2-9.29 13.23L393.43 416.14c-3.43 2.18-7.32 3.3-11.28 3.3Zm159.14-184.69c-.14 0-.27.04-.39.11L353.79 353.7c-.06.04-.25.16-.32.46-.07.29.06.48.1.54l27.94 43.99c.04.06.16.26.45.32.28.06.49-.06.55-.1l187.12-118.86c.06-.04.25-.16.32-.46.07-.29-.06-.48-.1-.54s-27.94-43.99-27.94-43.99a.733.733 0 0 0-.61-.34Z" />
<path d="m 546 215 z M 382.15 419.42 c -1.54 0 -3.1 -0.17 -4.64 -0.51 c -5.51 -1.23 -10.21 -4.53 -13.23 -9.29 l -27.94 -43.98 c -3.02 -4.76 -4.02 -10.41 -2.79 -15.92 c 1.23 -5.5 4.53 -10.2 9.29 -13.23 l 187.12 -118.86 c 9.83 -6.25 22.91 -3.32 29.15 6.51 l 27.94 43.99 a 20.95 20.95 0 0 1 2.79 15.92 c -1.23 5.5 -4.53 10.2 -9.29 13.23 L 393.43 416.14 c -3.43 2.18 -7.32 3.3 -11.28 3.3 Z m 159.14 -184.69 c -0.14 0 -0.27 0.04 -0.39 0.11 L 353.79 353.7 c -0.06 0.04 -0.25 0.16 -0.32 0.46 c -0.07 0.29 0.06 0.48 0.1 0.54 l 27.94 43.99 c 0.04 0.06 0.16 0.26 0.45 0.32 c 0.28 0.06 0.49 -0.06 0.55 -0.1 l 187.12 -118.86 c 0.06 -0.04 0.25 -0.16 0.32 -0.46 c 0.07 -0.29 -0.06 -0.48 -0.1 -0.54 s -27.94 -43.99 -27.94 -43.99 a 0.733 0.733 0 0 0 -0.61 -0.34 Z" />{" "}
<path d="M305.24 435.71c-6.62 0-12.81-3.33-16.5-9.13-4.46-7.03-4.09-15.84.96-22.46l46.56-61.07 16.22 12.36-45.35 59.49 73.12-15.77 6.55 20.29-77.31 15.83c-1.42.31-2.84.45-4.24.45Z" />
<path d="M291.2 641.83h-.03c-10.97 0-20.65-6.94-25.27-18.08l-30.01-72.33h-45.94c-47.9 0-86.87-45.85-86.87-102.2V215.03c0-56.35 38.97-102.2 86.87-102.2h479.17c47.9 0 86.87 45.85 86.87 102.2H735.6c0-45.11-29.82-81.81-66.48-81.81H189.95c-36.66 0-66.48 36.7-66.48 81.81v234.19c0 45.11 29.82 81.81 66.48 81.81h59.56l35.23 84.91c1.42 3.44 3.84 5.5 6.46 5.5 2.63 0 5.06-2.06 6.5-5.51l35.22-84.9h120.61v20.39h-107l-30.01 72.33c-4.65 11.16-14.35 18.08-25.32 18.08Z" />
<path d="M745.8 311.93c-27.28 0-49.48-22.2-49.48-49.48s22.2-49.48 49.48-49.48 49.48 22.2 49.48 49.48-22.2 49.48-49.48 49.48Zm0-78.57c-16.04 0-29.09 13.05-29.09 29.09s13.05 29.09 29.09 29.09 29.09-13.05 29.09-29.09-13.05-29.09-29.09-29.09ZM468.73 446.72h24.22v106.19h-24.22z" />
Expand Down
Loading