fix: stabilize ai design history switching
This commit is contained in:
@@ -930,6 +930,8 @@ export function ImageCanvas() {
|
||||
const conversation = useImageWorkspaceStore((state) => state.conversation);
|
||||
const tasks = useImageWorkspaceStore((state) => state.tasks);
|
||||
const pendingTurn = useImageWorkspaceStore((state) => state.pendingTurn);
|
||||
const loadingOlderMessages = useImageWorkspaceStore((state) => state.loadingOlderMessages);
|
||||
const olderMessagesError = useImageWorkspaceStore((state) => state.olderMessagesError);
|
||||
const workspaceError = useImageWorkspaceStore((state) => state.error);
|
||||
const load = useImageWorkspaceStore((state) => state.load);
|
||||
const connectTaskStream = useImageWorkspaceStore((state) => state.connectTaskStream);
|
||||
@@ -937,6 +939,7 @@ export function ImageCanvas() {
|
||||
const markTaskStreamNeedsReconciliation = useImageWorkspaceStore(
|
||||
(state) => state.markTaskStreamNeedsReconciliation,
|
||||
);
|
||||
const loadOlderMessages = useImageWorkspaceStore((state) => state.loadOlderMessages);
|
||||
const sendMessage = useImageWorkspaceStore((state) => state.sendMessage);
|
||||
const updateGenerationQuote = useImageWorkspaceStore(
|
||||
(state) => state.updateGenerationQuote,
|
||||
@@ -966,6 +969,7 @@ export function ImageCanvas() {
|
||||
const conversationEndRef = useRef<HTMLDivElement | null>(null);
|
||||
const conversationWindowStartRef = useRef<number | null>(null);
|
||||
const conversationShouldStickRef = useRef(true);
|
||||
const olderMessagesRequestRef = useRef(false);
|
||||
const promptRef = useRef<HTMLTextAreaElement | null>(null);
|
||||
const referenceUploadInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const promptSelectionRef = useRef({ start: 0, end: 0 });
|
||||
@@ -1111,6 +1115,7 @@ export function ImageCanvas() {
|
||||
useEffect(() => {
|
||||
conversationWindowStartRef.current = null;
|
||||
conversationShouldStickRef.current = true;
|
||||
olderMessagesRequestRef.current = false;
|
||||
setConversationWindowStart(null);
|
||||
setPrompt('');
|
||||
setReferenceAssets([]);
|
||||
@@ -1162,6 +1167,22 @@ export function ImageCanvas() {
|
||||
setConversationWindowStart(null);
|
||||
}, [conversationMessages.length]);
|
||||
|
||||
const requestOlderMessages = useCallback(() => {
|
||||
const element = conversationScrollRef.current;
|
||||
if (!element || olderMessagesRequestRef.current || !conversation?.messagePage?.hasOlder) return;
|
||||
const previousHeight = element.scrollHeight;
|
||||
olderMessagesRequestRef.current = true;
|
||||
conversationShouldStickRef.current = false;
|
||||
void loadOlderMessages().finally(() => {
|
||||
olderMessagesRequestRef.current = false;
|
||||
window.requestAnimationFrame(() => {
|
||||
const nextElement = conversationScrollRef.current;
|
||||
if (!nextElement) return;
|
||||
nextElement.scrollTop += nextElement.scrollHeight - previousHeight;
|
||||
});
|
||||
});
|
||||
}, [conversation?.messagePage?.hasOlder, loadOlderMessages]);
|
||||
|
||||
const handleConversationScroll = useCallback(() => {
|
||||
const element = conversationScrollRef.current;
|
||||
if (!element) return;
|
||||
@@ -1177,11 +1198,13 @@ export function ImageCanvas() {
|
||||
if (!nextElement) return;
|
||||
nextElement.scrollTop += nextElement.scrollHeight - previousHeight;
|
||||
});
|
||||
} else if (element.scrollTop < 96 && currentStart === 0) {
|
||||
requestOlderMessages();
|
||||
}
|
||||
conversationShouldStickRef.current = element.scrollHeight
|
||||
- element.scrollTop
|
||||
- element.clientHeight <= CANVAS_BOTTOM_THRESHOLD_PX;
|
||||
}, [conversationMessages.length]);
|
||||
}, [conversationMessages.length, requestOlderMessages]);
|
||||
|
||||
const repriceQuote = async (
|
||||
requestedQuoteId: string,
|
||||
@@ -1787,9 +1810,30 @@ export function ImageCanvas() {
|
||||
setConversationWindowStart(0);
|
||||
}}
|
||||
>
|
||||
加载更早消息({effectiveConversationWindowStart})
|
||||
显示已加载的更早消息({effectiveConversationWindowStart})
|
||||
</button>
|
||||
) : null}
|
||||
{effectiveConversationWindowStart === 0 && loadingOlderMessages ? (
|
||||
<div
|
||||
data-testid="image-workspace-loading-older-messages"
|
||||
className="mx-auto flex items-center gap-2 py-1 text-xs text-muted-foreground"
|
||||
>
|
||||
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||
正在读取更早消息…
|
||||
</div>
|
||||
) : null}
|
||||
{effectiveConversationWindowStart === 0
|
||||
&& !loadingOlderMessages
|
||||
&& olderMessagesError
|
||||
&& conversation?.messagePage?.hasOlder ? (
|
||||
<button
|
||||
type="button"
|
||||
className="mx-auto block rounded-md border border-border/70 px-3 py-1.5 text-xs text-muted-foreground hover:bg-surface-subtle hover:text-foreground"
|
||||
onClick={requestOlderMessages}
|
||||
>
|
||||
重新加载更早消息
|
||||
</button>
|
||||
) : null}
|
||||
{windowedConversationMessages.map((message) => {
|
||||
const assistant = message.role === 'assistant';
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user