fix: keep pinned chat following final summaries
This commit is contained in:
@@ -122,8 +122,6 @@ export const useChatAutoFollow = ({
|
|||||||
const [isFollowingProgrammatically, setIsFollowingProgrammatically] = React.useState(false);
|
const [isFollowingProgrammatically, setIsFollowingProgrammatically] = React.useState(false);
|
||||||
|
|
||||||
const stateRef = React.useRef<AutoFollowState>('following');
|
const stateRef = React.useRef<AutoFollowState>('following');
|
||||||
const sessionWorkingRef = React.useRef(sessionIsWorking);
|
|
||||||
sessionWorkingRef.current = sessionIsWorking;
|
|
||||||
const sessionMessageCountRef = React.useRef(sessionMessageCount);
|
const sessionMessageCountRef = React.useRef(sessionMessageCount);
|
||||||
sessionMessageCountRef.current = sessionMessageCount;
|
sessionMessageCountRef.current = sessionMessageCount;
|
||||||
const currentSessionIdRef = React.useRef(currentSessionId);
|
const currentSessionIdRef = React.useRef(currentSessionId);
|
||||||
@@ -189,7 +187,7 @@ export const useChatAutoFollow = ({
|
|||||||
stopFollowLoop();
|
stopFollowLoop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stateRef.current !== 'following' || !sessionWorkingRef.current) {
|
if (stateRef.current !== 'following') {
|
||||||
stopFollowLoop();
|
stopFollowLoop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -224,7 +222,7 @@ export const useChatAutoFollow = ({
|
|||||||
const startFollowLoop = React.useCallback(() => {
|
const startFollowLoop = React.useCallback(() => {
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
if (followRafRef.current !== null) return;
|
if (followRafRef.current !== null) return;
|
||||||
if (stateRef.current !== 'following' || !sessionWorkingRef.current) return;
|
if (stateRef.current !== 'following') return;
|
||||||
settledFramesRef.current = 0;
|
settledFramesRef.current = 0;
|
||||||
setIsFollowingProgrammatically(true);
|
setIsFollowingProgrammatically(true);
|
||||||
followRafRef.current = window.requestAnimationFrame(tickFollow);
|
followRafRef.current = window.requestAnimationFrame(tickFollow);
|
||||||
@@ -293,17 +291,13 @@ export const useChatAutoFollow = ({
|
|||||||
setStateValue('following');
|
setStateValue('following');
|
||||||
lastUserReleaseAtRef.current = 0;
|
lastUserReleaseAtRef.current = 0;
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
if (mode === 'smooth' && sessionWorkingRef.current) {
|
if (mode === 'smooth') {
|
||||||
startFollowLoop();
|
startFollowLoop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const target = Math.max(0, container.scrollHeight - container.clientHeight);
|
const target = Math.max(0, container.scrollHeight - container.clientHeight);
|
||||||
writeScrollTopInstant(target);
|
writeScrollTopInstant(target);
|
||||||
if (sessionWorkingRef.current) {
|
startSettleBurst();
|
||||||
startFollowLoop();
|
|
||||||
} else {
|
|
||||||
startSettleBurst();
|
|
||||||
}
|
|
||||||
}, [setStateValue, startFollowLoop, startSettleBurst, writeScrollTopInstant]);
|
}, [setStateValue, startFollowLoop, startSettleBurst, writeScrollTopInstant]);
|
||||||
|
|
||||||
const flushSave = React.useCallback(() => {
|
const flushSave = React.useCallback(() => {
|
||||||
@@ -371,9 +365,7 @@ export const useChatAutoFollow = ({
|
|||||||
lastUserReleaseAtRef.current = 0;
|
lastUserReleaseAtRef.current = 0;
|
||||||
const target = Math.max(0, container.scrollHeight - container.clientHeight);
|
const target = Math.max(0, container.scrollHeight - container.clientHeight);
|
||||||
writeScrollTopInstant(target);
|
writeScrollTopInstant(target);
|
||||||
if (sessionWorkingRef.current) {
|
startFollowLoop();
|
||||||
startFollowLoop();
|
|
||||||
}
|
|
||||||
startSettleBurst();
|
startSettleBurst();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -413,12 +405,10 @@ export const useChatAutoFollow = ({
|
|||||||
}, [currentSessionId, flushSave, markProgrammaticWrite, stopFollowLoop, stopSettleBurst]);
|
}, [currentSessionId, flushSave, markProgrammaticWrite, stopFollowLoop, stopSettleBurst]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!sessionIsWorking) {
|
if (sessionIsWorking && stateRef.current === 'following') {
|
||||||
stopFollowLoop();
|
|
||||||
} else if (stateRef.current === 'following') {
|
|
||||||
startFollowLoop();
|
startFollowLoop();
|
||||||
}
|
}
|
||||||
}, [sessionIsWorking, startFollowLoop, stopFollowLoop]);
|
}, [sessionIsWorking, startFollowLoop]);
|
||||||
|
|
||||||
// Replay a deferred restoreSnapshot once ChatViewport mounts.
|
// Replay a deferred restoreSnapshot once ChatViewport mounts.
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@@ -471,9 +461,7 @@ export const useChatAutoFollow = ({
|
|||||||
const inGrace = (now - lastUserReleaseAtRef.current) < REPIN_GRACE_AFTER_RELEASE_MS;
|
const inGrace = (now - lastUserReleaseAtRef.current) < REPIN_GRACE_AFTER_RELEASE_MS;
|
||||||
if (stateRef.current === 'released' && isNearBottom(container, isMobile) && !inGrace) {
|
if (stateRef.current === 'released' && isNearBottom(container, isMobile) && !inGrace) {
|
||||||
setStateValue('following');
|
setStateValue('following');
|
||||||
if (sessionWorkingRef.current) {
|
startFollowLoop();
|
||||||
startFollowLoop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
queueSave();
|
queueSave();
|
||||||
@@ -564,7 +552,7 @@ export const useChatAutoFollow = ({
|
|||||||
|
|
||||||
const observer = new ResizeObserver(() => {
|
const observer = new ResizeObserver(() => {
|
||||||
updateOverflowAndButton();
|
updateOverflowAndButton();
|
||||||
if (stateRef.current === 'following' && sessionWorkingRef.current) {
|
if (stateRef.current === 'following') {
|
||||||
startFollowLoop();
|
startFollowLoop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -583,7 +571,7 @@ export const useChatAutoFollow = ({
|
|||||||
const notifyContentChange = React.useCallback((_reason?: ContentChangeReason) => {
|
const notifyContentChange = React.useCallback((_reason?: ContentChangeReason) => {
|
||||||
void _reason;
|
void _reason;
|
||||||
updateOverflowAndButton();
|
updateOverflowAndButton();
|
||||||
if (stateRef.current === 'following' && sessionWorkingRef.current) {
|
if (stateRef.current === 'following') {
|
||||||
startFollowLoop();
|
startFollowLoop();
|
||||||
}
|
}
|
||||||
}, [startFollowLoop, updateOverflowAndButton]);
|
}, [startFollowLoop, updateOverflowAndButton]);
|
||||||
@@ -595,7 +583,7 @@ export const useChatAutoFollow = ({
|
|||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
|
|
||||||
const kick = () => {
|
const kick = () => {
|
||||||
if (stateRef.current === 'following' && sessionWorkingRef.current) {
|
if (stateRef.current === 'following') {
|
||||||
startFollowLoop();
|
startFollowLoop();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user