fix: chat scroll fix

This commit is contained in:
2026-06-05 02:46:39 +02:00
parent 9e1d75d038
commit ca069e2f61
6 changed files with 203 additions and 209 deletions

View File

@@ -1,4 +1,4 @@
import { resolveAutoScrollBehavior } from './auto-scroll.rules';
import { isStuckToBottom, resolveAutoScrollBehavior } from './auto-scroll.rules';
describe('resolveAutoScrollBehavior', () => {
const base = {
@@ -48,3 +48,28 @@ describe('resolveAutoScrollBehavior', () => {
).toBe('smooth');
});
});
describe('isStuckToBottom', () => {
it('is stuck when exactly at the bottom', () => {
expect(isStuckToBottom(0)).toBe(true);
});
it('is stuck within the default sticky threshold', () => {
expect(isStuckToBottom(300)).toBe(true);
expect(isStuckToBottom(299)).toBe(true);
});
it('is not stuck once past the default threshold', () => {
expect(isStuckToBottom(301)).toBe(false);
expect(isStuckToBottom(2000)).toBe(false);
});
it('honours a custom threshold', () => {
expect(isStuckToBottom(80, 100)).toBe(true);
expect(isStuckToBottom(150, 100)).toBe(false);
});
it('treats negative overscroll distances as stuck', () => {
expect(isStuckToBottom(-20)).toBe(true);
});
});

View File

@@ -42,3 +42,21 @@ export function resolveAutoScrollBehavior(input: AutoScrollDecisionInput): AutoS
return input.withinInitialGrace ? 'instant' : 'smooth';
}
/** Default pixel distance under which the list is considered stuck to bottom. */
export const STICKY_BOTTOM_THRESHOLD = 300;
/**
* Whether the scroll position is close enough to the bottom that the list
* should keep auto-pinning to the latest message. Negative distances (rubber
* band / overscroll) count as stuck.
*
* This is the predicate the message list uses to decide whether a content
* height change (late image/embed/plugin render) should re-pin to bottom.
*/
export function isStuckToBottom(
distanceFromBottom: number,
threshold: number = STICKY_BOTTOM_THRESHOLD
): boolean {
return distanceFromBottom <= threshold;
}