change auto layout ocnif

This commit is contained in:
Nate Kelley 2025-02-11 16:46:22 -07:00
parent 9f914a34f9
commit 18549b442f
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
13 changed files with 112 additions and 57 deletions

View File

@ -2,5 +2,5 @@ export const itemAnimationConfig = {
initial: { opacity: 0 },
animate: { opacity: 1 },
exit: { opacity: 0 },
transition: { duration: 0.675 }
transition: { duration: 0.725 }
};

View File

@ -34,7 +34,6 @@ export const ReasoningMessageContainer: React.FC<{
isLastMessageItem={index === lastMessageIndex}
chatId={chatId}
/>
<VerticalDivider />
</div>
))}
</div>
@ -71,6 +70,12 @@ const useStyles = createStyles(({ token, css }) => ({
&:has(+ .file-card) {
margin-bottom: 3px;
}
&:has(+ .thought-card) {
.vertical-divider {
display: none;
}
}
`,
fileCard: css`
margin-bottom: 4px;

View File

@ -15,7 +15,7 @@ export const ReasoningMessage_Thought: React.FC<ReasoningMessageProps> = React.m
return (
<BarContainer
showBar={hasThoughts}
showBar={hasThoughts || !isLastMessageItem}
status={loadingStatus}
isCompletedStream={isCompletedStream}
title={thought_title}

View File

@ -40,7 +40,10 @@ export const useChatIndividualContext = ({
(x) => !x.chatsMessages[currentMessageId]?.isCompletedStream
);
useAutoChangeLayout({ lastMessageId: currentMessageId, onSetSelectedFile });
useAutoChangeLayout({
lastMessageId: currentMessageId,
onSetSelectedFile
});
return {
hasChat,

View File

@ -5,6 +5,7 @@ import { useEffect } from 'react';
export const useAutoChangeLayout = ({
lastMessageId,
onSetSelectedFile
}: {
lastMessageId: string;
@ -18,6 +19,7 @@ export const useAutoChangeLayout = ({
const hasReasoning = !!reasoningMessagesLength;
const previousIsEmpty = previousReasoningMessagesLength === 0;
//change the page to reasoning file if we get a reasoning message
useEffect(() => {
if (isLoading && previousIsEmpty && hasReasoning) {
onSetSelectedFile({ id: lastMessageId, type: 'reasoning' });

View File

@ -11,7 +11,7 @@ import type { AppSplitterRef } from '@/components/layout';
import { createChatAssetRoute, createFileRoute } from './helpers';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
import { DEFAULT_CHAT_OPTION } from './config';
import { useAutoSetLayout } from '../hooks';
import { useInitialChatLayout } from '../hooks';
import { useChatFileLayout } from './useChatFileLayout';
interface UseChatSplitterProps {
@ -32,12 +32,13 @@ export const useChatLayout = ({
const animateOpenSplitter = useMemoizedFn((side: 'left' | 'right' | 'both') => {
if (appSplitterRef.current) {
const { animateWidth, isSideClosed } = appSplitterRef.current;
const { animateWidth } = appSplitterRef.current;
if (side === 'left') {
animateWidth('100%', 'left');
} else if (side === 'right') {
animateWidth('100%', 'right');
} else if (side === 'both' && (isSideClosed('right') || isSideClosed('left'))) {
} else if (side === 'both') {
//&& (isSideClosed('right') || isSideClosed('left'))
animateWidth(DEFAULT_CHAT_OPTION, 'left');
setIsPureChat(false);
setIsPureFile(false);
@ -69,7 +70,9 @@ export const useChatLayout = ({
setIsCollapseOpen(!isCloseAction);
if (isFileLayout) {
if (defaultSelectedFile && defaultSelectedFile.type === 'reasoning') {
animateOpenSplitter(!isCloseAction ? 'both' : 'left');
} else if (isFileLayout) {
// For file layout, toggle between 'both' and 'right'
animateOpenSplitter(!isCloseAction && defaultSelectedFile ? 'both' : 'right');
} else {
@ -86,8 +89,11 @@ export const useChatLayout = ({
setIsPureFile,
collapseDirection,
isCollapseOpen
} = useAutoSetLayout({
defaultSelectedLayout
} = useInitialChatLayout({
defaultSelectedLayout,
defaultSelectedFile,
chatId,
onCollapseFileClick
});
const fileLayoutContext = useChatFileLayout({

View File

@ -1,3 +1,3 @@
export * from './useDefaultFile';
export * from './useAutoSetLayout';
export * from './useInitialChatLayout';
export * from './useDefaultSplitterLayout';

View File

@ -1,31 +0,0 @@
import { useUpdateLayoutEffect } from 'ahooks';
import { useMemo, useState } from 'react';
export const useAutoSetLayout = ({
defaultSelectedLayout
}: {
defaultSelectedLayout: 'chat' | 'file' | 'both' | undefined;
}) => {
const [isPureFile, setIsPureFile] = useState(defaultSelectedLayout === 'file');
const [isPureChat, setIsPureChat] = useState(defaultSelectedLayout === 'chat');
const [isCollapseOpen, setIsCollapseOpen] = useState(isPureChat ? true : false);
useUpdateLayoutEffect(() => {
if (isPureFile === true) setIsPureFile(defaultSelectedLayout === 'file');
if (isPureChat === true) setIsPureChat(defaultSelectedLayout === 'chat');
}, [defaultSelectedLayout]);
const collapseDirection: 'left' | 'right' = useMemo(() => {
return defaultSelectedLayout === 'file' ? 'left' : 'right';
}, [defaultSelectedLayout]);
return {
isPureFile,
isPureChat,
setIsPureChat,
setIsPureFile,
collapseDirection,
setIsCollapseOpen,
isCollapseOpen
};
};

View File

@ -0,0 +1,56 @@
import { useMemoizedFn, useUpdateEffect, useUpdateLayoutEffect } from 'ahooks';
import { useEffect, useMemo, useState } from 'react';
import { ChatSplitterProps } from '../ChatLayout';
import { useBusterChatContextSelector } from '@/context/Chats';
export const useInitialChatLayout = ({
defaultSelectedLayout,
defaultSelectedFile,
chatId,
onCollapseFileClick
}: {
defaultSelectedLayout: 'chat' | 'file' | 'both' | undefined;
chatId: string | undefined;
defaultSelectedFile: ChatSplitterProps['defaultSelectedFile'];
onCollapseFileClick: (close?: boolean) => void;
}) => {
const getChatMemoized = useBusterChatContextSelector((x) => x.getChatMemoized);
const isReasoningFile = defaultSelectedFile?.type === 'reasoning';
const [isPureFile, setIsPureFile] = useState(defaultSelectedLayout === 'file');
const [isPureChat, setIsPureChat] = useState(defaultSelectedLayout === 'chat');
const [isCollapseOpen, setIsCollapseOpen] = useState(
isPureChat || isReasoningFile ? true : false
);
const collapseDirection: 'left' | 'right' = useMemo(() => {
if (defaultSelectedFile?.type === 'reasoning') return 'right';
return defaultSelectedLayout === 'file' ? 'left' : 'right';
}, [defaultSelectedLayout, defaultSelectedFile?.type]);
const resetChatForNewChat = useMemoizedFn(() => {
onCollapseFileClick(true);
setIsPureChat(true);
});
useUpdateLayoutEffect(() => {
if (isPureFile === true) setIsPureFile(defaultSelectedLayout === 'file');
if (isPureChat === true) setIsPureChat(defaultSelectedLayout === 'chat');
}, [defaultSelectedLayout]);
useUpdateEffect(() => {
if (chatId && getChatMemoized(chatId)?.isNewChat) {
resetChatForNewChat();
}
}, [chatId]);
return {
isPureFile,
isPureChat,
setIsPureChat,
setIsPureFile,
collapseDirection,
setIsCollapseOpen,
isCollapseOpen
};
};

View File

@ -17,7 +17,7 @@ export const useBusterNewChat = () => {
startListeningForChatProgress,
stopListeningForChatProgress,
stopChatCallback,
initializeChatCallback,
initializeNewChatCallback,
replaceMessageCallback
} = useChatUpdateMessage();
@ -52,7 +52,7 @@ export const useBusterNewChat = () => {
},
responseEvent: {
route: '/chats/post:initializeChat',
callback: initializeChatCallback
callback: initializeNewChatCallback
}
});
@ -68,10 +68,20 @@ export const useBusterNewChat = () => {
);
const onStartChatFromFile = useMemoizedFn(
async ({}: { prompt: string; fileId: string; fileType: FileType }) => {
console.log('start chat from file');
await new Promise((resolve) => setTimeout(resolve, 1000));
async ({
prompt,
fileId,
fileType
}: {
prompt: string;
fileId: string;
fileType: FileType;
}) => {
onStartNewChat({
prompt,
metricId: fileType === 'metric' ? fileId : undefined,
dashboardId: fileType === 'dashboard' ? fileId : undefined
});
}
);

View File

@ -11,7 +11,6 @@ import { updateChatToIChat } from '@/utils/chat';
import { useAutoAppendThought } from './useAutoAppendThought';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
import { BusterRoutes } from '@/routes';
import last from 'lodash/last';
export const useChatUpdateMessage = () => {
const busterSocket = useBusterWebSocket();
@ -69,11 +68,14 @@ export const useChatUpdateMessage = () => {
const _generatingReasoningMessageCallback = useMemoizedFn(
(d: ChatEvent_GeneratingReasoningMessage) => {
const { message_id, reasoning, chat_id } = d;
const currentReasoning = getChatMessageMemoized(message_id)!.reasoning;
const isNewMessage = !currentReasoning?.some(({ id }) => id === message_id);
const currentReasoning = getChatMessageMemoized(message_id)?.reasoning ?? [];
const reasoningMessageId = reasoning.id;
const foundReasoningMessage = currentReasoning.find(({ id }) => id === reasoningMessageId);
const isNewMessage = !foundReasoningMessage;
const updatedReasoning = isNewMessage
? [...currentReasoning, reasoning]
: currentReasoning.map((rm) => (rm.id === message_id ? reasoning : rm));
: currentReasoning.map((rm) => (rm.id === reasoningMessageId ? reasoning : rm));
onUpdateChatMessage({
id: message_id,
@ -96,7 +98,7 @@ export const useChatUpdateMessage = () => {
});
});
const initializeChatCallback = useMemoizedFn((d: BusterChat) => {
const initializeNewChatCallback = useMemoizedFn((d: BusterChat) => {
const { iChat, iChatMessages } = updateChatToIChat(d, true);
onBulkSetChatMessages(iChatMessages);
onUpdateChat(iChat);
@ -179,7 +181,7 @@ export const useChatUpdateMessage = () => {
});
return {
initializeChatCallback,
initializeNewChatCallback,
completeChatCallback,
startListeningForChatProgress,
stopListeningForChatProgress,

View File

@ -2,6 +2,7 @@ import type { BusterChat, BusterChatMessage } from '@/api/asset_interfaces';
export interface IBusterChat extends Omit<BusterChat, 'messages'> {
messages: string[];
isNewChat: boolean;
}
export interface IBusterChatMessage extends BusterChatMessage {

View File

@ -1,10 +1,11 @@
import type { BusterChat, BusterChatMessage } from '@/api/asset_interfaces';
import type { IBusterChat, IBusterChatMessage } from '@/context/Chats/interfaces';
const chatUpgrader = (chat: BusterChat): IBusterChat => {
const chatUpgrader = (chat: BusterChat, { isNewChat }: { isNewChat: boolean }): IBusterChat => {
return {
...chat,
messages: chat.messages.map((message) => message.id)
messages: chat.messages.map((message) => message.id),
isNewChat
};
};
@ -36,7 +37,7 @@ const chatMessageUpgrader = (
};
export const updateChatToIChat = (chat: BusterChat, isNewChat: boolean) => {
const iChat = chatUpgrader(chat);
const iChat = chatUpgrader(chat, { isNewChat });
const iChatMessages = chatMessageUpgrader(chat.messages, {
isCompletedStream: !isNewChat,
messageId: chat.messages[0].id