refactor: enhance Sidepanel layout and structure for improved usability and responsiveness

This commit is contained in:
n4ze3m 2025-02-08 16:01:47 +05:30
parent d315a39793
commit 7b8ba1404d
5 changed files with 333 additions and 312 deletions

View File

@ -23,7 +23,8 @@ export const SidePanelBody = () => {
} }
}) })
return ( return (
<div className="grow flex flex-col md:translate-x-0 transition-transform duration-300 ease-in-out"> <>
<div className="relative flex w-full flex-col items-center pt-16 pb-4">
{messages.length === 0 && <EmptySidePanel />} {messages.length === 0 && <EmptySidePanel />}
{messages.map((message, index) => ( {messages.map((message, index) => (
<PlaygroundMessage <PlaygroundMessage
@ -52,13 +53,15 @@ export const SidePanelBody = () => {
reasoningTimeTaken={message?.reasoning_time_taken} reasoningTimeTaken={message?.reasoning_time_taken}
/> />
))} ))}
<div className="w-full h-48 flex-shrink-0"></div>
<div ref={divRef} /> <div ref={divRef} />
</div>
<div className="w-full pb-[157px]"></div>
<MessageSourcePopup <MessageSourcePopup
open={isSourceOpen} open={isSourceOpen}
setOpen={setIsSourceOpen} setOpen={setIsSourceOpen}
source={source} source={source}
/> />
</div> </>
) )
} }

View File

@ -134,8 +134,8 @@ export const EmptySidePanel = () => {
} }
return ( return (
<div className="mx-auto sm:max-w-md px-4 mt-10"> <div className="mx-auto sm:max-w-lg px-4 mt-10">
<div className="rounded-lg justify-center items-center flex flex-col border dark:border-gray-700 p-8 bg-white dark:bg-[#262626] shadow-sm"> <div className="rounded-lg justify-center items-center flex flex-col border border-gray-300 dark:border-gray-700 p-8 bg-white dark:bg-[#262626] shadow-sm">
{(ollamaStatus === "pending" || isRefetching) && ( {(ollamaStatus === "pending" || isRefetching) && (
<div className="inline-flex items-center space-x-2"> <div className="inline-flex items-center space-x-2">
<div className="w-3 h-3 bg-blue-500 rounded-full animate-bounce"></div> <div className="w-3 h-3 bg-blue-500 rounded-full animate-bounce"></div>

View File

@ -226,9 +226,14 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
}, [defaultChatWithWebsite]) }, [defaultChatWithWebsite])
return ( return (
<div className="px-3 pt-3 md:px-6 md:pt-6 bg-white dark:bg-[#262626] border rounded-t-xl border-gray-300 dark:border-gray-600"> <div className="flex w-full flex-col items-center p-2 pt-1 pb-4">
<div className="relative z-10 flex w-full flex-col items-center justify-center gap-2 text-base">
<div className="relative flex w-full flex-row justify-center gap-2 lg:w-4/5">
<div <div
className={`h-full rounded-md shadow relative ${ className={` bg-neutral-50 dark:bg-[#262626] relative w-full max-w-[48rem] p-1 backdrop-blur-lg duration-100 border border-gray-300 rounded-xl dark:border-gray-600
`}>
<div
className={`h-full shadow relative ${
form.values.image.length === 0 ? "hidden" : "block" form.values.image.length === 0 ? "hidden" : "block"
}`}> }`}>
<div className="relative"> <div className="relative">
@ -259,14 +264,20 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
if (chatMode === "rag") { if (chatMode === "rag") {
const defaultEM = await defaultEmbeddingModelForRag() const defaultEM = await defaultEmbeddingModelForRag()
if (!defaultEM) { if (!defaultEM) {
form.setFieldError("message", t("formError.noEmbeddingModel")) form.setFieldError(
"message",
t("formError.noEmbeddingModel")
)
return return
} }
} }
if (webSearch) { if (webSearch) {
const defaultEM = await defaultEmbeddingModelForRag() const defaultEM = await defaultEmbeddingModelForRag()
if (!defaultEM) { if (!defaultEM) {
form.setFieldError("message", t("formError.noEmbeddingModel")) form.setFieldError(
"message",
t("formError.noEmbeddingModel")
)
return return
} }
} }
@ -295,7 +306,7 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
multiple={false} multiple={false}
onChange={onInputChange} onChange={onInputChange}
/> />
<div className="w-full border-x border-t border-gray-300 flex flex-col dark:border-gray-600 rounded-t-xl p-2"> <div className="w-full flex flex-col p-1">
<textarea <textarea
onKeyDown={(e) => handleKeyDown(e)} onKeyDown={(e) => handleKeyDown(e)}
ref={textareaRef} ref={textareaRef}
@ -436,7 +447,9 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
<Checkbox <Checkbox
checked={chatMode === "rag"} checked={chatMode === "rag"}
onChange={(e) => { onChange={(e) => {
setChatMode(e.target.checked ? "rag" : "normal") setChatMode(
e.target.checked ? "rag" : "normal"
)
}}> }}>
{t("common:chatWithCurrentPage")} {t("common:chatWithCurrentPage")}
</Checkbox> </Checkbox>
@ -447,7 +460,9 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
label: ( label: (
<Checkbox <Checkbox
checked={useOCR} checked={useOCR}
onChange={(e) => setUseOCR(e.target.checked)}> onChange={(e) =>
setUseOCR(e.target.checked)
}>
{t("useOCR")} {t("useOCR")}
</Checkbox> </Checkbox>
) )
@ -493,5 +508,8 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
)} )}
</div> </div>
</div> </div>
</div>
</div>
</div>
) )
} }

