Skip to content

Commit

Permalink
fix(android): slow autoscroll with fabric
Browse files Browse the repository at this point in the history
Fix autoscroll not scrolling enough on Android with Fabric enabled.
Make autoscroll speed more consistent with iOS.
  • Loading branch information
omahili committed Jan 14, 2025
1 parent 04a10f8 commit 0f0f3e4
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/components/ReorderableListCore/ReorderableListCore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from 'react-native-gesture-handler';
import Animated, {SharedValue} from 'react-native-reanimated';

import {AUTOSCROLL_DELAY} from './constants';
import {AUTOSCROLL_CONFIG} from './constants';
import {useReorderableListCore} from './useReorderableListCore';
import {ReorderableListContext} from '../../contexts';
import type {ReorderableListProps} from '../../types';
Expand Down Expand Up @@ -43,7 +43,7 @@ const ReorderableListCore = <T,>(
data,
autoscrollThreshold = 0.1,
autoscrollSpeedScale = 1,
autoscrollDelay = AUTOSCROLL_DELAY,
autoscrollDelay = AUTOSCROLL_CONFIG.delay,
animationDuration = 200,
dragReorderThreshold = 0.2,
onLayout,
Expand Down
3 changes: 0 additions & 3 deletions src/components/ReorderableListCore/constants.ios.ts

This file was deleted.

34 changes: 31 additions & 3 deletions src/components/ReorderableListCore/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
// Default constants
export const AUTOSCROLL_INCREMENT = 5;
export const AUTOSCROLL_DELAY = 0;
import {Platform} from 'react-native';

const IOS_CONFIG = {
delay: 80,
increment: 100,
};

const ANDROID_FABRIC_CONFIG = {
delay: 50,
increment: 80,
};

const ANDROID_PAPER_CONFIG = {
delay: 10,
increment: 4,
};

export const IS_FABRIC =
global && typeof global === 'object' && 'nativeFabricUIManager' in global;

export const AUTOSCROLL_CONFIG = Platform.select({
// autoscroll behaves differently with Fabric and Paper on Android
android: IS_FABRIC ? ANDROID_FABRIC_CONFIG : ANDROID_PAPER_CONFIG,
ios: IOS_CONFIG,

// unsupported platforms
web: IOS_CONFIG,
macos: IOS_CONFIG,
windows: IOS_CONFIG,
native: IOS_CONFIG,
});
19 changes: 8 additions & 11 deletions src/components/ReorderableListCore/useReorderableListCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import Animated, {
AnimatedRef,
Easing,
SharedValue,
cancelAnimation,
runOnJS,
runOnUI,
scrollTo,
Expand All @@ -24,7 +23,7 @@ import Animated, {
withTiming,
} from 'react-native-reanimated';

import {AUTOSCROLL_INCREMENT} from './constants';
import {AUTOSCROLL_CONFIG} from './constants';
import {ReorderableListDragEndEvent, ReorderableListState} from '../../types';
import type {ReorderableListReorderEvent} from '../../types';

Expand Down Expand Up @@ -493,14 +492,14 @@ export const useReorderableListCore = <T>({
) {
setCurrentIndex(y);

if (scrollDirection(y)) {
if (scrollDirection(y) !== 0) {
if (state.value !== ReorderableListState.AUTO_SCROLL) {
// trigger autoscroll
lastAutoscrollTrigger.value = autoscrollTrigger.value;
autoscrollTrigger.value *= -1;
state.value = ReorderableListState.AUTO_SCROLL;
}
state.value = ReorderableListState.AUTO_SCROLL;
} else {
} else if (state.value === ReorderableListState.AUTO_SCROLL) {
state.value = ReorderableListState.DRAGGING;
}
}
Expand All @@ -516,7 +515,9 @@ export const useReorderableListCore = <T>({
) {
let y = currentY.value + scrollViewDragScrollTranslationY.value;
const autoscrollIncrement =
scrollDirection(y) * AUTOSCROLL_INCREMENT * autoscrollSpeedScale;
scrollDirection(y) *
AUTOSCROLL_CONFIG.increment *
autoscrollSpeedScale;

if (autoscrollIncrement !== 0) {
let scrollOffset = flatListScrollOffsetY.value;
Expand Down Expand Up @@ -545,7 +546,7 @@ export const useReorderableListCore = <T>({

// checking if the list is not scrollable instead of the scrolling state
// fixes a bug on iOS where the item is shifted after autoscrolling and then
// moving await from autoscroll area
// moving away from autoscroll area
if (!scrollEnabled.value) {
dragScrollTranslationY.value =
flatListScrollOffsetY.value - dragInitialScrollOffsetY.value;
Expand All @@ -557,8 +558,6 @@ export const useReorderableListCore = <T>({
dragScrollTranslationY.value +
scrollViewDragScrollTranslationY.value;

cancelAnimation(autoscrollTrigger);

lastAutoscrollTrigger.value = autoscrollTrigger.value;
autoscrollTrigger.value = withDelay(
autoscrollDelay,
Expand Down Expand Up @@ -586,8 +585,6 @@ export const useReorderableListCore = <T>({
dragY.value =
currentTranslationY.value + scrollViewDragScrollTranslationY.value;

cancelAnimation(autoscrollTrigger);

lastAutoscrollTrigger.value = autoscrollTrigger.value;
autoscrollTrigger.value = withDelay(
autoscrollDelay,
Expand Down

0 comments on commit 0f0f3e4

Please sign in to comment.