mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
Fix native chat anchoring while streaming
This commit is contained in:
@@ -608,6 +608,47 @@ describe("bottom anchor controller driver", () => {
|
||||
|
||||
expect(harness.driver.getSnapshot().mode).toBe("sticky-bottom");
|
||||
});
|
||||
|
||||
it("keeps native sticky content changes anchored when measured height is unchanged", () => {
|
||||
const harness = createDriverHarness({
|
||||
transportBehavior: {
|
||||
verificationDelayFrames: 2,
|
||||
verificationRetryMode: "recheck",
|
||||
},
|
||||
measurementState: createMeasurementState({
|
||||
containerKey: "native-virtualized",
|
||||
viewportWidth: 390,
|
||||
viewportHeight: 546,
|
||||
contentHeight: 546,
|
||||
offsetY: 0,
|
||||
viewportMeasuredForKey: "native-virtualized",
|
||||
contentMeasuredForKey: "native-virtualized",
|
||||
}),
|
||||
});
|
||||
harness.scrollToBottom.mockImplementation(() => {
|
||||
harness.context.measurementState.offsetY = 0;
|
||||
harness.context.nearBottom = true;
|
||||
});
|
||||
|
||||
harness.driver.prepareForStickyContentChange();
|
||||
|
||||
expect(harness.scrollToBottom).toHaveBeenCalledTimes(1);
|
||||
expect(harness.driver.getSnapshot()).toMatchObject({
|
||||
mode: "sticky-bottom",
|
||||
pendingVerification: {
|
||||
requestId: null,
|
||||
},
|
||||
});
|
||||
|
||||
harness.context.measurementState.offsetY = 50;
|
||||
harness.context.nearBottom = false;
|
||||
harness.driver.handleScrollNearBottomChange({
|
||||
nextIsNearBottom: false,
|
||||
scrollDelta: 50,
|
||||
});
|
||||
|
||||
expect(harness.driver.getSnapshot().mode).toBe("sticky-bottom");
|
||||
});
|
||||
});
|
||||
|
||||
describe("controller helper predicates", () => {
|
||||
|
||||
@@ -244,29 +244,6 @@ function createBottomAnchorControllerDriver(
|
||||
let stickyMeasurementRevision = 0;
|
||||
let lastVerifiedStickyMeasurementRevision = 0;
|
||||
|
||||
const _getLogContext = (extra?: Record<string, unknown>) => {
|
||||
const measurementState = input.getMeasurementState();
|
||||
const distanceFromBottom = Math.max(
|
||||
0,
|
||||
measurementState.contentHeight - (measurementState.offsetY + measurementState.viewportHeight),
|
||||
);
|
||||
return {
|
||||
agentId: input.getAgentId(),
|
||||
requestReason: pendingRequest?.reason ?? null,
|
||||
authoritativeHistoryReady: input.getIsAuthoritativeHistoryReady(),
|
||||
contentHeight: measurementState.contentHeight,
|
||||
viewportHeight: measurementState.viewportHeight,
|
||||
offset: measurementState.offsetY,
|
||||
distanceFromBottom,
|
||||
renderStrategy: input.getRenderStrategy(),
|
||||
blockedReason,
|
||||
mode,
|
||||
containerKey: measurementState.containerKey,
|
||||
transportBehavior: input.getTransportBehavior(),
|
||||
...extra,
|
||||
};
|
||||
};
|
||||
|
||||
const setBlockedReason = (nextBlockedReason: BottomAnchorBlockedReason | null) => {
|
||||
if (blockedReason === nextBlockedReason) {
|
||||
return;
|
||||
@@ -327,7 +304,6 @@ function createBottomAnchorControllerDriver(
|
||||
});
|
||||
|
||||
const scheduleVerification = (attemptContext: AttemptContext, delayFramesOverride?: number) => {
|
||||
const _scheduledMeasurementState = input.getMeasurementState();
|
||||
if (verificationHandle) {
|
||||
input.cancelFrame(verificationHandle);
|
||||
}
|
||||
@@ -582,6 +558,16 @@ function createBottomAnchorControllerDriver(
|
||||
return;
|
||||
}
|
||||
markStickyMeasurementChanged();
|
||||
if (!pendingRequest) {
|
||||
pendingVerification = { requestId: null, retries: 0 };
|
||||
if (attemptHandle) {
|
||||
input.cancelFrame(attemptHandle);
|
||||
attemptHandle = null;
|
||||
}
|
||||
runAttempt(false);
|
||||
return;
|
||||
}
|
||||
evaluate(false, "content_size_change");
|
||||
},
|
||||
handleScrollNearBottomChange(params) {
|
||||
const { nextIsNearBottom, scrollDelta } = params;
|
||||
|
||||
Reference in New Issue
Block a user