@@ -226,6 +226,7 @@ class DraggableFlatList<T> extends React.Component<Props<T>, State> {
226226
227227 keyToIndex = new Map < string , number > ( ) ;
228228
229+ /** Whether we've sent an incomplete call to the FlatList to do a scroll */
229230 isAutoscrolling = {
230231 native : new Value < number > ( 0 ) ,
231232 js : false
@@ -611,23 +612,49 @@ class DraggableFlatList<T> extends React.Component<Props<T>, State> {
611612 return targetOffset ;
612613 } ;
613614
614- autoscroll = async ( [
615- distFromTop ,
616- distFromBottom ,
617- scrollOffset ,
618- isScrolledUp ,
619- isScrolledDown
620- ] : readonly number [ ] ) => {
621- const targetOffset = this . getScrollTargetOffset (
622- distFromTop ,
623- distFromBottom ,
624- scrollOffset ,
625- ! ! isScrolledUp ,
626- ! ! isScrolledDown
627- ) ;
628- if ( targetOffset >= 0 && this . isPressedIn . js ) {
629- const nextScrollParams = await this . scrollToAsync ( targetOffset ) ;
630- this . autoscroll ( nextScrollParams ) ;
615+ /** Ensure that only 1 call to autoscroll is active at a time */
616+ autoscrollLooping = false ;
617+ autoscroll = async ( params : readonly number [ ] ) => {
618+ if ( this . autoscrollLooping ) {
619+ return ;
620+ }
621+ this . autoscrollLooping = true ;
622+ try {
623+ let shouldScroll = true ;
624+ let curParams = params ;
625+ while ( shouldScroll ) {
626+ const [
627+ distFromTop ,
628+ distFromBottom ,
629+ scrollOffset ,
630+ isScrolledUp ,
631+ isScrolledDown
632+ ] = curParams ;
633+ const targetOffset = this . getScrollTargetOffset (
634+ distFromTop ,
635+ distFromBottom ,
636+ scrollOffset ,
637+ ! ! isScrolledUp ,
638+ ! ! isScrolledDown
639+ ) ;
640+ const scrollingUpAtTop = ! ! (
641+ isScrolledUp && targetOffset <= scrollOffset
642+ ) ;
643+ const scrollingDownAtBottom = ! ! (
644+ isScrolledDown && targetOffset >= scrollOffset
645+ ) ;
646+ shouldScroll =
647+ targetOffset >= 0 &&
648+ this . isPressedIn . js &&
649+ ! scrollingUpAtTop &&
650+ ! scrollingDownAtBottom ;
651+
652+ if ( shouldScroll ) {
653+ curParams = await this . scrollToAsync ( targetOffset ) ;
654+ }
655+ }
656+ } finally {
657+ this . autoscrollLooping = false ;
631658 }
632659 } ;
633660
@@ -669,17 +696,26 @@ class DraggableFlatList<T> extends React.Component<Props<T>, State> {
669696 and (
670697 this . isAutoscrolling . native ,
671698 or (
699+ // We've scrolled to where we want to be
672700 lessOrEq (
673701 abs ( sub ( this . targetScrollOffset , this . scrollOffset ) ) ,
674702 scrollPositionTolerance
675703 ) ,
676- this . isScrolledUp ,
677- this . isScrolledDown
704+ // We're at the start, but still want to scroll farther up
705+ and (
706+ this . isScrolledUp ,
707+ lessOrEq ( this . targetScrollOffset , this . scrollOffset )
708+ ) ,
709+ // We're at the end, but still want to scroll further down
710+ and (
711+ this . isScrolledDown ,
712+ greaterOrEq ( this . targetScrollOffset , this . scrollOffset )
713+ )
678714 )
679715 ) ,
680716 [
717+ // Finish scrolling
681718 set ( this . isAutoscrolling . native , 0 ) ,
682- this . checkAutoscroll ,
683719 call ( this . autoscrollParams , this . onAutoscrollComplete )
684720 ]
685721 )
@@ -779,7 +815,10 @@ class DraggableFlatList<T> extends React.Component<Props<T>, State> {
779815 [ `translate${ horizontal ? "X" : "Y" } ` ] : this
780816 . hoverComponentTranslate
781817 }
782- ]
818+ // We need the cast because the transform array usually accepts
819+ // only specific keys, and we dynamically generate the key
820+ // above
821+ ] as Animated . AnimatedTransform
783822 }
784823 ] }
785824 >
0 commit comments