Add hover effects for chat messages

This commit is contained in:
sabaimran
2024-07-09 14:56:57 +05:30
parent a0e9530fa4
commit 5b69252337
4 changed files with 72 additions and 52 deletions

View File

@@ -149,9 +149,8 @@ function ChatInputArea(props: ChatInputProps) {
<FileArrowUp weight='fill' /> <FileArrowUp weight='fill' />
</Button> </Button>
<div className="grid w-full gap-1.5"> <div className="grid w-full gap-1.5">
{/* <Label htmlFor="message">Your message</Label> */}
<Textarea <Textarea
className='border-none min-h-[60px]' className='border-none min-h-[20px]'
placeholder="Type / to see a list of commands" placeholder="Type / to see a list of commands"
id="message" id="message"
value={message} value={message}

View File

@@ -61,7 +61,8 @@ div.author {
div.chatFooter { div.chatFooter {
display: flex; display: flex;
justify-content: flex-end; justify-content: space-between;
min-height: 28px;
} }
div.chatButtons { div.chatButtons {
@@ -71,7 +72,8 @@ div.chatButtons {
border-radius: 16px; border-radius: 16px;
position: relative; position: relative;
bottom: -28px; bottom: -28px;
background-color: hsla(var(--background)); background-color: hsla(var(--secondary));
box-shadow: 0 4px 10px var(--box-shadow-color);
} }
div.chatFooter button { div.chatFooter button {
@@ -88,10 +90,6 @@ div.chatFooter button:hover {
background-color: hsla(var(--frosted-background-color)); background-color: hsla(var(--frosted-background-color));
} }
div.chatTimestamp {
font-size: small;
}
button.codeCopyButton { button.codeCopyButton {
cursor: pointer; cursor: pointer;
float: right; float: right;

View File

@@ -214,6 +214,7 @@ export function TrainOfThought(props: TrainOfThoughtProps) {
export default function ChatMessage(props: ChatMessageProps) { export default function ChatMessage(props: ChatMessageProps) {
const [copySuccess, setCopySuccess] = useState<boolean>(false); const [copySuccess, setCopySuccess] = useState<boolean>(false);
const [isHovering, setIsHovering] = useState<boolean>(false);
let message = props.chatMessage.message; let message = props.chatMessage.message;
@@ -260,12 +261,23 @@ export default function ChatMessage(props: ChatMessageProps) {
}, [markdownRendered]); }, [markdownRendered]);
function renderTimeStamp(timestamp: string) { function renderTimeStamp(timestamp: string) {
var dateObject = new Date(timestamp); const messageDateTime = new Date(timestamp);
var month = dateObject.getMonth() + 1; const currentDataTime = new Date();
var date = dateObject.getDate(); const timeDiff = currentDataTime.getTime() - messageDateTime.getTime();
var year = dateObject.getFullYear();
const formattedDate = `${month}/${date}/${year}`; if (timeDiff < 60000) {
return `${formattedDate} ${dateObject.toLocaleTimeString()}`; return "Just now";
}
if (timeDiff < 3600000) {
return `${Math.floor(timeDiff / 60000)}m ago`;
}
if (timeDiff < 86400000) {
return `${Math.floor(timeDiff / 3600000)}h ago`;
}
return `${Math.floor(timeDiff / 86400000)}d ago`;
} }
useEffect(() => { useEffect(() => {
@@ -304,6 +316,8 @@ export default function ChatMessage(props: ChatMessageProps) {
return ( return (
<div <div
className={constructClasses(props.chatMessage)} className={constructClasses(props.chatMessage)}
onMouseLeave={(event) => setIsHovering(false)}
onMouseEnter={(event) => setIsHovering(true)}
onClick={props.chatMessage.by === "khoj" ? (event) => undefined : undefined}> onClick={props.chatMessage.by === "khoj" ? (event) => undefined : undefined}>
<div className={chatMessageWrapperClasses(props.chatMessage)}> <div className={chatMessageWrapperClasses(props.chatMessage)}>
<div ref={messageRef} className={styles.chatMessage} dangerouslySetInnerHTML={{ __html: markdownRendered }} /> <div ref={messageRef} className={styles.chatMessage} dangerouslySetInnerHTML={{ __html: markdownRendered }} />
@@ -315,40 +329,49 @@ export default function ChatMessage(props: ChatMessageProps) {
onlineReferenceCardData={allReferences.onlineReferenceCardData} /> onlineReferenceCardData={allReferences.onlineReferenceCardData} />
</div> </div>
<div className={styles.chatFooter}> <div className={styles.chatFooter}>
{/* <div className={styles.chatTimestamp}> {
{renderTimeStamp(props.chatMessage.created)} isHovering &&
</div> */} (
<div className={styles.chatButtons}> <>
{ <div className={`text-gray-400 relative top-2 left-2`}>
<div className={styles.referenceButton}> {renderTimeStamp(props.chatMessage.created)}
<button onClick={(event) => console.log("speaker")}> </div>
<SpeakerHifi color='hsl(var(--muted-foreground))' /> <div className={styles.chatButtons}>
</button> {
</div> (props.chatMessage.by === "khoj") &&
} (
<button className={`${styles.copyButton}`} onClick={() => { <button onClick={(event) => console.log("speaker")}>
navigator.clipboard.writeText(props.chatMessage.message); <SpeakerHifi color='hsl(var(--muted-foreground))' />
setCopySuccess(true); </button>
}}> )
{ }
copySuccess ? <button className={`${styles.copyButton}`} onClick={() => {
<Copy color='green' /> navigator.clipboard.writeText(props.chatMessage.message);
: <Copy color='hsl(var(--muted-foreground))' /> setCopySuccess(true);
} }}>
</button> {
{ copySuccess ?
props.chatMessage.by === "khoj" && <Copy color='green' />
( : <Copy color='hsl(var(--muted-foreground))' />
props.chatMessage.intent ? }
<FeedbackButtons </button>
uquery={props.chatMessage.intent.query} {
kquery={props.chatMessage.message} /> (props.chatMessage.by === "khoj") &&
: <FeedbackButtons (
uquery={props.chatMessage.rawQuery || props.chatMessage.message} props.chatMessage.intent ?
kquery={props.chatMessage.message} /> <FeedbackButtons
) uquery={props.chatMessage.intent.query}
} kquery={props.chatMessage.message} />
</div> : <FeedbackButtons
uquery={props.chatMessage.rawQuery || props.chatMessage.message}
kquery={props.chatMessage.message} />
)
}
</div>
</>
)
}
</div> </div>
</div> </div>
) )

View File

@@ -59,7 +59,7 @@ function NotesContextReferenceCard(props: NotesContextReferenceCardProps) {
onMouseEnter={() => setIsHovering(true)} onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)} onMouseLeave={() => setIsHovering(false)}
className={`${props.showFullContent ? 'w-auto' : 'w-[200px]'} overflow-hidden break-words text-balance rounded-lg p-2 bg-muted border-none`} className={`${props.showFullContent ? 'w-auto' : 'w-[200px]'} overflow-hidden break-words text-balance rounded-lg p-2 bg-muted border-none`}
> >
<h3 className={`${props.showFullContent ? 'block' : 'line-clamp-1'} text-muted-foreground}`}> <h3 className={`${props.showFullContent ? 'block' : 'line-clamp-1'} text-muted-foreground}`}>
<File className='w-6 h-6 text-muted-foreground inline-flex' /> <File className='w-6 h-6 text-muted-foreground inline-flex' />
{props.title} {props.title}
@@ -320,9 +320,9 @@ export default function ReferencePanel(props: ReferencePanelDataProps) {
return ( return (
<Sheet> <Sheet>
<SheetTrigger className='text-balance w-[200px] overflow-hidden break-words p-0 bg-transparent border-none text-gray-400 align-middle justify-center items-center !m-0 inline-flex' <SheetTrigger
onClick={() => { console.log("showing references") }}> className='text-balance w-[200px] overflow-hidden break-words p-0 bg-transparent border-none text-gray-400 align-middle justify-center items-center !m-0 inline-flex'>
View references <ArrowRight className='m-1' /> View references <ArrowRight className='m-1' />
</SheetTrigger> </SheetTrigger>
<SheetContent className="overflow-y-scroll"> <SheetContent className="overflow-y-scroll">
<SheetHeader> <SheetHeader>