mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(web): require user intent to cancel initial scroll (#1291)
* fix(web): require user intent to cancel initial scroll * fix(web): snapshot scroll intent before consumption
This commit is contained in:
@@ -200,7 +200,18 @@ describe('scroll anchor helpers', () => {
|
||||
distanceFromBottom: 182,
|
||||
isScrollingUp: true
|
||||
})
|
||||
expect(shouldCancelInitialScrollSettling(intent)).toBe(true)
|
||||
expect(shouldCancelInitialScrollSettling(intent, true)).toBe(true)
|
||||
})
|
||||
|
||||
it('keeps initial scroll settling for programmatic upward movement', () => {
|
||||
const intent = getScrollIntent({
|
||||
scrollTop: 0,
|
||||
previousScrollTop: 700,
|
||||
scrollHeight: 1232,
|
||||
clientHeight: 530
|
||||
})
|
||||
|
||||
expect(shouldCancelInitialScrollSettling(intent, false)).toBe(false)
|
||||
})
|
||||
|
||||
it('keeps initial scroll settling for negligible movement at the bottom', () => {
|
||||
@@ -215,7 +226,7 @@ describe('scroll anchor helpers', () => {
|
||||
distanceFromBottom: 0,
|
||||
isScrollingUp: false
|
||||
})
|
||||
expect(shouldCancelInitialScrollSettling(intent)).toBe(false)
|
||||
expect(shouldCancelInitialScrollSettling(intent, false)).toBe(false)
|
||||
})
|
||||
|
||||
it('restores the captured message to the same viewport offset', () => {
|
||||
|
||||
@@ -158,8 +158,13 @@ export function getScrollIntent(params: {
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldCancelInitialScrollSettling(intent: ScrollIntent): boolean {
|
||||
return intent.isScrollingUp && intent.distanceFromBottom > MANUAL_SCROLL_EPSILON_PX
|
||||
export function shouldCancelInitialScrollSettling(
|
||||
intent: ScrollIntent,
|
||||
hasExplicitUpwardIntent: boolean
|
||||
): boolean {
|
||||
return hasExplicitUpwardIntent
|
||||
&& intent.isScrollingUp
|
||||
&& intent.distanceFromBottom > MANUAL_SCROLL_EPSILON_PX
|
||||
}
|
||||
|
||||
export function captureScrollAnchor(viewport: HTMLElement): ScrollAnchor | null {
|
||||
@@ -608,8 +613,16 @@ export function HappyThread(props: {
|
||||
let wheelIntentUntil = 0
|
||||
let wheelLatched = false
|
||||
|
||||
const hasExplicitUpwardIntent = (intent: ScrollIntent): boolean => {
|
||||
return intent.isScrollingUp && (
|
||||
pointerResumeActive
|
||||
|| keyboardResumeUntil >= Date.now()
|
||||
|| wheelIntentUntil >= Date.now()
|
||||
)
|
||||
}
|
||||
|
||||
const consumeExplicitUpwardIntent = (intent: ScrollIntent): boolean => {
|
||||
if (!intent.isScrollingUp) {
|
||||
if (!hasExplicitUpwardIntent(intent)) {
|
||||
return false
|
||||
}
|
||||
if (pointerResumeActive && !pointerResumeLatched) {
|
||||
@@ -658,10 +671,11 @@ export function HappyThread(props: {
|
||||
// Keep the keyboard/pointer intent armed while the user moves
|
||||
// through ordinary history. Consume it only when the viewport
|
||||
// actually reaches the preload area.
|
||||
const hadExplicitUpwardIntent = hasExplicitUpwardIntent(intent)
|
||||
const explicitUpwardIntent = needsCoverage && consumeExplicitUpwardIntent(intent)
|
||||
|
||||
if (isInitialScrollSettling()) {
|
||||
if (shouldCancelInitialScrollSettling(intent)) {
|
||||
if (shouldCancelInitialScrollSettling(intent, hadExplicitUpwardIntent)) {
|
||||
initialScrollDeadlineRef.current = 0
|
||||
clearInitialScrollTimers()
|
||||
setAutoScrollMode(false)
|
||||
|
||||
Reference in New Issue
Block a user