diff --git a/mobile/src/session/native-chat/mobile-native-chat-reading-place.test.tsx b/mobile/src/session/native-chat/mobile-native-chat-reading-place.test.tsx index 82cbaf45e79..296bf73e68c 100644 --- a/mobile/src/session/native-chat/mobile-native-chat-reading-place.test.tsx +++ b/mobile/src/session/native-chat/mobile-native-chat-reading-place.test.tsx @@ -433,6 +433,21 @@ it('holds back a change below a scrolling reader until they rest, then keeps the expect(chat0.scroller.top(mobileNativeChatRowId('m4'))).toBe(line) }) +it('a parked reader stays parked when React Native Web repeats the scroll event of its own correction', () => { + const rows = Array.from({ length: 12 }, (_, i) => say(`m${i}`, i % 2 ? 'assistant' : 'user', 'x')) + const chat0 = mount(rows) + chat0.read(() => chat0.scroller.showFrom(40)) + const line = chat0.scroller.top(mobileNativeChatRowId('m4')) + const n1 = say('n1', 'assistant', 'reply') + chat0.show([...rows, n1]) + chat0.scrolled() + // React Native Web sends the last scroll event again 100 ms after scrolling stops. + chat0.scrolled() + chat0.show([...rows, n1, say('n2', 'assistant', 'more')]) + expect(chat0.drawn(mobileNativeChatRowId('n2'))).toBe(1) + expect(chat0.scroller.top(mobileNativeChatRowId('m4'))).toBe(line) +}) + it('releases a held change once a chat hidden mid-scroll is shown again and the reader rests', () => { const rows = Array.from({ length: 12 }, (_, i) => say(`m${i}`, i % 2 ? 'assistant' : 'user', 'x')) const chat0 = mount(rows) diff --git a/mobile/src/session/native-chat/transcript/MobileNativeChatPageList.tsx b/mobile/src/session/native-chat/transcript/MobileNativeChatPageList.tsx index 27e36d78ac3..2d8d0e526d8 100644 --- a/mobile/src/session/native-chat/transcript/MobileNativeChatPageList.tsx +++ b/mobile/src/session/native-chat/transcript/MobileNativeChatPageList.tsx @@ -361,8 +361,9 @@ export function MobileNativeChatPageList({ return } const byReader = own.current === null || Math.abs(s.scrollTop - own.current) >= 1 - own.current = null + // RN Web repeats the last scroll event 100 ms after scrolling stops; keep our write so that repeat is ours too. if (byReader) { + own.current = null readerScrolledAt.current = Date.now() } onEndDistance(Math.max(0, -s.scrollTop), byReader)