This commit is contained in:
Jin Yucong 2024-07-05 14:36:50 +08:00
parent 5b1aaee605
commit 3b737a078a
63 changed files with 1132 additions and 1853 deletions

View file

@ -1,24 +1,17 @@
'use client';
"use client";
/* eslint-disable @next/next/no-img-element */
import React, { MutableRefObject, useEffect, useState } from 'react';
import { Message } from './ChatWindow';
import { cn } from '@/lib/utils';
import {
BookCopy,
Disc3,
Volume2,
StopCircle,
Layers3,
Plus,
} from 'lucide-react';
import Markdown from 'markdown-to-jsx';
import Copy from './MessageActions/Copy';
import Rewrite from './MessageActions/Rewrite';
import MessageSources from './MessageSources';
import SearchImages from './SearchImages';
import SearchVideos from './SearchVideos';
import { useSpeech } from 'react-text-to-speech';
import React, { MutableRefObject, useEffect, useState } from "react";
import { Message } from "./ChatWindow";
import { cn } from "@/lib/utils";
import { BookCopy, Disc3, Volume2, StopCircle, Layers3, Plus } from "lucide-react";
import Markdown from "markdown-to-jsx";
import Copy from "./MessageActions/Copy";
import Rewrite from "./MessageActions/Rewrite";
import MessageSources from "./MessageSources";
import SearchImages from "./SearchImages";
import SearchVideos from "./SearchVideos";
import { useSpeech } from "react-text-to-speech";
const MessageBox = ({
message,
@ -45,11 +38,7 @@ const MessageBox = ({
useEffect(() => {
const regex = /\[(\d+)\]/g;
if (
message.role === 'assistant' &&
message?.sources &&
message.sources.length > 0
) {
if (message.role === "assistant" && message?.sources && message.sources.length > 0) {
return setParsedMessage(
message.content.replace(
regex,
@ -59,7 +48,7 @@ const MessageBox = ({
);
}
setSpeechMessage(message.content.replace(regex, ''));
setSpeechMessage(message.content.replace(regex, ""));
setParsedMessage(message.content);
}, [message.content, message.sources, message.role]);
@ -67,27 +56,20 @@ const MessageBox = ({
return (
<div>
{message.role === 'user' && (
<div className={cn('w-full', messageIndex === 0 ? 'pt-16' : 'pt-8')}>
<h2 className="text-black dark:text-white font-medium text-3xl lg:w-9/12">
{message.content}
</h2>
{message.role === "user" && (
<div className={cn("w-full", messageIndex === 0 ? "pt-16" : "pt-8")}>
<h2 className="text-black dark:text-white font-medium text-3xl lg:w-9/12">{message.content}</h2>
</div>
)}
{message.role === 'assistant' && (
{message.role === "assistant" && (
<div className="flex flex-col space-y-9 lg:space-y-0 lg:flex-row lg:justify-between lg:space-x-9">
<div
ref={dividerRef}
className="flex flex-col space-y-6 w-full lg:w-9/12"
>
<div ref={dividerRef} className="flex flex-col space-y-6 w-full lg:w-9/12">
{message.sources && message.sources.length > 0 && (
<div className="flex flex-col space-y-2">
<div className="flex flex-row items-center space-x-2">
<BookCopy className="text-black dark:text-white" size={20} />
<h3 className="text-black dark:text-white font-medium text-xl">
Sources
</h3>
<h3 className="text-black dark:text-white font-medium text-xl">Sources</h3>
</div>
<MessageSources sources={message.sources} />
</div>
@ -95,20 +77,15 @@ const MessageBox = ({
<div className="flex flex-col space-y-2">
<div className="flex flex-row items-center space-x-2">
<Disc3
className={cn(
'text-black dark:text-white',
isLast && loading ? 'animate-spin' : 'animate-none',
)}
className={cn("text-black dark:text-white", isLast && loading ? "animate-spin" : "animate-none")}
size={20}
/>
<h3 className="text-black dark:text-white font-medium text-xl">
Answer
</h3>
<h3 className="text-black dark:text-white font-medium text-xl">Answer</h3>
</div>
<Markdown
className={cn(
'prose dark:prose-invert prose-p:leading-relaxed prose-pre:p-0',
'max-w-none break-words text-black dark:text-white text-sm md:text-base font-medium',
"prose dark:prose-invert prose-p:leading-relaxed prose-pre:p-0",
"max-w-none break-words text-black dark:text-white text-sm md:text-base font-medium",
)}
>
{parsedMessage}
@ -125,7 +102,7 @@ const MessageBox = ({
<Copy initialMessage={message.content} message={message} />
<button
onClick={() => {
if (speechStatus === 'started') {
if (speechStatus === "started") {
stop();
} else {
start();
@ -133,11 +110,7 @@ const MessageBox = ({
}}
className="p-2 text-black/70 dark:text-white/70 rounded-xl hover:bg-light-secondary dark:hover:bg-dark-secondary transition duration-200 hover:text-black dark:hover:text-white"
>
{speechStatus === 'started' ? (
<StopCircle size={18} />
) : (
<Volume2 size={18} />
)}
{speechStatus === "started" ? <StopCircle size={18} /> : <Volume2 size={18} />}
</button>
</div>
</div>
@ -145,7 +118,7 @@ const MessageBox = ({
{isLast &&
message.suggestions &&
message.suggestions.length > 0 &&
message.role === 'assistant' &&
message.role === "assistant" &&
!loading && (
<>
<div className="h-px w-full bg-light-secondary dark:bg-dark-secondary" />
@ -156,10 +129,7 @@ const MessageBox = ({
</div>
<div className="flex flex-col space-y-3">
{message.suggestions.map((suggestion, i) => (
<div
className="flex flex-col space-y-3 text-sm"
key={i}
>
<div className="flex flex-col space-y-3 text-sm" key={i}>
<div className="h-px w-full bg-light-secondary dark:bg-dark-secondary" />
<div
onClick={() => {
@ -167,13 +137,8 @@ const MessageBox = ({
}}
className="cursor-pointer flex flex-row justify-between font-medium space-x-2 items-center"
>
<p className="transition duration-200 hover:text-[#24A0ED]">
{suggestion}
</p>
<Plus
size={20}
className="text-[#24A0ED] flex-shrink-0"
/>
<p className="transition duration-200 hover:text-[#24A0ED]">{suggestion}</p>
<Plus size={20} className="text-[#24A0ED] flex-shrink-0" />
</div>
</div>
))}
@ -184,14 +149,8 @@ const MessageBox = ({
</div>
</div>
<div className="lg:sticky lg:top-20 flex flex-col items-center space-y-3 w-full lg:w-3/12 z-30 h-full pb-4">
<SearchImages
query={history[messageIndex - 1].content}
chat_history={history.slice(0, messageIndex - 1)}
/>
<SearchVideos
chat_history={history.slice(0, messageIndex - 1)}
query={history[messageIndex - 1].content}
/>
<SearchImages query={history[messageIndex - 1].content} chat_history={history.slice(0, messageIndex - 1)} />
<SearchVideos chat_history={history.slice(0, messageIndex - 1)} query={history[messageIndex - 1].content} />
</div>
</div>
)}