mirror of https://github.com/buster-so/buster.git
chat file headers
This commit is contained in:
parent
2fe395b5ea
commit
8b21e0d50c
|
@ -1,18 +0,0 @@
|
|||
import React from 'react';
|
||||
import type { ChatSplitterProps } from './ChatSplitter';
|
||||
|
||||
interface ChatContainerProps {
|
||||
chatHeaderText: string;
|
||||
chatHeaderOptions: ChatSplitterProps['chatHeaderOptions'];
|
||||
chatContent: ChatSplitterProps['chatContent'];
|
||||
}
|
||||
|
||||
export const ChatContainer: React.FC<ChatContainerProps> = React.memo(({ chatHeaderText }) => {
|
||||
return (
|
||||
<div className="h-full w-full bg-red-500">
|
||||
{/* <Button onClick={onToggleClick}>Toggle {toggleClose.toString()}</Button> */}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
ChatContainer.displayName = 'ChatContainer';
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import type { ChatSplitterProps } from '../ChatSplitter';
|
||||
import { ChatContainerHeader } from './ChatContainerHeader';
|
||||
import { SelectedFile } from '../interfaces';
|
||||
import { ChatContainerContentContainer } from './ChatContainerContentContainer';
|
||||
|
||||
interface ChatContainerProps {
|
||||
chatContent: ChatSplitterProps['chatContent'];
|
||||
selectedFile: SelectedFile | undefined;
|
||||
}
|
||||
|
||||
export const ChatContainer: React.FC<ChatContainerProps> = React.memo(
|
||||
({ chatContent, selectedFile }) => {
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col">
|
||||
<ChatContainerHeader selectedFile={selectedFile} />
|
||||
<ChatContainerContentContainer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
ChatContainer.displayName = 'ChatContainer';
|
|
@ -0,0 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
export const ChatContainerContentContainer: React.FC = () => {
|
||||
return <div className="h-full w-full bg-red-200">ChatContainerContentContainer</div>;
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
import { appContentHeaderHeight } from '@/components/layout/AppContentHeader';
|
||||
import { createStyles } from 'antd-style';
|
||||
import React from 'react';
|
||||
import { SelectedFile } from '../../interfaces';
|
||||
import { useChatSplitterContextSelector } from '../../ChatSplitterContext';
|
||||
import { Text } from '@/components/text';
|
||||
import { ChatContainerHeaderOptions } from './ChatContainerHeaderOptions';
|
||||
import { ChatContainerHeaderTitle } from './ChatContainerHeaderTitle';
|
||||
|
||||
export const ChatContainerHeader: React.FC<{
|
||||
selectedFile: SelectedFile | undefined;
|
||||
}> = React.memo(({ selectedFile }) => {
|
||||
const { cx, styles } = useStyles();
|
||||
const hasFile = useChatSplitterContextSelector((state) => state.hasFile);
|
||||
|
||||
return (
|
||||
<div className={cx('flex w-full items-center justify-between space-x-2 px-4', styles.header)}>
|
||||
{hasFile && (
|
||||
<>
|
||||
<ChatContainerHeaderTitle />
|
||||
<ChatContainerHeaderOptions />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
ChatContainerHeader.displayName = 'ChatContainerHeader';
|
||||
|
||||
const useStyles = createStyles(({ token }) => ({
|
||||
header: {
|
||||
height: appContentHeaderHeight
|
||||
}
|
||||
}));
|
|
@ -0,0 +1,13 @@
|
|||
import { AppMaterialIcons } from '@/components';
|
||||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
export const ChatContainerHeaderOptions: React.FC<{}> = React.memo(() => {
|
||||
return (
|
||||
<div>
|
||||
<Button type="text" icon={<AppMaterialIcons icon="more_horiz" />} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
ChatContainerHeaderOptions.displayName = 'ChatContainerHeaderOptions';
|
|
@ -0,0 +1,16 @@
|
|||
import { Text } from '@/components/text';
|
||||
import React from 'react';
|
||||
import { useChatSplitterContextSelector } from '../../ChatSplitterContext';
|
||||
|
||||
export const ChatContainerHeaderTitle: React.FC<{}> = React.memo(() => {
|
||||
const hasFile = useChatSplitterContextSelector((state) => state.hasFile);
|
||||
const selectedFileTitle = useChatSplitterContextSelector((state) => state.selectedFileTitle);
|
||||
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<Text>{selectedFileTitle}</Text>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
ChatContainerHeaderTitle.displayName = 'ChatContainerHeaderTitle';
|
|
@ -0,0 +1 @@
|
|||
export * from './ChatContainerHeader';
|
|
@ -0,0 +1 @@
|
|||
export * from './ChatContainer';
|
|
@ -1,51 +1,44 @@
|
|||
import React, { useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
||||
import React, { useMemo, useRef } from 'react';
|
||||
import { AppSplitter, AppSplitterRef } from '@/components/layout/AppSplitter';
|
||||
import { AppChatMessageFileType } from '@/components/messages/AppChatMessageContainer';
|
||||
import { ChatContainer } from './ChatContainer';
|
||||
import { FileContainer } from './FileContainer';
|
||||
import { useUpdateEffect } from 'ahooks';
|
||||
import { ChatSplitterContextProvider } from './ChatSplitterContext';
|
||||
import { useChatSplitter } from './ChatSplitterContext/useChatSplitter';
|
||||
import { useChatSplitter } from './ChatSplitterContext';
|
||||
import { SelectedFile } from './interfaces';
|
||||
|
||||
export interface ChatSplitterProps {
|
||||
chatHeaderText: string;
|
||||
chatHeaderOptions?: [];
|
||||
chatContent?: React.ReactNode;
|
||||
fileHeader?: React.ReactNode;
|
||||
defaultShowFile?: boolean;
|
||||
showChatCollapse?: boolean;
|
||||
defaultShowLayout?: 'chat' | 'file' | 'both';
|
||||
defaultSelectedFile?: SelectedFile;
|
||||
}
|
||||
|
||||
export const ChatSplitter: React.FC<ChatSplitterProps> = React.memo(
|
||||
({
|
||||
chatHeaderText,
|
||||
defaultShowFile = false,
|
||||
defaultSelectedFile,
|
||||
chatHeaderOptions,
|
||||
chatContent,
|
||||
fileHeader
|
||||
}) => {
|
||||
({ defaultSelectedFile, defaultShowLayout = 'chat', chatHeaderOptions, chatContent }) => {
|
||||
const appSplitterRef = useRef<AppSplitterRef>(null);
|
||||
|
||||
const defaultLayout = useMemo(() => {
|
||||
return defaultShowFile ? ['20%', '80%'] : ['100%', '0%'];
|
||||
}, [defaultShowFile]);
|
||||
if (defaultShowLayout === 'chat') {
|
||||
return ['100%', '0%'];
|
||||
}
|
||||
if (defaultShowLayout === 'file') {
|
||||
return ['0%', '100%'];
|
||||
}
|
||||
return ['325px', 'auto'];
|
||||
}, [defaultShowLayout]);
|
||||
|
||||
const useChatSplitterProps = useChatSplitter({ defaultSelectedFile, appSplitterRef });
|
||||
const useChatSplitterProps = useChatSplitter({
|
||||
defaultSelectedFile,
|
||||
appSplitterRef
|
||||
});
|
||||
const { selectedFile, hasFile } = useChatSplitterProps;
|
||||
|
||||
return (
|
||||
<ChatSplitterContextProvider useChatSplitterProps={useChatSplitterProps}>
|
||||
<AppSplitter
|
||||
ref={appSplitterRef}
|
||||
leftChildren={
|
||||
<ChatContainer
|
||||
chatHeaderText={chatHeaderText}
|
||||
chatHeaderOptions={chatHeaderOptions}
|
||||
chatContent={chatContent}
|
||||
/>
|
||||
}
|
||||
leftChildren={<ChatContainer selectedFile={selectedFile} chatContent={chatContent} />}
|
||||
rightChildren={<FileContainer selectedFile={selectedFile} />}
|
||||
autoSaveId="chat-splitter"
|
||||
defaultLayout={defaultLayout}
|
||||
|
|
|
@ -5,7 +5,6 @@ import {
|
|||
useContextSelector
|
||||
} from '@fluentui/react-context-selector';
|
||||
import { useChatSplitter } from './useChatSplitter';
|
||||
import { AppSplitterRef } from '@/components/layout/AppSplitter';
|
||||
|
||||
const ChatSplitterContext = createContext<ReturnType<typeof useChatSplitter>>(
|
||||
{} as ReturnType<typeof useChatSplitter>
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export * from './ChatSplitterContext';
|
||||
export * from './useChatSplitter';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { SelectedFile } from '../interfaces';
|
||||
import { useUpdateEffect } from 'ahooks';
|
||||
import type { AppSplitterRef } from '@/components/layout/AppSplitter';
|
||||
|
@ -14,6 +14,11 @@ export const useChatSplitter = ({ appSplitterRef, defaultSelectedFile }: UseChat
|
|||
|
||||
const hasFile = !!selectedFile;
|
||||
|
||||
const selectedFileTitle: string = useMemo(() => {
|
||||
if (!selectedFile) return '';
|
||||
return 'This is a test';
|
||||
}, [selectedFile]);
|
||||
|
||||
const onSetSelectedFile = (file: SelectedFile) => {
|
||||
setSelectedFile(file);
|
||||
};
|
||||
|
@ -25,13 +30,12 @@ export const useChatSplitter = ({ appSplitterRef, defaultSelectedFile }: UseChat
|
|||
appSplitterRef.current?.animateWidth('50%', 'right');
|
||||
}, 1000);
|
||||
|
||||
// appSplitterRef.current.animateWidth('200px', 'left');
|
||||
|
||||
appSplitterRef.current?.animateWidth('100px', 'right');
|
||||
}
|
||||
}, [defaultSelectedFile]);
|
||||
|
||||
return {
|
||||
selectedFileTitle,
|
||||
hasFile,
|
||||
selectedFile,
|
||||
onSetSelectedFile
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import type { ChatSplitterProps } from './ChatSplitter';
|
||||
import { SelectedFile } from './interfaces';
|
||||
import type { ChatSplitterProps } from '../ChatSplitter';
|
||||
import { SelectedFile } from '../interfaces';
|
||||
|
||||
interface FileContainerProps {
|
||||
selectedFile: SelectedFile | undefined;
|
|
@ -0,0 +1 @@
|
|||
export * from './FileContainer';
|
|
@ -11,7 +11,10 @@ export default function Page() {
|
|||
const [toggleClose, setToggleClose] = useState(false);
|
||||
const ref = useRef<AppSplitterRef>(null);
|
||||
|
||||
const [defaultFile, setDefaultFile] = useState<SelectedFile | undefined>(undefined);
|
||||
const [defaultFile, setDefaultFile] = useState<SelectedFile | undefined>({
|
||||
id: '1',
|
||||
type: 'metric'
|
||||
});
|
||||
|
||||
const onToggleClick = useMemoizedFn(() => {
|
||||
if (toggleClose) {
|
||||
|
@ -25,7 +28,7 @@ export default function Page() {
|
|||
|
||||
return (
|
||||
<div className="h-screen w-screen border">
|
||||
<ChatSplitter chatHeaderText="Chat" defaultSelectedFile={defaultFile} />
|
||||
<ChatSplitter defaultShowLayout="both" defaultSelectedFile={defaultFile} />
|
||||
|
||||
<Button onClick={() => setDefaultFile({ id: '1', type: 'metric' })}>Set Default File</Button>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue