Add @langchain/core dependency and update imports***

***Update SidepanelRouting to use dark mode***
***Add image support to PlaygroundMessage component
This commit is contained in:
n4ze3m
2024-02-03 17:51:11 +05:30
parent e6130f11da
commit be3a4ed256
13 changed files with 294 additions and 57 deletions

View File

@@ -1,7 +1,4 @@
import {
CheckIcon,
ClipboardIcon,
} from "@heroicons/react/24/outline"
import { CheckIcon, ClipboardIcon } from "@heroicons/react/24/outline"
import Markdown from "../../Common/Markdown"
import React from "react"
@@ -12,6 +9,7 @@ type Props = {
userAvatar?: JSX.Element
isBot: boolean
name: string
images?: string[]
}
export const PlaygroundMessage = (props: Props) => {
@@ -48,13 +46,11 @@ export const PlaygroundMessage = (props: Props) => {
</div>
</div>
<div className="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]">
{
props.isBot && (
{props.isBot && (
<span className="absolute mb-8 -top-4 left-0 text-xs text-gray-400 dark:text-gray-500">
{props.name}
</span>
)
}
)}
<div className="flex flex-grow flex-col gap-3">
<Markdown message={props.message} />
</div>
@@ -81,6 +77,19 @@ export const PlaygroundMessage = (props: Props) => {
)}
</div>
</div>
{props.images && (
<div className="flex md:max-w-2xl lg:max-w-xl xl:max-w-3xl p-3 m-auto w-full">
{props.images.map((image, index) => (
<div key={index} className="h-full rounded-md shadow relative">
<img
src={image}
alt="Uploaded"
className="h-full w-auto object-cover rounded-md min-w-[50px]"
/>
</div>
))}
</div>
)}
</div>
)
}

View File

@@ -20,6 +20,7 @@ export const SidePanelBody = () => {
isBot={message.isBot}
message={message.message}
name={message.name}
images={message.images || []}
/>
))}
<div className="w-full h-32 md:h-48 flex-shrink-0"></div>

View File

@@ -3,9 +3,17 @@ import { useMutation } from "@tanstack/react-query"
import React from "react"
import useDynamicTextareaSize from "~hooks/useDynamicTextareaSize"
import { useMessage } from "~hooks/useMessage"
import PhotoIcon from "@heroicons/react/24/outline/PhotoIcon"
import XMarkIcon from "@heroicons/react/24/outline/XMarkIcon"
import { toBase64 } from "~libs/to-base64"
export const SidepanelForm = () => {
type Props = {
dropedFile: File | undefined
}
export const SidepanelForm = ({ dropedFile }: Props) => {
const textareaRef = React.useRef<HTMLTextAreaElement>(null)
const inputRef = React.useRef<HTMLInputElement>(null)
const resetHeight = () => {
const textarea = textareaRef.current
@@ -15,16 +23,34 @@ export const SidepanelForm = () => {
}
const form = useForm({
initialValues: {
message: ""
message: "",
image: ""
}
})
useDynamicTextareaSize(
textareaRef,
form.values.message,
)
const onInputChange = async (
e: React.ChangeEvent<HTMLInputElement> | File
) => {
if (e instanceof File) {
const base64 = await toBase64(e)
form.setFieldValue("image", base64)
} else {
if (e.target.files) {
const base64 = await toBase64(e.target.files[0])
form.setFieldValue("image", base64)
}
}
}
const { onSubmit, selectedModel } = useMessage()
React.useEffect(() => {
if (dropedFile) {
onInputChange(dropedFile)
}
}, [dropedFile])
useDynamicTextareaSize(textareaRef, form.values.message, 120)
const { onSubmit, selectedModel, chatMode } = useMessage()
const { mutateAsync: sendMessage, isPending: isSending } = useMutation({
mutationFn: onSubmit
@@ -33,6 +59,24 @@ export const SidepanelForm = () => {
return (
<div className="p-3 md:p-6 md:bg-white dark:bg-[#0a0a0a] border rounded-t-xl border-black/10 dark:border-gray-900/50">
<div className="flex-grow space-y-6 ">
{chatMode === "normal" && form.values.image && (
<div className="h-full rounded-md shadow relative">
<div>
<img
src={form.values.image}
alt="Uploaded"
className="h-full w-auto object-cover rounded-md min-w-[50px]"
/>
<button
onClick={() => {
form.setFieldValue("image", "")
}}
className="absolute top-2 right-2 bg-white dark:bg-black p-1 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800 text-black dark:text-gray-100">
<XMarkIcon className="h-5 w-5" />
</button>
</div>
</div>
)}
<div className="flex">
<form
onSubmit={form.onSubmit(async (value) => {
@@ -42,10 +86,34 @@ export const SidepanelForm = () => {
}
form.reset()
resetHeight()
await sendMessage(value.message)
await sendMessage({
image: value.image,
message: value.message.trim()
})
})}
className="shrink-0 flex-grow flex items-center ">
<div className="flex items-center p-2 rounded-2xl border bg-gray-100 w-full dark:bg-black dark:border-gray-800">
<button
type="button"
onClick={() => {
inputRef.current?.click()
}}
className={`flex ml-3 items-center justify-center dark:text-gray-100 ${
chatMode === "rag" ? "hidden" : "block"
}`}>
<PhotoIcon className="h-5 w-5" />
</button>
<input
id="file-upload"
name="file-upload"
type="file"
className="sr-only"
ref={inputRef}
accept="image/*"
multiple={false}
onChange={onInputChange}
/>
<textarea
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey && !isSending) {
@@ -60,12 +128,15 @@ export const SidepanelForm = () => {
}
form.reset()
resetHeight()
await sendMessage(value.message)
await sendMessage({
image: value.image,
message: value.message.trim()
})
})()
}
}}
ref={textareaRef}
className="rounded-full pl-4 pr-2 py-2 w-full resize-none bg-transparent focus-within:outline-none sm:text-sm focus:ring-0 focus-visible:ring-0 ring-0 dark:ring-0 border-0 dark:text-gray-100"
className="pl-4 pr-2 py-2 w-full resize-none bg-transparent focus-within:outline-none sm:text-sm focus:ring-0 focus-visible:ring-0 ring-0 dark:ring-0 border-0 dark:text-gray-100"
required
rows={1}
tabIndex={0}