View File

@ -40,7 +40,7 @@ export const SidepanelHeader = () => {
const [sidebarOpen, setSidebarOpen] = React.useState(false) const [sidebarOpen, setSidebarOpen] = React.useState(false)
return ( return (
<div className="flex px-3 justify-between bg-white dark:bg-[#171717] border-b border-gray-300 dark:border-gray-700 py-4 items-center"> <div className=" px-3 justify-between bg-white dark:bg-[#171717] border-b border-gray-300 dark:border-gray-700 py-4 items-center absolute top-0 z-10 flex h-14 w-full">
<div className="focus:outline-none focus-visible:ring-2 focus-visible:ring-pink-700 flex items-center dark:text-white"> <div className="focus:outline-none focus-visible:ring-2 focus-visible:ring-pink-700 flex items-center dark:text-white">
<img <img
className="h-6 w-auto" className="h-6 w-auto"

View File

@ -126,25 +126,25 @@ const SidepanelChat = () => {
}, [bgMsg]) }, [bgMsg])
return ( return (
<div <div className="flex h-full w-full">
ref={drop} <main className="relative h-dvh w-full">
className={`flex ${ <div className="relative z-10 w-full">
dropState === "dragging" && chatMode === "normal"
? "bg-neutral-200 dark:bg-gray-800 z-10"
: "bg-neutral-50 dark:bg-[#171717]"
} flex-col min-h-screen mx-auto max-w-7xl`}>
<div className="sticky top-0 z-10">
<SidepanelHeader /> <SidepanelHeader />
</div> </div>
<div
ref={drop}
className={`relative flex h-full flex-col items-center ${
dropState === "dragging" ? "bg-gray-100 dark:bg-gray-800" : ""
} bg-white dark:bg-[#171717]`}>
<div className="custom-scrollbar bg-bottom-mask-light dark:bg-bottom-mask-dark mask-bottom-fade will-change-mask flex h-full w-full flex-col items-center overflow-x-hidden overflow-y-auto px-5">
<SidePanelBody /> <SidePanelBody />
</div>
<div className="bottom-0 w-full bg-transparent border-0 fixed pt-2"> <div className="absolute bottom-0 w-full">
<div className="stretch mx-2 flex flex-row gap-3 md:mx-4 lg:mx-auto lg:max-w-2xl xl:max-w-3xl">
<div className="relative flex flex-col h-full flex-1 items-stretch md:flex-col">
<SidepanelForm dropedFile={dropedFile} /> <SidepanelForm dropedFile={dropedFile} />
</div> </div>
</div> </div>
</div> </main>
</div> </div>
) )
} }