diff --git a/src/interface/web/app/chat/chat.module.css b/src/interface/web/app/chat/chat.module.css index 6df3483f..3d3c4665 100644 --- a/src/interface/web/app/chat/chat.module.css +++ b/src/interface/web/app/chat/chat.module.css @@ -15,7 +15,7 @@ div.inputBox { grid-template-columns: auto 1fr auto auto; border: 1px solid var(--border-color); border-radius: 16px; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.03); + box-shadow: 0 4px 10px var(--box-shadow-color); margin-bottom: 20px; gap: 12px; padding-left: 20px; diff --git a/src/interface/web/app/components/chatHistory/chatHistory.module.css b/src/interface/web/app/components/chatHistory/chatHistory.module.css index 67be0e47..984fb922 100644 --- a/src/interface/web/app/components/chatHistory/chatHistory.module.css +++ b/src/interface/web/app/components/chatHistory/chatHistory.module.css @@ -26,5 +26,5 @@ div.trainOfThought { border-radius: 16px; padding: 16px; margin: 12px; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.03); + box-shadow: 0 4px 10px var(--box-shadow-color); } diff --git a/src/interface/web/app/components/chatHistory/chatHistory.tsx b/src/interface/web/app/components/chatHistory/chatHistory.tsx index be9361f0..ce844c7e 100644 --- a/src/interface/web/app/components/chatHistory/chatHistory.tsx +++ b/src/interface/web/app/components/chatHistory/chatHistory.tsx @@ -101,13 +101,17 @@ export default function ChatHistory(props: ChatHistoryProps) { } return () => observer.disconnect(); - }, [sentinelRef.current, hasMoreMessages, currentPage, props.conversationId, fetchingData]); + }, [sentinelRef.current, hasMoreMessages, currentPage, fetchingData]); + + useEffect(() => { + setHasMoreMessages(true); + setFetchingData(false); + setCurrentPage(0); + setData(null); + }, [props.conversationId]); const fetchMoreMessages = (currentPage: number) => { if (!hasMoreMessages || fetchingData) return; - - console.log("fetchMoreMessages", currentPage); - const nextPage = currentPage + 1; fetch(`/api/chat/history?client=web&conversation_id=${props.conversationId}&n=${10 * nextPage}`) .then(response => response.json()) @@ -117,6 +121,7 @@ export default function ChatHistory(props: ChatHistoryProps) { if (chatData.response.chat.length === data?.chat.length) { setHasMoreMessages(false); + setFetchingData(false); return; } @@ -124,12 +129,10 @@ export default function ChatHistory(props: ChatHistoryProps) { setLoading(false); if (currentPage < 2) { - console.log("call scroll to bottom"); scrollToBottom(); } setFetchingData(false); } else { - console.log("No more messages"); setHasMoreMessages(false); } }) @@ -146,8 +149,6 @@ export default function ChatHistory(props: ChatHistoryProps) { } } - console.log("isUserAtBottom", isUserAtBottom()); - if (isUserAtBottom()) { scrollToBottom(); } @@ -222,7 +223,9 @@ export default function ChatHistory(props: ChatHistoryProps) {
-
+
+ {fetchingData && } +
{(data && data.chat) && data.chat.map((chatMessage, index) => ( }
- + - {constructAgentName()} + {constructAgentName()}
diff --git a/src/interface/web/app/components/chatMessage/chatMessage.module.css b/src/interface/web/app/components/chatMessage/chatMessage.module.css index 2a16cc73..f0d80130 100644 --- a/src/interface/web/app/components/chatMessage/chatMessage.module.css +++ b/src/interface/web/app/components/chatMessage/chatMessage.module.css @@ -4,7 +4,7 @@ div.chatMessageContainer { margin: 12px; border-radius: 16px; padding: 16px; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.03); + box-shadow: 0 4px 10px var(--box-shadow-color) } div.chatMessageWrapper { @@ -12,7 +12,6 @@ div.chatMessageWrapper { } div.khojfullHistory { - border-color: var(--border-color); border-width: 1px; padding-left: 4px; } @@ -26,14 +25,14 @@ div.chatMessageContainer.youfullHistory { } div.you { - background-color: var(--frosted-background-color); + background-color: hsla(var(--secondary)); align-self: flex-end; border-radius: 16px; } div.khoj { background-color: transparent; - color: #000000; + color: hsl(var(--accent-foreground)); align-self: flex-start; } @@ -50,8 +49,8 @@ div.chatMessageContainer h3 img { width: 24px; } -div.you .author { - color: var(--frosted-background-color); +div.you { + color: hsla(var(--secondary-foreground)); } div.author { @@ -87,7 +86,7 @@ div.chatFooter button { } div.chatFooter button:hover { - background-color: var(--frosted-background-color); + background-color: hsla(var(--frosted-background-color)); } div.chatTimestamp { @@ -101,7 +100,7 @@ button.codeCopyButton { } button.codeCopyButton:hover { - color: var(--frosted-background-color); + color: hsla(var(--frosted-background-color)); } div.feedbackButtons img, diff --git a/src/interface/web/app/components/chatMessage/chatMessage.tsx b/src/interface/web/app/components/chatMessage/chatMessage.tsx index 68c5b126..e4c7ca56 100644 --- a/src/interface/web/app/components/chatMessage/chatMessage.tsx +++ b/src/interface/web/app/components/chatMessage/chatMessage.tsx @@ -12,7 +12,9 @@ import 'highlight.js/styles/github.css' import { hasValidReferences } from '../referencePanel/referencePanel'; -import { ThumbsUp, ThumbsDown, Copy, Brain, Cloud, Folder, Book } from '@phosphor-icons/react'; +import { ThumbsUp, ThumbsDown, Copy, Brain, Cloud, Folder, Book, Aperture } from '@phosphor-icons/react'; +import { MagnifyingGlass } from '@phosphor-icons/react/dist/ssr'; +import { compare } from 'swr/_internal'; const md = new markdownIt({ html: true, @@ -170,6 +172,14 @@ function chooseIconFromHeader(header: string, iconColor: string) { return ; } + if (compareHeader.includes("search")) { + return ; + } + + if (compareHeader.includes("summary") || compareHeader.includes("summarize")) { + return ; + } + return ; } diff --git a/src/interface/web/app/components/loading/loading.tsx b/src/interface/web/app/components/loading/loading.tsx index b2a0198b..a45377a5 100644 --- a/src/interface/web/app/components/loading/loading.tsx +++ b/src/interface/web/app/components/loading/loading.tsx @@ -14,8 +14,8 @@ interface InlineLoadingProps { export function InlineLoading(props: InlineLoadingProps) { return ( - ) } diff --git a/src/interface/web/app/components/navMenu/navMenu.tsx b/src/interface/web/app/components/navMenu/navMenu.tsx index 3e3e11f2..792405b8 100644 --- a/src/interface/web/app/components/navMenu/navMenu.tsx +++ b/src/interface/web/app/components/navMenu/navMenu.tsx @@ -22,6 +22,8 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { Toggle } from '@/components/ui/toggle'; +import { Moon } from '@phosphor-icons/react'; interface NavMenuProps { @@ -36,6 +38,7 @@ export default function NavMenu(props: NavMenuProps) { const [displayTitle, setDisplayTitle] = useState(props.title || props.selected.toUpperCase()); const [isMobileWidth, setIsMobileWidth] = useState(false); + const [darkMode, setDarkMode] = useState(false); useEffect(() => { setIsMobileWidth(window.innerWidth < 768); @@ -43,6 +46,31 @@ export default function NavMenu(props: NavMenuProps) { }, [props.title]); + useEffect(() => { + window.addEventListener('resize', () => { + setIsMobileWidth(window.innerWidth < 768); + }); + + if (localStorage.getItem('theme') === 'dark') { + document.documentElement.classList.add('dark'); + setDarkMode(true); + } + + }, []); + + useEffect(() => { + toggleDarkMode(darkMode); + }, [darkMode]); + + function toggleDarkMode(darkMode: boolean) { + if (darkMode) { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } + localStorage.setItem('theme', darkMode ? 'dark' : 'light'); + } + return (
@@ -94,30 +122,42 @@ export default function NavMenu(props: NavMenuProps) { Automations - {userData && - - Profile - - - - Settings - - - - - - Help - - - - - - Logout - - - - - } + + Profile + + + { + console.log("clicked on dark mode method"); + setDarkMode(!darkMode)} + }> + + + + {userData && + <> + + + Settings + + + + + + Help + + + + + + Logout + + + + } + + }
diff --git a/src/interface/web/app/components/referencePanel/referencePanel.module.css b/src/interface/web/app/components/referencePanel/referencePanel.module.css index a6179e46..83ca4ab8 100644 --- a/src/interface/web/app/components/referencePanel/referencePanel.module.css +++ b/src/interface/web/app/components/referencePanel/referencePanel.module.css @@ -25,7 +25,7 @@ div.contextReference:hover { div.singleReference { padding: 8px; border-radius: 8px; - background-color: var(--frosted-background-color); + background-color: hsla(var(--frosted-background-color)); margin-top: 8px; } diff --git a/src/interface/web/app/components/sidePanel/sidePanel.module.css b/src/interface/web/app/components/sidePanel/sidePanel.module.css index 03b4cd1b..81d04ad5 100644 --- a/src/interface/web/app/components/sidePanel/sidePanel.module.css +++ b/src/interface/web/app/components/sidePanel/sidePanel.module.css @@ -14,11 +14,12 @@ div.compressed { } div.sessionHover { - background-color: var(--secondary-accent); + background-color: hsla(var(--popover)); } div.session:hover { - background-color: var(--secondary-accent); + background-color: hsla(var(--popover)); + color: hsla(var(--popover-foreground)); } div.session a { @@ -43,8 +44,7 @@ div.panel { display: grid; grid-auto-flow: row; padding: 1rem; - background-color: hsla(var(--primary-foreground)); - background-color: var(--secondary-background-color); + background-color: hsla(var(--muted)); height: 100%; overflow-y: auto; max-width: auto; @@ -94,7 +94,7 @@ div.modalSessionsList { left: 0; width: 100%; height: 100%; - background-color: var(--frosted-background-color); + background-color: hsla(var(--frosted-background-color)); z-index: 1; display: flex; justify-content: center; @@ -105,7 +105,7 @@ div.modalSessionsList { div.modalSessionsList div.content { max-width: 80%; max-height: 80%; - background-color: var(--frosted-background-color); + background-color: hsla(var(--frosted-background-color)); overflow: auto; padding: 20px; border-radius: 10px; diff --git a/src/interface/web/app/globals.css b/src/interface/web/app/globals.css index dfebb72a..bc833077 100644 --- a/src/interface/web/app/globals.css +++ b/src/interface/web/app/globals.css @@ -29,11 +29,12 @@ /* Khoj Custom Colors */ --primary-hover: #fee285; - --frosted-background-color: #F5F3F2; + --frosted-background-color: 20 13% 95%; --secondary-background-color: #F7F7F5; --secondary-accent: #EDEDED; --khoj-orange: #FFE7D1; --border-color: #e2e2e2; + --box-shadow-color: rgba(0, 0, 0, 0.03); } .dark { @@ -57,6 +58,7 @@ --input: 215 27.9% 16.9%; --ring: 263.4 70% 50.4%; --font-family: "Noto Sans", "Noto Sans Arabic", sans-serif !important; + --box-shadow-color: rgba(255, 255, 255, 0.05); } } diff --git a/src/interface/web/components/ui/toggle.tsx b/src/interface/web/components/ui/toggle.tsx new file mode 100644 index 00000000..b6f2e7d3 --- /dev/null +++ b/src/interface/web/components/ui/toggle.tsx @@ -0,0 +1,45 @@ +"use client" + +import * as React from "react" +import * as TogglePrimitive from "@radix-ui/react-toggle" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const toggleVariants = cva( + "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground", + { + variants: { + variant: { + default: "bg-transparent", + outline: + "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground", + }, + size: { + default: "h-10 px-3", + sm: "h-9 px-2.5", + lg: "h-11 px-5", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +const Toggle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, size, ...props }, ref) => ( + +)) + +Toggle.displayName = TogglePrimitive.Root.displayName + +export { Toggle, toggleVariants } diff --git a/src/interface/web/package.json b/src/interface/web/package.json index 6ca1c013..b38dfa37 100644 --- a/src/interface/web/package.json +++ b/src/interface/web/package.json @@ -29,6 +29,7 @@ "@radix-ui/react-popover": "^1.1.1", "@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-toggle": "^1.1.0", "@types/katex": "^0.16.7", "@types/markdown-it": "^14.1.1", "autoprefixer": "^10.4.19", diff --git a/src/interface/web/yarn.lock b/src/interface/web/yarn.lock index e56434ad..baf44ac8 100644 --- a/src/interface/web/yarn.lock +++ b/src/interface/web/yarn.lock @@ -803,6 +803,15 @@ dependencies: "@radix-ui/react-compose-refs" "1.1.0" +"@radix-ui/react-toggle@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.1.0.tgz#1f7697b82917019330a16c6f96f649f46b4606cf" + integrity sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + "@radix-ui/react-use-callback-ref@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1" diff --git a/src/khoj/routers/api.py b/src/khoj/routers/api.py index cbe19891..ef5394ac 100644 --- a/src/khoj/routers/api.py +++ b/src/khoj/routers/api.py @@ -372,7 +372,7 @@ async def extract_references_and_questions( logger.info(f"🔍 Searching knowledge base with queries: {inferred_queries}") if send_status_func: inferred_queries_str = "\n- " + "\n- ".join(inferred_queries) - await send_status_func(f"**🔍 Searching Documents for:** {inferred_queries_str}") + await send_status_func(f"**Searching Documents for:** {inferred_queries_str}") for query in inferred_queries: n_items = min(n, 3) if using_offline_chat else n search_results.extend(