mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-09 13:25:11 +00:00
Update dark mode, fix chat message time stamp, fix rendering for new message
This commit is contained in:
@@ -217,7 +217,7 @@ function ChatInputArea(props: ChatInputProps) {
|
|||||||
<PopoverContent
|
<PopoverContent
|
||||||
onOpenAutoFocus={(e) => e.preventDefault()}
|
onOpenAutoFocus={(e) => e.preventDefault()}
|
||||||
className={`${props.isMobileWidth} ? 'w-[100vw] : w-full`}>
|
className={`${props.isMobileWidth} ? 'w-[100vw] : w-full`}>
|
||||||
<Command className='max-w-full'>
|
<Command className='max-w-full shadow-md'>
|
||||||
<CommandInput placeholder="Type a command or search..." value={message} className='hidden' />
|
<CommandInput placeholder="Type a command or search..." value={message} className='hidden' />
|
||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty>No matching commands.</CommandEmpty>
|
<CommandEmpty>No matching commands.</CommandEmpty>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import React, { useEffect, useRef, useState } from 'react';
|
|||||||
import 'katex/dist/katex.min.css';
|
import 'katex/dist/katex.min.css';
|
||||||
import 'highlight.js/styles/github.css'
|
import 'highlight.js/styles/github.css'
|
||||||
|
|
||||||
import { ReferencePanelData, TeaserReferencesSection, constructAllReferences } from '../referencePanel/referencePanel';
|
import { TeaserReferencesSection, constructAllReferences } from '../referencePanel/referencePanel';
|
||||||
|
|
||||||
import { ThumbsUp, ThumbsDown, Copy, Brain, Cloud, Folder, Book, Aperture, ArrowRight, SpeakerHifi } from '@phosphor-icons/react';
|
import { ThumbsUp, ThumbsDown, Copy, Brain, Cloud, Folder, Book, Aperture, ArrowRight, SpeakerHifi } from '@phosphor-icons/react';
|
||||||
import { MagnifyingGlass } from '@phosphor-icons/react/dist/ssr';
|
import { MagnifyingGlass } from '@phosphor-icons/react/dist/ssr';
|
||||||
@@ -140,17 +140,6 @@ function FeedbackButtons({ uquery, kquery }: { uquery: string, kquery: string })
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHAT TO DO WHEN CLICK ON KHOJ MESSAGE
|
|
||||||
function onClickMessage(
|
|
||||||
event: React.MouseEvent<any>,
|
|
||||||
referencePanelData: ReferencePanelData,
|
|
||||||
setReferencePanelData: Function,
|
|
||||||
setShowReferencePanel: Function) {
|
|
||||||
|
|
||||||
setReferencePanelData(referencePanelData);
|
|
||||||
setShowReferencePanel(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChatMessageProps {
|
interface ChatMessageProps {
|
||||||
chatMessage: SingleChatMessage;
|
chatMessage: SingleChatMessage;
|
||||||
isMobileWidth: boolean;
|
isMobileWidth: boolean;
|
||||||
@@ -215,25 +204,36 @@ 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);
|
const [isHovering, setIsHovering] = useState<boolean>(false);
|
||||||
|
const [markdownRendered, setMarkdownRendered] = useState<string>('');
|
||||||
let message = props.chatMessage.message;
|
|
||||||
|
|
||||||
// Replace LaTeX delimiters with placeholders
|
|
||||||
message = message.replace(/\\\(/g, 'LEFTPAREN').replace(/\\\)/g, 'RIGHTPAREN')
|
|
||||||
.replace(/\\\[/g, 'LEFTBRACKET').replace(/\\\]/g, 'RIGHTBRACKET');
|
|
||||||
|
|
||||||
if (props.chatMessage.intent && props.chatMessage.intent.type == "text-to-image2") {
|
|
||||||
message = `\n\n${props.chatMessage.intent["inferred-queries"][0]}`
|
|
||||||
}
|
|
||||||
|
|
||||||
let markdownRendered = md.render(message);
|
|
||||||
|
|
||||||
// Replace placeholders with LaTeX delimiters
|
|
||||||
markdownRendered = markdownRendered.replace(/LEFTPAREN/g, '\\(').replace(/RIGHTPAREN/g, '\\)')
|
|
||||||
.replace(/LEFTBRACKET/g, '\\[').replace(/RIGHTBRACKET/g, '\\]');
|
|
||||||
|
|
||||||
const messageRef = useRef<HTMLDivElement>(null);
|
const messageRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let message = props.chatMessage.message;
|
||||||
|
|
||||||
|
// Replace LaTeX delimiters with placeholders
|
||||||
|
message = message.replace(/\\\(/g, 'LEFTPAREN').replace(/\\\)/g, 'RIGHTPAREN')
|
||||||
|
.replace(/\\\[/g, 'LEFTBRACKET').replace(/\\\]/g, 'RIGHTBRACKET');
|
||||||
|
|
||||||
|
if (props.chatMessage.intent && props.chatMessage.intent.type == "text-to-image2") {
|
||||||
|
message = `\n\n${props.chatMessage.intent["inferred-queries"][0]}`
|
||||||
|
}
|
||||||
|
|
||||||
|
let markdownRendered = md.render(message);
|
||||||
|
|
||||||
|
// Replace placeholders with LaTeX delimiters
|
||||||
|
markdownRendered = markdownRendered.replace(/LEFTPAREN/g, '\\(').replace(/RIGHTPAREN/g, '\\)')
|
||||||
|
.replace(/LEFTBRACKET/g, '\\[').replace(/RIGHTBRACKET/g, '\\]');
|
||||||
|
setMarkdownRendered(markdownRendered);
|
||||||
|
}, [props.chatMessage.message]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (copySuccess) {
|
||||||
|
setTimeout(() => {
|
||||||
|
setCopySuccess(false);
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}, [copySuccess]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (messageRef.current) {
|
if (messageRef.current) {
|
||||||
const preElements = messageRef.current.querySelectorAll('pre > .hljs');
|
const preElements = messageRef.current.querySelectorAll('pre > .hljs');
|
||||||
@@ -260,8 +260,12 @@ export default function ChatMessage(props: ChatMessageProps) {
|
|||||||
}
|
}
|
||||||
}, [markdownRendered]);
|
}, [markdownRendered]);
|
||||||
|
|
||||||
|
if (!props.chatMessage.message) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function renderTimeStamp(timestamp: string) {
|
function renderTimeStamp(timestamp: string) {
|
||||||
const messageDateTime = new Date(timestamp);
|
const messageDateTime = new Date(timestamp + 'Z');
|
||||||
const currentDataTime = new Date();
|
const currentDataTime = new Date();
|
||||||
const timeDiff = currentDataTime.getTime() - messageDateTime.getTime();
|
const timeDiff = currentDataTime.getTime() - messageDateTime.getTime();
|
||||||
|
|
||||||
@@ -270,24 +274,17 @@ export default function ChatMessage(props: ChatMessageProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (timeDiff < 3600000) {
|
if (timeDiff < 3600000) {
|
||||||
return `${Math.floor(timeDiff / 60000)}m ago`;
|
// Using Math.round for closer to actual time representation
|
||||||
|
return `${Math.round(timeDiff / 60000)}m ago`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeDiff < 86400000) {
|
if (timeDiff < 86400000) {
|
||||||
return `${Math.floor(timeDiff / 3600000)}h ago`;
|
return `${Math.round(timeDiff / 3600000)}h ago`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${Math.floor(timeDiff / 86400000)}d ago`;
|
return `${Math.round(timeDiff / 86400000)}d ago`;
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (copySuccess) {
|
|
||||||
setTimeout(() => {
|
|
||||||
setCopySuccess(false);
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
}, [copySuccess]);
|
|
||||||
|
|
||||||
function constructClasses(chatMessage: SingleChatMessage) {
|
function constructClasses(chatMessage: SingleChatMessage) {
|
||||||
let classes = [styles.chatMessageContainer];
|
let classes = [styles.chatMessageContainer];
|
||||||
classes.push(styles[chatMessage.by]);
|
classes.push(styles[chatMessage.by]);
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ function GenericOnlineReferenceCard(props: OnlineReferenceCardProps) {
|
|||||||
const [isHovering, setIsHovering] = useState(false);
|
const [isHovering, setIsHovering] = useState(false);
|
||||||
|
|
||||||
if (!props.link) {
|
if (!props.link) {
|
||||||
console.log("invalid link", props);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import {
|
|||||||
|
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
|
||||||
import { ArrowRight, ArrowLeft, ArrowDown, Spinner, Check, FolderPlus } from "@phosphor-icons/react";
|
import { ArrowRight, ArrowLeft, ArrowDown, Spinner, Check, FolderPlus, DotsThreeVertical } from "@phosphor-icons/react";
|
||||||
|
|
||||||
interface ChatHistory {
|
interface ChatHistory {
|
||||||
conversation_id: string;
|
conversation_id: string;
|
||||||
@@ -496,7 +496,7 @@ function ChatSessionActionMenu(props: ChatSessionActionMenuProps) {
|
|||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
onOpenChange={(open) => setIsOpen(open)}
|
onOpenChange={(open) => setIsOpen(open)}
|
||||||
open={isOpen}>
|
open={isOpen}>
|
||||||
<DropdownMenuTrigger>:</DropdownMenuTrigger>
|
<DropdownMenuTrigger><DotsThreeVertical className="h-4 w-4"/></DropdownMenuTrigger>
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<Button className="p-0 text-sm h-auto" variant={'ghost'} onClick={() => setIsRenaming(true)}>
|
<Button className="p-0 text-sm h-auto" variant={'ghost'} onClick={() => setIsRenaming(true)}>
|
||||||
|
|||||||
@@ -38,24 +38,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: 224 71.4% 4.1%;
|
--background: 0 0% 14%;
|
||||||
--foreground: 210 20% 98%;
|
--foreground: 210 20% 98%;
|
||||||
--card: 224 71.4% 4.1%;
|
--card: 0 0% 14%;
|
||||||
--card-foreground: 210 20% 98%;
|
--card-foreground: 210 20% 98%;
|
||||||
--popover: 224 71.4% 4.1%;
|
--popover: 0 0% 14%;
|
||||||
--popover-foreground: 210 20% 98%;
|
--popover-foreground: 210 20% 98%;
|
||||||
--primary: 263.4 70% 50.4%;
|
--primary: 263.4 70% 50.4%;
|
||||||
--primary-foreground: 210 20% 98%;
|
--primary-foreground: 210 20% 98%;
|
||||||
--secondary: 215 27.9% 16.9%;
|
--secondary: 0 0% 9%;
|
||||||
--secondary-foreground: 210 20% 98%;
|
--secondary-foreground: 210 20% 98%;
|
||||||
--muted: 215 27.9% 16.9%;
|
--muted: 0 0% 9%;
|
||||||
--muted-foreground: 217.9 10.6% 64.9%;
|
--muted-foreground: 217.9 10.6% 64.9%;
|
||||||
--accent: 215 27.9% 16.9%;
|
--accent: 0 0% 9%;
|
||||||
--accent-foreground: 210 20% 98%;
|
--accent-foreground: 210 20% 98%;
|
||||||
--destructive: 0 62.8% 30.6%;
|
--destructive: 0 62.8% 30.6%;
|
||||||
--destructive-foreground: 210 20% 98%;
|
--destructive-foreground: 210 20% 98%;
|
||||||
--border: 215 27.9% 16.9%;
|
--border: 0 0% 9%;
|
||||||
--input: 215 27.9% 16.9%;
|
--input: 0 0% 9%;
|
||||||
--ring: 263.4 70% 50.4%;
|
--ring: 263.4 70% 50.4%;
|
||||||
--font-family: "Noto Sans", "Noto Sans Arabic", sans-serif !important;
|
--font-family: "Noto Sans", "Noto Sans Arabic", sans-serif !important;
|
||||||
--box-shadow-color: rgba(255, 255, 255, 0.05);
|
--box-shadow-color: rgba(255, 255, 255, 0.05);
|
||||||
|
|||||||
Reference in New Issue
Block a user