feat: refresh shared chat and server workflows
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Button, Empty, Input, List, Spin, Typography } from 'antd';
|
||||
import type { ChatConversationSummary } from '../../mainChatPanel/types';
|
||||
import { shouldShowConversationForMode } from '../../isolatedChatRooms';
|
||||
import { shouldShowPrimaryConversation } from '../../chatSessionRouting';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
@@ -26,7 +26,7 @@ export function ConversationListPane({
|
||||
onSelectSession,
|
||||
onCreateConversation,
|
||||
}: ConversationListPaneProps) {
|
||||
const visibleItems = items.filter((item) => shouldShowConversationForMode(item.sessionId, 'live'));
|
||||
const visibleItems = items.filter((item) => shouldShowPrimaryConversation(item.sessionId));
|
||||
|
||||
return (
|
||||
<section className="chat-v2__pane chat-v2__pane--list">
|
||||
|
||||
@@ -5,6 +5,11 @@ import type {
|
||||
ChatRuntimeSnapshot,
|
||||
} from '../../mainChatPanel/types';
|
||||
|
||||
const SCROLL_JUMP_HIDE_THRESHOLD = 24;
|
||||
const SCROLL_JUMP_MIN_OVERFLOW = 48;
|
||||
const SCROLL_JUMP_DIRECTION_THRESHOLD = 6;
|
||||
const SCROLL_JUMP_IDLE_HIDE_DELAY_MS = 900;
|
||||
|
||||
type UseConversationViewportControllerOptions = {
|
||||
activeConversation: ChatConversationSummary | null;
|
||||
activeQueuedComposerRequestsCount: number;
|
||||
@@ -50,6 +55,7 @@ export function useConversationViewportController({
|
||||
const systemStatusTimerRef = useRef<number | null>(null);
|
||||
const restoreAutoScrollFrameRef = useRef<number | null>(null);
|
||||
const showScrollToBottomRef = useRef(false);
|
||||
const scrollJumpIdleTimerRef = useRef<number | null>(null);
|
||||
const shouldStickToBottomRef = useRef(true);
|
||||
const lastViewportScrollTopRef = useRef(0);
|
||||
const autoScrollSuspendedUntilRef = useRef(0);
|
||||
@@ -74,6 +80,13 @@ export function useConversationViewportController({
|
||||
}
|
||||
}, []);
|
||||
|
||||
const clearScrollJumpIdleTimer = useCallback(() => {
|
||||
if (scrollJumpIdleTimerRef.current !== null) {
|
||||
window.clearTimeout(scrollJumpIdleTimerRef.current);
|
||||
scrollJumpIdleTimerRef.current = null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const syncShowScrollToBottom = useCallback((nextValue: boolean) => {
|
||||
if (showScrollToBottomRef.current === nextValue) {
|
||||
return;
|
||||
@@ -144,8 +157,11 @@ export function useConversationViewportController({
|
||||
}
|
||||
|
||||
const remainingDistance = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;
|
||||
const isNearBottom = remainingDistance <= 24;
|
||||
const isScrollingUp = viewport.scrollTop < lastViewportScrollTopRef.current - 2;
|
||||
const maxScrollDistance = Math.max(0, viewport.scrollHeight - viewport.clientHeight);
|
||||
const currentScrollTop = viewport.scrollTop;
|
||||
const scrollDelta = currentScrollTop - lastViewportScrollTopRef.current;
|
||||
const isNearBottom = remainingDistance <= SCROLL_JUMP_HIDE_THRESHOLD;
|
||||
const isScrollingUp = scrollDelta < -2;
|
||||
|
||||
if (isNearBottom) {
|
||||
releaseAutoScrollSuspension();
|
||||
@@ -155,9 +171,30 @@ export function useConversationViewportController({
|
||||
|
||||
const shouldStickToBottom = isNearBottom && !isAutoScrollSuspended();
|
||||
shouldStickToBottomRef.current = shouldStickToBottom;
|
||||
lastViewportScrollTopRef.current = viewport.scrollTop;
|
||||
syncShowScrollToBottom(!shouldStickToBottom);
|
||||
}, [isAutoScrollSuspended, releaseAutoScrollSuspension, syncShowScrollToBottom, viewportRef]);
|
||||
lastViewportScrollTopRef.current = currentScrollTop;
|
||||
|
||||
if (maxScrollDistance < SCROLL_JUMP_MIN_OVERFLOW || shouldStickToBottom) {
|
||||
clearScrollJumpIdleTimer();
|
||||
syncShowScrollToBottom(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.abs(scrollDelta) >= SCROLL_JUMP_DIRECTION_THRESHOLD) {
|
||||
clearScrollJumpIdleTimer();
|
||||
scrollJumpIdleTimerRef.current = window.setTimeout(() => {
|
||||
scrollJumpIdleTimerRef.current = null;
|
||||
syncShowScrollToBottom(false);
|
||||
}, SCROLL_JUMP_IDLE_HIDE_DELAY_MS);
|
||||
}
|
||||
|
||||
syncShowScrollToBottom(true);
|
||||
}, [
|
||||
clearScrollJumpIdleTimer,
|
||||
isAutoScrollSuspended,
|
||||
releaseAutoScrollSuspension,
|
||||
syncShowScrollToBottom,
|
||||
viewportRef,
|
||||
]);
|
||||
|
||||
const captureViewportRestoreSnapshot = useCallback((options?: { forceStickToBottom?: boolean }) => {
|
||||
if (options?.forceStickToBottom) {
|
||||
@@ -491,12 +528,13 @@ export function useConversationViewportController({
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
clearSystemStatusTimer();
|
||||
clearScrollJumpIdleTimer();
|
||||
|
||||
if (restoreAutoScrollFrameRef.current !== null) {
|
||||
window.cancelAnimationFrame(restoreAutoScrollFrameRef.current);
|
||||
}
|
||||
};
|
||||
}, [clearSystemStatusTimer]);
|
||||
}, [clearScrollJumpIdleTimer, clearSystemStatusTimer]);
|
||||
|
||||
return {
|
||||
activeSystemStatus,
|
||||
|
||||
Reference in New Issue
Block a user