diff --git a/web/src/app/app/_layouts/ChatLayout/ChatLayout.tsx b/web/src/app/app/_layouts/ChatLayout/ChatLayout.tsx index 174332081..23209c578 100644 --- a/web/src/app/app/_layouts/ChatLayout/ChatLayout.tsx +++ b/web/src/app/app/_layouts/ChatLayout/ChatLayout.tsx @@ -27,19 +27,17 @@ export const ChatLayout: React.FC = React.memo( }, [selectedLayout]); const useChatSplitterProps = useChatLayout({ selectedFile }); - const { onSetSelectedFile, hasFile, selectedFileId } = useChatSplitterProps; + const { onSetSelectedFile, hasFile } = useChatSplitterProps; useUpdateEffect(() => { if (appSplitterRef.current) { + const { animateWidth, isSideClosed } = appSplitterRef.current; if (selectedLayout === 'chat') { - appSplitterRef.current?.animateWidth('100%', 'left'); + animateWidth('100%', 'left'); } else if (selectedLayout === 'file') { - appSplitterRef.current?.animateWidth('100%', 'right'); - } else if ( - selectedLayout === 'both' && - (appSplitterRef.current.isRightClosed || appSplitterRef.current.isLeftClosed) - ) { - appSplitterRef.current?.animateWidth('320px', 'left'); + animateWidth('100%', 'right'); + } else if (selectedLayout === 'both' && (isSideClosed('right') || isSideClosed('left'))) { + animateWidth('320px', 'left'); } } @@ -55,11 +53,10 @@ export const ChatLayout: React.FC = React.memo( } - rightChildren={!selectedFileId ? null : } + rightChildren={} autoSaveId="chat-splitter" defaultLayout={defaultSplitterLayout} preserveSide="left" - rightHidden={!hasFile} leftPanelMaxSize={hasFile ? 625 : undefined} leftPanelMinSize={hasFile ? 250 : undefined} rightPanelMinSize={450} diff --git a/web/src/app/app/_layouts/ChatLayout/ChatLayoutContext/ChatLayoutContext.tsx b/web/src/app/app/_layouts/ChatLayout/ChatLayoutContext/ChatLayoutContext.tsx index 56f37762c..6b357a6c5 100644 --- a/web/src/app/app/_layouts/ChatLayout/ChatLayoutContext/ChatLayoutContext.tsx +++ b/web/src/app/app/_layouts/ChatLayout/ChatLayoutContext/ChatLayoutContext.tsx @@ -11,18 +11,15 @@ interface UseChatSplitterProps { } export const useChatLayout = ({ selectedFile: selectedFileProp }: UseChatSplitterProps) => { - const [selectedFileId, setSelectedFileId] = useState(selectedFileProp?.id); - + const selectedFileId = selectedFileProp?.id; + const selectedFileType = selectedFileProp?.type; const hasFile = !!selectedFileId; const selectedFileTitle: string = useMemo(() => { - console.log('selectedFileId', selectedFileId); if (!selectedFileId) return ''; return 'test'; }, [selectedFileId]); - const selectedFileType = selectedFileProp?.type; - const onSetSelectedFile = (file: SelectedFile) => { // setSelectedFileId(file.id); }; diff --git a/web/src/app/app/_layouts/ChatLayout/FileContainer/FileContainer.tsx b/web/src/app/app/_layouts/ChatLayout/FileContainer/FileContainer.tsx index 229d3f11b..26e52718a 100644 --- a/web/src/app/app/_layouts/ChatLayout/FileContainer/FileContainer.tsx +++ b/web/src/app/app/_layouts/ChatLayout/FileContainer/FileContainer.tsx @@ -1,11 +1,36 @@ import React from 'react'; -import type { ChatSplitterProps } from '../ChatLayout'; -import { SelectedFile } from '../interfaces'; +import { useChatSplitterContextSelector } from '../ChatLayoutContext'; +import { AnimatePresence, motion } from 'framer-motion'; interface FileContainerProps {} +const animation = { + initial: { opacity: 0 }, + animate: { opacity: 1 }, + exit: { opacity: 0 }, + transition: { duration: 0.15 } +}; + export const FileContainer: React.FC = React.memo(({}) => { - return
FileContainer
; + const selectedFileId = useChatSplitterContextSelector((state) => state.selectedFileId); + const selectedFileType = useChatSplitterContextSelector((state) => state.selectedFileType); + + const hasFile = !!selectedFileId; + + return ( +
+ + {hasFile ? ( + +
+ {selectedFileType} +
+
+ ) : null} +
+
+ ); }); FileContainer.displayName = 'FileContainer'; diff --git a/web/src/components/layout/AppSplitter/AppSplitter.tsx b/web/src/components/layout/AppSplitter/AppSplitter.tsx index 606e2ddeb..eb89a93c6 100644 --- a/web/src/components/layout/AppSplitter/AppSplitter.tsx +++ b/web/src/components/layout/AppSplitter/AppSplitter.tsx @@ -25,8 +25,7 @@ import { createStyles } from 'antd-style'; export interface AppSplitterRef { setSplitSizes: (newSizes: (number | string)[]) => void; animateWidth: (width: string, side: 'left' | 'right', duration?: number) => Promise; - isLeftClosed: boolean; - isRightClosed: boolean; + isSideClosed: (side: 'left' | 'right') => boolean; } export const AppSplitter = React.memo( @@ -100,13 +99,12 @@ export const AppSplitter = React.memo( }; }, [rightHidden]); - const isLeftClosed = useMemo(() => { - return _sizes[0] === '0px' || _sizes[0] === '0%' || _sizes[0] === 0; - }, [_sizes]); - - const isRightClosed = useMemo(() => { + const isSideClosed = useMemoizedFn((side: 'left' | 'right') => { + if (side === 'left') { + return _sizes[0] === '0px' || _sizes[0] === '0%' || _sizes[0] === 0; + } return _sizes[1] === '0px' || _sizes[1] === '0%' || _sizes[1] === 0; - }, [_sizes]); + }); const sashRender = useMemoizedFn((_: number, active: boolean) => ( ({ setSplitSizes, animateWidth, - isLeftClosed, - isRightClosed + isSideClosed }); - }, [setSplitSizes, animateWidth, isLeftClosed, isRightClosed]); + }, [setSplitSizes, animateWidth, isSideClosed]); // Add useImperativeHandle to expose the function useImperativeHandle(ref, imperativeHandleMethods);