From 79cfd0a7229d00b6cc8ae269301d3fde059b74df Mon Sep 17 00:00:00 2001 From: WanQuanXie Date: Fri, 24 May 2024 17:32:14 +0800 Subject: [PATCH 01/34] chore(ui): add next-themes --- ui/package.json | 1 + ui/yarn.lock | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/ui/package.json b/ui/package.json index ff61082..90a71f4 100644 --- a/ui/package.json +++ b/ui/package.json @@ -20,6 +20,7 @@ "lucide-react": "^0.363.0", "markdown-to-jsx": "^7.4.5", "next": "14.1.4", + "next-themes": "^0.3.0", "react": "^18", "react-dom": "^18", "react-text-to-speech": "^0.14.5", diff --git a/ui/yarn.lock b/ui/yarn.lock index ec8b3d7..d348a8c 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2244,6 +2244,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +next-themes@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.3.0.tgz#b4d2a866137a67d42564b07f3a3e720e2ff3871a" + integrity sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w== + next@14.1.4: version "14.1.4" resolved "https://registry.yarnpkg.com/next/-/next-14.1.4.tgz#203310f7310578563fd5c961f0db4729ce7a502d" @@ -2854,8 +2859,16 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: - name string-width-cjs +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -2919,7 +2932,14 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From f9664d48e7f9d8f5f473938d5074b56bba3ff034 Mon Sep 17 00:00:00 2001 From: WanQuanXie Date: Fri, 24 May 2024 18:20:15 +0800 Subject: [PATCH 02/34] feat: setup theme context config --- ui/app/layout.tsx | 25 +++++++------ ui/components/theme/Provider.tsx | 14 +++++++ ui/components/theme/Switcher.tsx | 63 ++++++++++++++++++++++++++++++++ ui/tailwind.config.ts | 1 + 4 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 ui/components/theme/Provider.tsx create mode 100644 ui/components/theme/Switcher.tsx diff --git a/ui/app/layout.tsx b/ui/app/layout.tsx index b3f5005..87144cf 100644 --- a/ui/app/layout.tsx +++ b/ui/app/layout.tsx @@ -4,6 +4,7 @@ import './globals.css'; import { cn } from '@/lib/utils'; import Sidebar from '@/components/Sidebar'; import { Toaster } from 'sonner'; +import { ThemeProviderComponent } from '@/components/theme/Provider'; const montserrat = Montserrat({ weight: ['300', '400', '500', '700'], @@ -24,18 +25,20 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + - {children} - + + {children} + + ); diff --git a/ui/components/theme/Provider.tsx b/ui/components/theme/Provider.tsx new file mode 100644 index 0000000..2e110f6 --- /dev/null +++ b/ui/components/theme/Provider.tsx @@ -0,0 +1,14 @@ +'use client'; +import { ThemeProvider } from 'next-themes'; + +export function ThemeProviderComponent({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/ui/components/theme/Switcher.tsx b/ui/components/theme/Switcher.tsx new file mode 100644 index 0000000..d1f44a3 --- /dev/null +++ b/ui/components/theme/Switcher.tsx @@ -0,0 +1,63 @@ +'use client'; +import { useTheme } from 'next-themes'; +import { SunIcon, MoonIcon, MonitorIcon } from 'lucide-react'; +import { useCallback, useEffect, useState } from 'react'; + +type Theme = 'dark' | 'light' | 'system'; + +export function ThemeSwitcher() { + const [mounted, setMounted] = useState(false); + + const { theme, setTheme } = useTheme(); + + const isTheme = useCallback((t: Theme) => t === theme, [theme]); + + const handleThemeSwitch = (theme: Theme) => { + setTheme(theme); + }; + + useEffect(() => { + setMounted(true); + }, []); + + useEffect(() => { + if (isTheme('system')) { + const preferDarkScheme = window.matchMedia( + '(prefers-color-scheme: dark)', + ); + + const detectThemeChange = (event: MediaQueryListEvent) => { + const theme: Theme = event.matches ? 'dark' : 'light'; + setTheme(theme); + }; + + preferDarkScheme.addEventListener('change', detectThemeChange); + + return () => { + preferDarkScheme.removeEventListener('change', detectThemeChange); + }; + } + }, [isTheme, setTheme, theme]); + + // Avoid Hydration Mismatch + if (!mounted) { + return null; + } + + return isTheme('dark') ? ( + handleThemeSwitch('light')} + /> + ) : isTheme('light') ? ( + handleThemeSwitch('dark')} + /> + ) : ( + handleThemeSwitch('system')} + /> + ); +} diff --git a/ui/tailwind.config.ts b/ui/tailwind.config.ts index 05f107d..a757263 100644 --- a/ui/tailwind.config.ts +++ b/ui/tailwind.config.ts @@ -6,6 +6,7 @@ const config: Config = { './components/**/*.{js,ts,jsx,tsx,mdx}', './app/**/*.{js,ts,jsx,tsx,mdx}', ], + darkMode: 'class', theme: { extend: {}, }, From 996cc1b674e169b54c91b1e269a71d6e51f43943 Mon Sep 17 00:00:00 2001 From: WanQuanXie Date: Fri, 24 May 2024 20:29:49 +0800 Subject: [PATCH 03/34] feat: adaptive light mode --- ui/app/layout.tsx | 2 +- ui/components/Chat.tsx | 2 +- ui/components/EmptyChat.tsx | 2 +- ui/components/EmptyChatMessageInput.tsx | 6 +-- ui/components/Layout.tsx | 2 +- ui/components/MessageActions/Copy.tsx | 2 +- ui/components/MessageActions/Rewrite.tsx | 2 +- ui/components/MessageBox.tsx | 30 +++++++----- ui/components/MessageBoxLoading.tsx | 8 +-- ui/components/MessageInput.tsx | 8 +-- ui/components/MessageInputActions.tsx | 24 +++++---- ui/components/MessageSources.tsx | 24 ++++----- ui/components/Navbar.tsx | 2 +- ui/components/SearchImages.tsx | 8 +-- ui/components/SearchVideos.tsx | 12 ++--- ui/components/SettingsDialog.tsx | 62 ++++++++++++++---------- ui/components/Sidebar.tsx | 41 +++++++++++----- ui/tailwind.config.ts | 14 +++++- 18 files changed, 149 insertions(+), 102 deletions(-) diff --git a/ui/app/layout.tsx b/ui/app/layout.tsx index 87144cf..124a3b5 100644 --- a/ui/app/layout.tsx +++ b/ui/app/layout.tsx @@ -34,7 +34,7 @@ export default function RootLayout({ unstyled: true, classNames: { toast: - 'dark:dark:bg-[#111111] text-white rounded-lg p-4 flex flex-row items-center space-x-2', + 'bg-primaryLight dark:bg-primaryDark text-white rounded-lg p-4 flex flex-row items-center space-x-2', }, }} /> diff --git a/ui/components/Chat.tsx b/ui/components/Chat.tsx index 7b0c1b3..60096b3 100644 --- a/ui/components/Chat.tsx +++ b/ui/components/Chat.tsx @@ -66,7 +66,7 @@ const Chat = ({ sendMessage={sendMessage} /> {!isLast && msg.role === 'assistant' && ( -
+
)} ); diff --git a/ui/components/EmptyChat.tsx b/ui/components/EmptyChat.tsx index 30bb883..6b9fddb 100644 --- a/ui/components/EmptyChat.tsx +++ b/ui/components/EmptyChat.tsx @@ -11,7 +11,7 @@ const EmptyChat = ({ }) => { return (
-

+

Research begins here.

-
+
setMessage(e.target.value)} minRows={2} - className="bg-transparent placeholder:text-white/50 text-sm text-white resize-none focus:outline-none w-full max-h-24 lg:max-h-36 xl:max-h-48" + className="bg-transparent placeholder:text-black/50 dark:placeholder:text-white/50 text-sm text-black dark:text-white resize-none focus:outline-none w-full max-h-24 lg:max-h-36 xl:max-h-48" placeholder="Ask anything..." />
@@ -51,7 +51,7 @@ const EmptyChatMessageInput = ({ /> diff --git a/ui/components/Layout.tsx b/ui/components/Layout.tsx index e517e00..cb128db 100644 --- a/ui/components/Layout.tsx +++ b/ui/components/Layout.tsx @@ -1,6 +1,6 @@ const Layout = ({ children }: { children: React.ReactNode }) => { return ( -
+
{children}
); diff --git a/ui/components/MessageActions/Copy.tsx b/ui/components/MessageActions/Copy.tsx index b19d8d4..5418811 100644 --- a/ui/components/MessageActions/Copy.tsx +++ b/ui/components/MessageActions/Copy.tsx @@ -19,7 +19,7 @@ const Copy = ({ setCopied(true); setTimeout(() => setCopied(false), 1000); }} - className="p-2 text-white/70 rounded-xl hover:bg-[#1c1c1c] transition duration-200 hover:text-white" + className="p-2 text-black/70 dark:text-white/70 rounded-xl hover:bg-secondLight dark:hover:bg-secondDark transition duration-200 hover:text-black dark:hover:text-white" > {copied ? : } diff --git a/ui/components/MessageActions/Rewrite.tsx b/ui/components/MessageActions/Rewrite.tsx index 3282e7d..b5f865b 100644 --- a/ui/components/MessageActions/Rewrite.tsx +++ b/ui/components/MessageActions/Rewrite.tsx @@ -10,7 +10,7 @@ const Rewrite = ({ return ( */} @@ -123,7 +127,7 @@ const MessageBox = ({ start(); } }} - className="p-2 text-white/70 rounded-xl hover:bg-[#1c1c1c] transition duration-200 hover:text-white" + className="p-2 text-black/70 dark:text-white/70 rounded-xl hover(bg-secondLight dark:bg-secondDark) transition duration-200 hover:text-black dark:hover:text-white" > {speechStatus === 'started' ? ( @@ -140,8 +144,8 @@ const MessageBox = ({ message.role === 'assistant' && !loading && ( <> -
-
+
+

Related

@@ -152,7 +156,7 @@ const MessageBox = ({ className="flex flex-col space-y-3 text-sm" key={i} > -
+
{ sendMessage(suggestion); diff --git a/ui/components/MessageBoxLoading.tsx b/ui/components/MessageBoxLoading.tsx index e070a27..3a80fe8 100644 --- a/ui/components/MessageBoxLoading.tsx +++ b/ui/components/MessageBoxLoading.tsx @@ -1,9 +1,9 @@ const MessageBoxLoading = () => { return ( -
-
-
-
+
+
+
+
); }; diff --git a/ui/components/MessageInput.tsx b/ui/components/MessageInput.tsx index baf6095..4fbea7c 100644 --- a/ui/components/MessageInput.tsx +++ b/ui/components/MessageInput.tsx @@ -40,7 +40,7 @@ const MessageInput = ({ } }} className={cn( - 'bg-[#111111] p-4 flex items-center overflow-hidden border border-[#1C1C1C]', + 'bg-primaryLight dark:bg-primaryDark p-4 flex items-center overflow-hidden border border-light dark:border-dark', mode === 'multi' ? 'flex-col rounded-lg' : 'flex-row rounded-full', )} > @@ -51,7 +51,7 @@ const MessageInput = ({ onHeightChange={(height, props) => { setTextareaRows(Math.ceil(height / props.rowHeight)); }} - className="transition bg-transparent placeholder:text-white/50 placeholder:text-sm text-sm text-white resize-none focus:outline-none w-full px-2 max-h-24 lg:max-h-36 xl:max-h-48 flex-grow flex-shrink" + className="transition bg-transparent dark:placeholder:text-white/50 placeholder:text-sm text-sm dark:text-white resize-none focus:outline-none w-full px-2 max-h-24 lg:max-h-36 xl:max-h-48 flex-grow flex-shrink" placeholder="Ask a follow-up" /> {mode === 'single' && ( @@ -62,7 +62,7 @@ const MessageInput = ({ /> @@ -78,7 +78,7 @@ const MessageInput = ({ /> diff --git a/ui/components/MessageInputActions.tsx b/ui/components/MessageInputActions.tsx index 9c00c4d..22fc708 100644 --- a/ui/components/MessageInputActions.tsx +++ b/ui/components/MessageInputActions.tsx @@ -16,7 +16,7 @@ export const Attach = () => { return ( @@ -85,7 +85,7 @@ export const Focus = ({ {focusMode !== 'webSearch' ? (
@@ -109,7 +109,7 @@ export const Focus = ({ leaveTo="opacity-0 translate-y-1" > -
+
{focusModes.map((mode, i) => ( setFocusMode(mode.key)} @@ -117,20 +117,24 @@ export const Focus = ({ className={cn( 'p-2 rounded-lg flex flex-col items-start justify-start text-start space-y-2 duration-200 cursor-pointer transition', focusMode === mode.key - ? 'bg-[#111111]' - : 'hover:bg-[#111111]', + ? 'bg-primaryLight dark:bg-primaryDark' + : 'hover:bg-primaryLight dark:bg-primaryDark', )} >
{mode.icon}

{mode.title}

-

{mode.description}

+

+ {mode.description} +

))}
@@ -152,14 +156,14 @@ export const CopilotToggle = ({ Copilot @@ -170,7 +174,7 @@ export const CopilotToggle = ({ 'text-xs font-medium transition-colors duration-150 ease-in-out', copilotEnabled ? 'text-[#24A0ED]' - : 'text-white/50 group-hover:text-white', + : 'text-black/50 dark:text-white/50 group-hover:text-black dark:group-hover:text-white', )} > Copilot diff --git a/ui/components/MessageSources.tsx b/ui/components/MessageSources.tsx index 5816f8d..476c73c 100644 --- a/ui/components/MessageSources.tsx +++ b/ui/components/MessageSources.tsx @@ -20,12 +20,12 @@ const MessageSources = ({ sources }: { sources: Document[] }) => {
{sources.slice(0, 3).map((source, i) => ( -

+

{source.metadata.title}

@@ -37,11 +37,11 @@ const MessageSources = ({ sources }: { sources: Document[] }) => { alt="favicon" className="rounded-lg h-4 w-4" /> -

+

{source.metadata.url.replace(/.+\/\/|www.|\..+/g, '')}

-
+
{i + 1}
@@ -51,7 +51,7 @@ const MessageSources = ({ sources }: { sources: Document[] }) => { {sources.length > 3 && ( @@ -83,19 +83,19 @@ const MessageSources = ({ sources }: { sources: Document[] }) => { leaveFrom="opacity-100 scale-200" leaveTo="opacity-0 scale-95" > - - + + Sources
{sources.map((source, i) => ( -

+

{source.metadata.title}

@@ -107,14 +107,14 @@ const MessageSources = ({ sources }: { sources: Document[] }) => { alt="favicon" className="rounded-lg h-4 w-4" /> -

+

{source.metadata.url.replace( /.+\/\/|www.|\..+/g, '', )}

-
+
{i + 1}
diff --git a/ui/components/Navbar.tsx b/ui/components/Navbar.tsx index 75c34a6..c07d6fd 100644 --- a/ui/components/Navbar.tsx +++ b/ui/components/Navbar.tsx @@ -38,7 +38,7 @@ const Navbar = ({ messages }: { messages: Message[] }) => { }, []); return ( -
+
@@ -76,7 +76,7 @@ const SearchImages = ({ {[...Array(4)].map((_, i) => (
))}
@@ -120,7 +120,7 @@ const SearchImages = ({ {images.length > 4 && ( diff --git a/ui/components/SearchVideos.tsx b/ui/components/SearchVideos.tsx index b5ff6c5..05c3180 100644 --- a/ui/components/SearchVideos.tsx +++ b/ui/components/SearchVideos.tsx @@ -77,7 +77,7 @@ const Searchvideos = ({ ); setLoading(false); }} - className="border border-dashed border-[#1C1C1C] hover:bg-[#1c1c1c] active:scale-95 duration-200 transition px-4 py-2 flex flex-row items-center justify-between rounded-lg text-white text-sm w-full" + className="border border-dashed border-light dark:border-dark hover(bg-secondLight dark:bg-secondDark) active:scale-95 duration-200 transition px-4 py-2 flex flex-row items-center justify-between rounded-lg dark:text-white text-sm w-full" >
@@ -91,7 +91,7 @@ const Searchvideos = ({ {[...Array(4)].map((_, i) => (
))}
@@ -118,7 +118,7 @@ const Searchvideos = ({ alt={video.title} className="relative h-full w-full aspect-video object-cover rounded-lg" /> -
+

Video

@@ -142,7 +142,7 @@ const Searchvideos = ({ alt={video.title} className="relative h-full w-full aspect-video object-cover rounded-lg" /> -
+

Video

@@ -151,7 +151,7 @@ const Searchvideos = ({ {videos.length > 4 && ( diff --git a/ui/components/SettingsDialog.tsx b/ui/components/SettingsDialog.tsx index 57f79f6..1942179 100644 --- a/ui/components/SettingsDialog.tsx +++ b/ui/components/SettingsDialog.tsx @@ -145,7 +145,7 @@ const SettingsDialog = ({ leaveFrom="opacity-100" leaveTo="opacity-0" > -
+
@@ -158,15 +158,15 @@ const SettingsDialog = ({ leaveFrom="opacity-100 scale-200" leaveTo="opacity-0 scale-95" > - - + + Settings {config && !isLoading && (
{config.chatModelProviders && (
-

+

Chat model Provider

setSelectedChatModel(e.target.value) } - className="bg-[#111111] px-3 py-2 flex items-center overflow-hidden border border-[#1C1C1C] text-white rounded-lg text-sm" + className="bg-primaryLight dark:bg-primaryDark px-3 py-2 flex items-center overflow-hidden border border-light dark:border-dark dark:text-white rounded-lg text-sm" > {config.chatModelProviders[ selectedChatModelProvider @@ -231,7 +233,9 @@ const SettingsDialog = ({ selectedChatModelProvider === 'custom_openai' && ( <>
-

Model name

+

+ Model name +

setSelectedChatModel(e.target.value) } - className="bg-[#111111] px-3 py-2 flex items-center overflow-hidden border border-[#1C1C1C] text-white rounded-lg text-sm" + className="bg-primaryLight dark:bg-primaryDark px-3 py-2 flex items-center overflow-hidden border border-light dark:border-dark dark:text-white rounded-lg text-sm" />
-

+

Custom OpenAI API Key

setCustomOpenAIApiKey(e.target.value) } - className="bg-[#111111] px-3 py-2 flex items-center overflow-hidden border border-[#1C1C1C] text-white rounded-lg text-sm" + className="bg-primaryLight dark:bg-primaryDark px-3 py-2 flex items-center overflow-hidden border border-light dark:border-dark dark:text-white rounded-lg text-sm" />
-

+

Custom OpenAI Base URL

setCustomOpenAIBaseURL(e.target.value) } - className="bg-[#111111] px-3 py-2 flex items-center overflow-hidden border border-[#1C1C1C] text-white rounded-lg text-sm" + className="bg-primaryLight dark:bg-primaryDark px-3 py-2 flex items-center overflow-hidden border border-light dark:border-dark dark:text-white rounded-lg text-sm" />
@@ -275,7 +279,7 @@ const SettingsDialog = ({ {/* Embedding models */} {config.embeddingModelProviders && (
-

+

Embedding model Provider

setSelectedEmbeddingModel(e.target.value) } - className="bg-[#111111] px-3 py-2 flex items-center overflow-hidden border border-[#1C1C1C] text-white rounded-lg text-sm" + className="bg-primaryLight dark:bg-primaryDark px-3 py-2 flex items-center overflow-hidden border border-light dark:border-dark dark:text-white rounded-lg text-sm" > {config.embeddingModelProviders[ selectedEmbeddingModelProvider @@ -336,7 +342,9 @@ const SettingsDialog = ({
)}
-

OpenAI API Key

+

+ OpenAI API Key +

-

Ollama API URL

+

+ Ollama API URL +

-

GROQ API Key

+

+ GROQ API Key +

)} {isLoading && ( -
+
)}
-

+

We'll refresh the page after updating the settings.

+ ); +} const Sidebar = ({ children }: { children: React.ReactNode }) => { const segments = useSelectedLayoutSegments(); @@ -38,31 +45,39 @@ const Sidebar = ({ children }: { children: React.ReactNode }) => { return (
-
+
- + -
+ {navLinks.map((link, i) => ( {link.active && ( -
+
)} ))} -
- setIsSettingsOpen(!isSettingsOpen)} - className="text-white cursor-pointer" - /> + + + + + + setIsSettingsOpen(!isSettingsOpen)} + className="cursor-pointer" + /> + + {
-
+
{navLinks.map((link, i) => ( Date: Fri, 24 May 2024 21:58:14 +0800 Subject: [PATCH 04/34] refactor(SettingDialog): extract reduplicate code to common component DO NOT REPEAT YOURSELF! --- ui/components/SettingsDialog.tsx | 213 ++++++++++++++++++------------- 1 file changed, 127 insertions(+), 86 deletions(-) diff --git a/ui/components/SettingsDialog.tsx b/ui/components/SettingsDialog.tsx index 1942179..4d80b9c 100644 --- a/ui/components/SettingsDialog.tsx +++ b/ui/components/SettingsDialog.tsx @@ -1,6 +1,51 @@ +import { cn } from '@/lib/utils'; import { Dialog, Transition } from '@headlessui/react'; import { CloudUpload, RefreshCcw, RefreshCw } from 'lucide-react'; -import React, { Fragment, useEffect, useState } from 'react'; +import React, { + Fragment, + useEffect, + useMemo, + useState, + type SelectHTMLAttributes, +} from 'react'; + +interface InputProps extends React.InputHTMLAttributes {} + +function Input({ className, ...restProps }: InputProps) { + return ( + + ); +} + +interface SelectProps extends SelectHTMLAttributes { + options: { value: string; label: string; disabled?: boolean }[]; +} + +function Select({ className, options, ...restProps }: SelectProps) { + return ( + + ); +} interface SettingsType { chatModelProviders: { @@ -169,7 +214,7 @@ const SettingsDialog = ({

Chat model Provider

- + />
)} {selectedChatModelProvider && @@ -196,37 +239,40 @@ const SettingsDialog = ({

Chat Model

- + ]; + + return chatModelProvider + ? chatModelProvider.length > 0 + ? chatModelProvider.map((model) => ({ + value: model, + label: model, + })) + : [ + { + value: '', + label: 'No models available', + disabled: true, + }, + ] + : [ + { + value: '', + label: + 'Invalid provider, please check backend logs', + disabled: true, + }, + ]; + })()} + />
)} {selectedChatModelProvider && @@ -236,42 +282,39 @@ const SettingsDialog = ({

Model name

- setSelectedChatModel(e.target.value) } - className="bg-primaryLight dark:bg-primaryDark px-3 py-2 flex items-center overflow-hidden border border-light dark:border-dark dark:text-white rounded-lg text-sm" />

Custom OpenAI API Key

- setCustomOpenAIApiKey(e.target.value) } - className="bg-primaryLight dark:bg-primaryDark px-3 py-2 flex items-center overflow-hidden border border-light dark:border-dark dark:text-white rounded-lg text-sm" />

Custom OpenAI Base URL

- setCustomOpenAIBaseURL(e.target.value) } - className="bg-primaryLight dark:bg-primaryDark px-3 py-2 flex items-center overflow-hidden border border-light dark:border-dark dark:text-white rounded-lg text-sm" />
@@ -282,7 +325,7 @@ const SettingsDialog = ({

Embedding model Provider

- + options={Object.keys( + config.embeddingModelProviders, + ).map((provider) => ({ + label: + provider.charAt(0).toUpperCase() + + provider.slice(1), + value: provider, + }))} + />
)} {selectedEmbeddingModelProvider && ( @@ -308,44 +349,47 @@ const SettingsDialog = ({

Embedding Model

- + ]; + + return embeddingModelProvider + ? embeddingModelProvider.length > 0 + ? embeddingModelProvider.map((model) => ({ + label: model, + value: model, + })) + : [ + { + label: 'No embedding models available', + value: '', + disabled: true, + }, + ] + : [ + { + label: + 'Invalid provider, please check backend logs', + value: '', + disabled: true, + }, + ]; + })()} + />
)}

OpenAI API Key

-

Ollama API URL

-

GROQ API Key

-
From 89c30530bc44013d6c7d088f8a7011c11c4c450c Mon Sep 17 00:00:00 2001 From: WanQuanXie Date: Fri, 24 May 2024 22:08:47 +0800 Subject: [PATCH 05/34] update(Navbar): update Navbar light mode background --- ui/components/Navbar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components/Navbar.tsx b/ui/components/Navbar.tsx index c07d6fd..f95a455 100644 --- a/ui/components/Navbar.tsx +++ b/ui/components/Navbar.tsx @@ -38,7 +38,7 @@ const Navbar = ({ messages }: { messages: Message[] }) => { }, []); return ( -
+
Date: Fri, 24 May 2024 22:41:06 +0800 Subject: [PATCH 06/34] update(SearchVideos): video cover label style adapt light mode --- ui/components/SearchVideos.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components/SearchVideos.tsx b/ui/components/SearchVideos.tsx index 05c3180..eaad078 100644 --- a/ui/components/SearchVideos.tsx +++ b/ui/components/SearchVideos.tsx @@ -118,7 +118,7 @@ const Searchvideos = ({ alt={video.title} className="relative h-full w-full aspect-video object-cover rounded-lg" /> -
+

Video

From c97a4347230f505a68339d0c08d13baf2cf67696 Mon Sep 17 00:00:00 2001 From: WanQuanXie Date: Sat, 25 May 2024 06:57:24 +0800 Subject: [PATCH 07/34] fix(ui): hover style class uses --- ui/components/MessageActions/Rewrite.tsx | 2 +- ui/components/MessageBox.tsx | 4 ++-- ui/components/MessageInputActions.tsx | 2 +- ui/components/MessageSources.tsx | 6 +++--- ui/components/SearchImages.tsx | 4 ++-- ui/components/SearchVideos.tsx | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ui/components/MessageActions/Rewrite.tsx b/ui/components/MessageActions/Rewrite.tsx index b5f865b..76a422f 100644 --- a/ui/components/MessageActions/Rewrite.tsx +++ b/ui/components/MessageActions/Rewrite.tsx @@ -10,7 +10,7 @@ const Rewrite = ({ return ( */} @@ -127,7 +127,7 @@ const MessageBox = ({ start(); } }} - className="p-2 text-black/70 dark:text-white/70 rounded-xl hover(bg-secondLight dark:bg-secondDark) transition duration-200 hover:text-black dark:hover:text-white" + className="p-2 text-black/70 dark:text-white/70 rounded-xl hover:bg-secondLight dark:hover:bg-secondDark transition duration-200 hover:text-black dark:hover:text-white" > {speechStatus === 'started' ? ( diff --git a/ui/components/MessageInputActions.tsx b/ui/components/MessageInputActions.tsx index 22fc708..8b6d784 100644 --- a/ui/components/MessageInputActions.tsx +++ b/ui/components/MessageInputActions.tsx @@ -85,7 +85,7 @@ export const Focus = ({ {focusMode !== 'webSearch' ? (
diff --git a/ui/components/MessageSources.tsx b/ui/components/MessageSources.tsx index 476c73c..292b8c6 100644 --- a/ui/components/MessageSources.tsx +++ b/ui/components/MessageSources.tsx @@ -20,7 +20,7 @@ const MessageSources = ({ sources }: { sources: Document[] }) => {
{sources.slice(0, 3).map((source, i) => ( { {sources.length > 3 && ( diff --git a/ui/components/MessageActions/Rewrite.tsx b/ui/components/MessageActions/Rewrite.tsx index 76a422f..80fadb3 100644 --- a/ui/components/MessageActions/Rewrite.tsx +++ b/ui/components/MessageActions/Rewrite.tsx @@ -10,7 +10,7 @@ const Rewrite = ({ return ( */} @@ -127,7 +127,7 @@ const MessageBox = ({ start(); } }} - className="p-2 text-black/70 dark:text-white/70 rounded-xl hover:bg-secondLight dark:hover:bg-secondDark transition duration-200 hover:text-black dark:hover:text-white" + className="p-2 text-black/70 dark:text-white/70 rounded-xl hover:bg-light-secondary dark:hover:bg-dark-secondary transition duration-200 hover:text-black dark:hover:text-white" > {speechStatus === 'started' ? ( @@ -144,7 +144,7 @@ const MessageBox = ({ message.role === 'assistant' && !loading && ( <> -
+
@@ -156,7 +156,7 @@ const MessageBox = ({ className="flex flex-col space-y-3 text-sm" key={i} > -
+
{ sendMessage(suggestion); diff --git a/ui/components/MessageBoxLoading.tsx b/ui/components/MessageBoxLoading.tsx index 3a80fe8..caa6f18 100644 --- a/ui/components/MessageBoxLoading.tsx +++ b/ui/components/MessageBoxLoading.tsx @@ -1,9 +1,9 @@ const MessageBoxLoading = () => { return ( -
-
-
-
+
+
+
+
); }; diff --git a/ui/components/MessageInput.tsx b/ui/components/MessageInput.tsx index 4fbea7c..d215787 100644 --- a/ui/components/MessageInput.tsx +++ b/ui/components/MessageInput.tsx @@ -40,7 +40,7 @@ const MessageInput = ({ } }} className={cn( - 'bg-primaryLight dark:bg-primaryDark p-4 flex items-center overflow-hidden border border-light dark:border-dark', + 'bg-light-primary dark:bg-dark-primary p-4 flex items-center overflow-hidden border border-light-300 dark:border-dark-200', mode === 'multi' ? 'flex-col rounded-lg' : 'flex-row rounded-full', )} > diff --git a/ui/components/MessageInputActions.tsx b/ui/components/MessageInputActions.tsx index 8b6d784..80b2797 100644 --- a/ui/components/MessageInputActions.tsx +++ b/ui/components/MessageInputActions.tsx @@ -16,7 +16,7 @@ export const Attach = () => { return ( @@ -85,7 +85,7 @@ export const Focus = ({ {focusMode !== 'webSearch' ? (
@@ -109,7 +109,7 @@ export const Focus = ({ leaveTo="opacity-0 translate-y-1" > -
+
{focusModes.map((mode, i) => ( setFocusMode(mode.key)} @@ -117,8 +117,8 @@ export const Focus = ({ className={cn( 'p-2 rounded-lg flex flex-col items-start justify-start text-start space-y-2 duration-200 cursor-pointer transition', focusMode === mode.key - ? 'bg-primaryLight dark:bg-primaryDark' - : 'hover:bg-primaryLight dark:bg-primaryDark', + ? 'bg-light-primary dark:bg-dark-primary' + : 'hover:bg-light-primary dark:bg-dark-primary', )} >
Copilot {
{sources.slice(0, 3).map((source, i) => ( { {sources.length > 3 && (