From acc88e362d314cc28836c382b1ce8eba3483faa4 Mon Sep 17 00:00:00 2001 From: notmd <33456881+notmd@users.noreply.github.com> Date: Sat, 22 Apr 2023 01:03:19 +0700 Subject: [PATCH] Rework chat layout UI (#2741) The `QueueInfo` is removed for now. I will add it back in follow up PR. Most of the change are UI code, there is no logic here, it safe to merge Desktop
Light mode ![image](https://user-images.githubusercontent.com/33456881/233029668-d04702cd-9f3b-4315-a4e2-8d99d78c68aa.png)
Dark mode ![image](https://user-images.githubusercontent.com/33456881/233029734-eaf0b350-43c8-487f-a1a4-13972280bb57.png)
Mobile
Light mode ![image](https://user-images.githubusercontent.com/33456881/233031042-45d5fd2c-ca70-48c4-b41a-abb6c70ac502.png)
Dark mode ![image](https://user-images.githubusercontent.com/33456881/233031086-508eabc4-1910-4d81-b079-0a5720d7e67d.png)
--------- Co-authored-by: AbdBarho --- website/public/locales/en/chat.json | 3 +- .../src/components/Chat/ChatConfigDesktop.tsx | 38 ++++++ ...hatConfigDrawer.tsx => ChatConfigForm.tsx} | 39 +------ .../src/components/Chat/ChatConfigMobile.tsx | 42 +++++++ .../src/components/Chat/ChatConfigSaver.tsx | 9 +- .../src/components/Chat/ChatConversation.tsx | 48 +++++--- website/src/components/Chat/ChatForm.tsx | 73 +++++++----- .../components/Chat/ChatInputIconButton.tsx | 19 +++ website/src/components/Chat/ChatListBase.tsx | 47 +++----- .../src/components/Chat/ChatListDesktop.tsx | 15 +-- website/src/components/Chat/ChatListItem.tsx | 9 +- .../src/components/Chat/ChatListMobile.tsx | 49 ++++++-- .../src/components/Chat/ChatMessageEntry.tsx | 10 +- website/src/components/Chat/ChatSection.tsx | 42 +++---- .../components/Chat/InferencePoweredBy.tsx | 37 +++--- website/src/components/Header/Header.tsx | 9 +- website/src/components/Layout/ChatLayout.tsx | 49 ++++---- .../components/Messages/BaseMessageEntry.tsx | 4 +- website/src/components/SideMenu.tsx | 109 ++++++++++-------- website/src/components/SideMenuLayout.tsx | 31 ++--- website/src/components/TeamMember.tsx | 8 +- website/src/pages/chat/index.tsx | 15 ++- website/src/styles/Theme/index.ts | 8 +- website/src/utils/chat.ts | 3 +- 24 files changed, 432 insertions(+), 284 deletions(-) create mode 100644 website/src/components/Chat/ChatConfigDesktop.tsx rename website/src/components/Chat/{ChatConfigDrawer.tsx => ChatConfigForm.tsx} (86%) create mode 100644 website/src/components/Chat/ChatConfigMobile.tsx create mode 100644 website/src/components/Chat/ChatInputIconButton.tsx diff --git a/website/public/locales/en/chat.json b/website/public/locales/en/chat.json index bd473b74ff..99ca3bd84a 100644 --- a/website/public/locales/en/chat.json +++ b/website/public/locales/en/chat.json @@ -23,5 +23,6 @@ "top_p": "Top P", "typical_p": "Typical P", "you_are_logged_in": "You are logged in to the chat service", - "your_chats": "Your Chats" + "your_chats": "Your Chats", + "input_placeholder": "Ask the assistant anything" } diff --git a/website/src/components/Chat/ChatConfigDesktop.tsx b/website/src/components/Chat/ChatConfigDesktop.tsx new file mode 100644 index 0000000000..e58b7253ca --- /dev/null +++ b/website/src/components/Chat/ChatConfigDesktop.tsx @@ -0,0 +1,38 @@ +import { Box } from "@chakra-ui/react"; +import { useTranslation } from "next-i18next"; +import { memo } from "react"; +import SimpleBar from "simplebar-react"; + +import { ChatConfigForm } from "./ChatConfigForm"; + +export const ChatConfigDesktop = memo(function ChatConfigDesktop() { + const { t } = useTranslation("chat"); + return ( + + + {t("config_title")} + + + + + + + ); +}); diff --git a/website/src/components/Chat/ChatConfigDrawer.tsx b/website/src/components/Chat/ChatConfigForm.tsx similarity index 86% rename from website/src/components/Chat/ChatConfigDrawer.tsx rename to website/src/components/Chat/ChatConfigForm.tsx index bfb33b31e7..69a5d7bd7c 100644 --- a/website/src/components/Chat/ChatConfigDrawer.tsx +++ b/website/src/components/Chat/ChatConfigForm.tsx @@ -1,14 +1,7 @@ import { - Drawer, - DrawerBody, - DrawerCloseButton, - DrawerContent, - DrawerHeader, - DrawerOverlay, Flex, FormControl, FormLabel, - IconButton, NumberDecrementStepper, NumberIncrementStepper, NumberInput, @@ -22,9 +15,7 @@ import { Stack, Switch, Tooltip, - useDisclosure, } from "@chakra-ui/react"; -import { Settings } from "lucide-react"; import { useTranslation } from "next-i18next"; import { ChangeEvent, memo, useCallback, useState } from "react"; import { Controller, useFormContext, useWatch } from "react-hook-form"; @@ -32,28 +23,6 @@ import { ChatConfigFormData, SamplingParameters } from "src/types/Chat"; import { useChatContext } from "./ChatContext"; import { areParametersEqual } from "./WorkParameters"; - -export const ChatConfigDrawer = memo(function ChatConfigDrawer() { - const { isOpen, onOpen, onClose } = useDisclosure(); - - const { t } = useTranslation("chat"); - return ( - <> - } onClick={onOpen} size="lg" borderRadius="xl" /> - - - - - {t("config_title")} - - - - - - - ); -}); - const sliderItems: Readonly< Array<{ key: keyof SamplingParameters; @@ -112,7 +81,7 @@ const parameterLabel: Record = { typical_p: "Typical P", }; -const ChatConfigForm = () => { +export const ChatConfigForm = memo(function ChatConfigForm() { const { t } = useTranslation("chat"); const { modelInfos } = useChatContext(); @@ -178,7 +147,7 @@ const ChatConfigForm = () => { ))} ); -}; +}); type NumberInputSliderProps = { max?: number; @@ -216,7 +185,9 @@ const ChatParameterField = memo(function ChatParameterField(props: NumberInputSl - {label} + + {label} + diff --git a/website/src/components/Chat/ChatConfigMobile.tsx b/website/src/components/Chat/ChatConfigMobile.tsx new file mode 100644 index 0000000000..caa7579b02 --- /dev/null +++ b/website/src/components/Chat/ChatConfigMobile.tsx @@ -0,0 +1,42 @@ +import { + Drawer, + DrawerBody, + DrawerCloseButton, + DrawerContent, + DrawerHeader, + DrawerOverlay, + useDisclosure, +} from "@chakra-ui/react"; +import { Settings } from "lucide-react"; +import { useTranslation } from "next-i18next"; +import { memo } from "react"; + +import { ChatConfigForm } from "./ChatConfigForm"; +import { ChatInputIconButton } from "./ChatInputIconButton"; + +export const ChatConfigDrawer = memo(function ChatConfigDrawer() { + const { isOpen, onOpen, onClose } = useDisclosure(); + + const { t } = useTranslation("chat"); + return ( + <> + + + + + + {t("config_title")} + + + + + + + ); +}); diff --git a/website/src/components/Chat/ChatConfigSaver.tsx b/website/src/components/Chat/ChatConfigSaver.tsx index 698317d09f..2d258d0a09 100644 --- a/website/src/components/Chat/ChatConfigSaver.tsx +++ b/website/src/components/Chat/ChatConfigSaver.tsx @@ -4,11 +4,14 @@ import { ChatConfigFormData } from "src/types/Chat"; import { setConfigCache } from "src/utils/chat"; export const ChatConfigSaver = () => { - const { watch } = useFormContext(); + const { watch, formState } = useFormContext(); const config = watch(); useEffect(() => { - setConfigCache(config); - }, [config]); + // only update when form is changed + if (formState.isDirty) { + setConfigCache(config); + } + }, [config, formState.isDirty]); return null; }; diff --git a/website/src/components/Chat/ChatConversation.tsx b/website/src/components/Chat/ChatConversation.tsx index ce5138d686..4bdc262a6c 100644 --- a/website/src/components/Chat/ChatConversation.tsx +++ b/website/src/components/Chat/ChatConversation.tsx @@ -1,7 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Flex, useBoolean, useToast } from "@chakra-ui/react"; +import { Box, useBoolean, useToast } from "@chakra-ui/react"; import { memo, useCallback, useRef, useState } from "react"; import { UseFormGetValues } from "react-hook-form"; +import SimpleBar from "simplebar-react"; import { useMessageVote } from "src/hooks/chat/useMessageVote"; import { get, post } from "src/lib/api"; import { handleChatEventStream, QueueInfo } from "src/lib/chat_stream"; @@ -200,18 +201,39 @@ export const ChatConversation = memo(function ChatConversation({ chatId, getConf ); return ( - - - {isSending && streamedResponse && } - + + + + {isSending && streamedResponse && } + - + ); }); diff --git a/website/src/components/Chat/ChatForm.tsx b/website/src/components/Chat/ChatForm.tsx index da27a5808a..059f5cef24 100644 --- a/website/src/components/Chat/ChatForm.tsx +++ b/website/src/components/Chat/ChatForm.tsx @@ -1,11 +1,12 @@ -import { Button, Grid, Textarea } from "@chakra-ui/react"; +import { Box, CircularProgress, Flex, Textarea } from "@chakra-ui/react"; +import { Send } from "lucide-react"; import { useTranslation } from "next-i18next"; import { forwardRef, KeyboardEvent, SyntheticEvent, useCallback } from "react"; import TextareaAutosize from "react-textarea-autosize"; import { QueueInfo } from "src/lib/chat_stream"; -import { ChatConfigDrawer } from "./ChatConfigDrawer"; -import { QueueInfoMessage } from "./QueueInfoMessage"; +import { ChatConfigDrawer } from "./ChatConfigMobile"; +import { ChatInputIconButton } from "./ChatInputIconButton"; type ChatFormProps = { isSending: boolean; @@ -16,7 +17,7 @@ type ChatFormProps = { // eslint-disable-next-line react/display-name export const ChatForm = forwardRef((props, ref) => { const { isSending, onSubmit: onSubmit, queueInfo } = props; - const { t } = useTranslation("common"); + const { t } = useTranslation("chat"); const handleSubmit = useCallback( (e: SyntheticEvent) => { e.preventDefault(); @@ -34,31 +35,43 @@ export const ChatForm = forwardRef((props, r [onSubmit] ); return ( -
-