@ -5,12 +5,16 @@ import {
HoverCard ,
JsonInput ,
List ,
ScrollArea ,
Stack ,
Tabs ,
Text ,
Textarea ,
TextInput ,
Transition ,
useMantineTheme ,
} from "@mantine/core" ;
import { useEffect, useState } from "react" ;
import { memo, useEffect, useState } from "react" ;
import {
defaultParameters ,
defaultSystemPrompt ,
@ -23,6 +27,7 @@ import type {
CommittedMessage ,
DraftMessage ,
OtherParameters ,
SendMessageStatus ,
} from "../../../types" ;
import Markdown from "react-markdown" ;
import {
@ -351,6 +356,8 @@ export default function ChatPage() {
const setSendMessageStatus = useStore ( ( state ) = > state . setSendMessageStatus ) ;
const setIsSendingMessage = useStore ( ( state ) = > state . setIsSendingMessage ) ;
const theme = useMantineTheme ( ) ;
// Function to send message using subscription
const sendSubscriptionMessage = async ( {
conversationId ,
@ -489,11 +496,11 @@ export default function ChatPage() {
}
return (
< >
< div >
< span> Conversation # { conversationId } - < / span >
< input
type = "text"
< Box >
< Group justify = "flex-start" gap = { "sm" } >
< TextInput
inputSize = "50"
description = { ` Conversation # ${ conversationId } ` }
defaultValue = { conversationTitle || "" }
// onChange={(e) => {
// setConversationTitle(e.target.value);
@ -504,10 +511,27 @@ export default function ChatPage() {
title : e.target.value ,
} ) ;
} }
variant = "unstyled"
styles = { {
input : {
// backgroundColor: "transparent",
// border: "none",
// padding: 0,
// margin: 0,
fontFamily : theme.headings.fontFamily ,
fontSize : theme.fontSizes.lg ,
lineHeight : theme.lineHeights [ "4xl" ] ,
} ,
wrapper : {
marginTop : 0 ,
} ,
} }
/ >
{ isSendingMessage && < IconLoaderQuarter size = { 16 } stroke = { 1.5 } / > }
{ sendMessageStatus && < span > { sendMessageStatus . message } < / span > }
< / div >
{ sendMessageStatus && (
< StatusMessage sendMessageStatus = { sendMessageStatus } / >
) }
< / Group >
< Tabs defaultValue = "message" >
< Tabs.List >
< Tabs.Tab value = "message" > Message < / Tabs.Tab >
@ -690,7 +714,7 @@ export default function ChatPage() {
< / List >
< / Tabs.Panel >
< / Tabs >
< / >
< / Box >
) ;
}
@ -792,15 +816,16 @@ function Messages() {
position = { message . role === "user" ? "left" : "right" }
>
< HoverCard.Target >
< Box
< ScrollArea
scrollbars = "x"
w = "75%"
p = "md"
bdrs = "md"
bg = {
message . role === "user"
? theme . colors . gray [ 2 ]
: theme . colors . blue [ 2 ]
}
p = "md"
bdrs = "md"
>
< Markdown >
{ message . parts
@ -808,7 +833,7 @@ function Messages() {
. map ( ( p ) = > p . text )
. join ( "\n" ) }
< / Markdown >
< / Box >
< / ScrollArea >
< / HoverCard.Target >
< HoverCard.Dropdown >
< ActionIcon.Group >
@ -840,3 +865,44 @@ function Messages() {
< / Stack >
) ;
}
const StatusMessage = memo (
( { sendMessageStatus } : { sendMessageStatus : SendMessageStatus | null } ) = > {
const [ displayMessage , setDisplayMessage ] = useState ( sendMessageStatus ) ;
const [ isVisible , setIsVisible ] = useState ( sendMessageStatus !== null ) ;
useEffect ( ( ) = > {
if ( sendMessageStatus === null ) {
setIsVisible ( false ) ;
setTimeout ( ( ) = > setDisplayMessage ( null ) , 250 ) ;
} else if ( displayMessage === null ) {
setDisplayMessage ( sendMessageStatus ) ;
setIsVisible ( true ) ;
} else if ( displayMessage . message !== sendMessageStatus . message ) {
setIsVisible ( false ) ;
setTimeout ( ( ) = > {
setDisplayMessage ( sendMessageStatus ) ;
setIsVisible ( true ) ;
} , 250 ) ;
}
} , [ sendMessageStatus , displayMessage ] ) ;
return (
< div style = { { position : "relative" } } >
{ /* This is a hack to make this component take up the space it would take up once the transition is complete. Useful for when this component is in a flexbox with a particular alignment/justification, which we want to be calculated against its eventual size. */ }
< span style = { { visibility : "hidden" } } > { displayMessage ? . message } < / span >
< Transition
transition = "pop"
duration = { 500 }
mounted = { isVisible && displayMessage !== null }
>
{ ( styles ) = > (
< span style = { { . . . styles , position : "absolute" , top : 0 , left : 0 } } >
{ displayMessage ? . message }
< / span >
) }
< / Transition >
< / div >
) ;
}
) ;