Merge pull request #1199 from buster-so/big-nate-bus-1901-report-is-scrolled-down-when-it-finishes-streaming-in

Big nate bus 1901 report is scrolled down when it finishes streaming in
This commit is contained in:
Nate Kelley 2025-09-27 19:59:40 -06:00 committed by GitHub
commit e0961e0637
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 31 additions and 10 deletions

View File

@ -6,9 +6,7 @@ import { ReportEditorSkeleton } from './ReportEditorSkeleton';
const DynamicReportEditorBase = lazy(() =>
import('@/components/ui/report/ReportEditor').then((mod) => {
return {
default: mod.ReportEditor,
};
return { default: mod.ReportEditor };
})
);

View File

@ -1,6 +1,6 @@
import type { AnyPluginConfig, Value } from 'platejs';
import { Plate, type TPlateEditor } from 'platejs/react';
import React, { useEffect, useImperativeHandle, useRef } from 'react';
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
import { ScrollToBottomButton } from '@/components/features/buttons/ScrollToBottomButton';
import { useAutoScroll } from '@/hooks/useAutoScroll';
import { useDebounceFn } from '@/hooks/useDebounce';
@ -140,7 +140,6 @@ export const ReportEditor = React.memo(
<Plate editor={editor} onValueChange={onValueChangeDebounced}>
<EditorContainer
variant={variant}
readOnly={readOnly}
className={cn('editor-container relative', containerClassName)}
>
{preEditorChildren}
@ -149,7 +148,7 @@ export const ReportEditor = React.memo(
style={style}
placeholder={placeholder}
className={cn('editor', className)}
readOnly={readOnly || isStreaming}
readOnly={readOnly} //do not have streaming here, it causes scrolling issue when toggling
autoFocus
/>
</ThemeWrapper>

View File

@ -6,6 +6,8 @@ import { useAutoRedirectStreaming } from './useAutoRedirectStreaming';
// Mock all the dependencies
vi.mock('@tanstack/react-router', () => ({
useNavigate: vi.fn(),
useLocation: vi.fn(),
useRouter: vi.fn(),
}));
vi.mock('@/api/buster_rest/chats', () => ({
@ -27,6 +29,10 @@ vi.mock('@/context/Chats/useGetChatMessage', () => ({
useGetChatMessageLastReasoningMessageId: vi.fn(),
}));
vi.mock('@/context/Routes/useRouteBuilder', () => ({
useBuildLocation: vi.fn(),
}));
vi.mock('@/hooks/useWindowFocus', () => ({
useWindowFocus: vi.fn(),
}));
@ -36,7 +42,7 @@ vi.mock('@/lib/assets/assetParamsToRoute', () => ({
}));
// Import the mocked functions to use in tests
import { useNavigate } from '@tanstack/react-router';
import { useLocation, useNavigate } from '@tanstack/react-router';
import { useGetChatMessageMemoized } from '@/api/buster_rest/chats';
import { useIsVersionChanged } from '@/context/AppVersion/useAppVersion';
import { useHasLoadedChat } from '@/context/Chats/useGetChat';
@ -46,6 +52,7 @@ import {
useGetChatMessageIsFinishedReasoning,
useGetChatMessageLastReasoningMessageId,
} from '@/context/Chats/useGetChatMessage';
import { useBuildLocation } from '@/context/Routes/useRouteBuilder';
import { assetParamsToRoute } from '@/lib/assets/assetParamsToRoute';
describe('useAutoRedirectStreaming', () => {
@ -69,6 +76,7 @@ describe('useAutoRedirectStreaming', () => {
};
let mockNavigateFn: ReturnType<typeof vi.fn>;
let mockBuildLocationFn: ReturnType<typeof vi.fn>;
beforeEach(() => {
vi.clearAllMocks();
@ -77,6 +85,16 @@ describe('useAutoRedirectStreaming', () => {
mockNavigateFn = vi.fn();
vi.mocked(useNavigate).mockReturnValue(mockNavigateFn);
// Setup location mocks
vi.mocked(useLocation).mockReturnValue({
pathname: '/current/path',
} as any);
mockBuildLocationFn = vi.fn().mockReturnValue({
pathname: '/different/path', // Different from current location to trigger navigation
});
vi.mocked(useBuildLocation).mockReturnValue(mockBuildLocationFn);
// Set default mock implementations
vi.mocked(useHasLoadedChat).mockReturnValue(true);
vi.mocked(useGetChatMessageCompleted).mockReturnValue(false);

View File

@ -1,4 +1,4 @@
import { useNavigate } from '@tanstack/react-router';
import { useLocation, useNavigate } from '@tanstack/react-router';
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
import type { BusterChatResponseMessage_file } from '@/api/asset_interfaces/chat';
import { useGetChatMessageMemoized } from '@/api/buster_rest/chats';
@ -10,6 +10,7 @@ import {
useGetChatMessageIsFinishedReasoning,
useGetChatMessageLastReasoningMessageId,
} from '@/context/Chats/useGetChatMessage';
import { useBuildLocation } from '@/context/Routes/useRouteBuilder';
import { useWindowFocus } from '@/hooks/useWindowFocus';
import { assetParamsToRoute } from '@/lib/assets/assetParamsToRoute';
@ -21,6 +22,8 @@ export const useAutoRedirectStreaming = ({
chatId: string | undefined;
}) => {
const navigate = useNavigate();
const location = useLocation();
const buildLocation = useBuildLocation();
const getChatMessageMemoized = useGetChatMessageMemoized();
const versionChanged = useIsVersionChanged();
const isStreamFinished = useGetChatMessageCompleted({ messageId: lastMessageId });
@ -67,8 +70,11 @@ export const useAutoRedirectStreaming = ({
chatId,
versionNumber: firstFile.version_number,
});
navigate({ ...linkProps, replace: true, reloadDocument: versionChanged });
const builtLocation = buildLocation(linkProps);
const isOnSamePage = builtLocation.pathname === location.pathname;
if (!isOnSamePage) {
navigate({ ...linkProps, replace: true, reloadDocument: versionChanged });
}
}
previousIsCompletedStream.current = true;