diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt index d248ef2a04..aeddaaa4e9 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt @@ -33,17 +33,17 @@ open class GestureHandler { private set // Host detector view is a reference to a Native Detector designated to handle events from a - // Logic Detector to which the gesture is assigned. + // Virtual Detector to which the gesture is assigned. var hostDetectorView: RNGestureHandlerDetectorView? = null val viewForEvents: RNGestureHandlerDetectorView get() { - assert(usesNativeOrLogicDetector(actionType)) { + assert(usesNativeOrVirtualDetector(actionType)) { "[react-native-gesture-handler] `viewForEvents` can only be used with NativeDetector." } val detector = if (actionType == - ACTION_TYPE_LOGIC_DETECTOR + ACTION_TYPE_VIRTUAL_DETECTOR ) { this.hostDetectorView } else if (this is NativeViewGestureHandler) { @@ -1020,7 +1020,7 @@ open class GestureHandler { const val ACTION_TYPE_JS_FUNCTION_OLD_API = 3 const val ACTION_TYPE_JS_FUNCTION_NEW_API = 4 const val ACTION_TYPE_NATIVE_DETECTOR = 5 - const val ACTION_TYPE_LOGIC_DETECTOR = 6 + const val ACTION_TYPE_VIRTUAL_DETECTOR = 6 const val POINTER_TYPE_TOUCH = 0 const val POINTER_TYPE_STYLUS = 1 const val POINTER_TYPE_MOUSE = 2 @@ -1056,8 +1056,8 @@ open class GestureHandler { return null } - fun usesNativeOrLogicDetector(actionType: Int): Boolean = - actionType == ACTION_TYPE_NATIVE_DETECTOR || actionType == ACTION_TYPE_LOGIC_DETECTOR + fun usesNativeOrVirtualDetector(actionType: Int): Boolean = + actionType == ACTION_TYPE_NATIVE_DETECTOR || actionType == ACTION_TYPE_VIRTUAL_DETECTOR } private data class PointerData( diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt index f2f15d9711..0fa3b16dd8 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt @@ -13,12 +13,13 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) { private val reactContext: ThemedReactContext get() = context as ThemedReactContext private var handlersToAttach: List? = null + private var virtualChildrenToAttach: List? = null private var nativeHandlers: MutableSet = mutableSetOf() private var attachedHandlers: MutableSet = mutableSetOf() - private var attachedLogicHandlers: MutableMap> = mutableMapOf() + private var attachedVirtualHandlers: MutableMap> = mutableMapOf() private var moduleId: Int = -1 - data class LogicChildren(val handlerTags: List, val viewTag: Int) + data class VirtualChildren(val handlerTags: List, val viewTag: Int) fun setHandlerTags(handlerTags: ReadableArray?) { val newHandlers = handlerTags?.toArrayList()?.map { (it as Double).toInt() } ?: emptyList() @@ -38,35 +39,21 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) { this.moduleId = id this.attachHandlers(handlersToAttach ?: return) handlersToAttach = null + this.attachVirtualChildren(virtualChildrenToAttach ?: return) + virtualChildrenToAttach = null } - fun setLogicChildren(newLogicChildren: ReadableArray?) { - val logicChildrenToDetach = attachedLogicHandlers.keys.toMutableSet() + fun setVirtualChildren(newVirtualChildren: ReadableArray?) { + val mappedChildren = newVirtualChildren?.mapVirtualChildren().orEmpty() - val mappedChildren = newLogicChildren?.mapLogicChildren().orEmpty() - - for (child in mappedChildren) { - if (!attachedLogicHandlers.containsKey(child.viewTag)) { - attachedLogicHandlers[child.viewTag] = mutableSetOf() - } - - logicChildrenToDetach.remove(child.viewTag) - - attachHandlers( - child.handlerTags, - child.viewTag, - GestureHandler.ACTION_TYPE_LOGIC_DETECTOR, - attachedLogicHandlers[child.viewTag]!!, - ) + if (moduleId == -1) { + // It's possible that handlerTags will be set before module id. In that case, store + // the handler ids and attach them after setting module id. + virtualChildrenToAttach = mappedChildren + return } - val registry = RNGestureHandlerModule.registries[moduleId] - ?: throw Exception("Tried to access a non-existent registry") - - for (tag in logicChildrenToDetach) { - registry.detachHandler(tag) - attachedLogicHandlers.remove(tag) - } + attachVirtualChildren(mappedChildren) } private fun shouldAttachGestureToChildView(tag: Int): Boolean { @@ -109,7 +96,7 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) { nativeHandlers.add(tag) } else { registry.attachHandlerToView(tag, viewTag, actionType) - if (actionType == GestureHandler.ACTION_TYPE_LOGIC_DETECTOR) { + if (actionType == GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR) { registry.getHandler(tag)?.hostDetectorView = this } attachedHandlers.add(tag) @@ -131,6 +118,32 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) { } } + private fun attachVirtualChildren(virtualChildrenToAttach: List) { + val virtualChildrenToDetach = attachedVirtualHandlers.keys.toMutableSet() + + for (child in virtualChildrenToAttach) { + if (!attachedVirtualHandlers.containsKey(child.viewTag)) { + attachedVirtualHandlers[child.viewTag] = mutableSetOf() + } + + virtualChildrenToDetach.remove(child.viewTag) + attachHandlers( + child.handlerTags, + child.viewTag, + GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR, + attachedVirtualHandlers[child.viewTag]!!, + ) + } + + val registry = RNGestureHandlerModule.registries[moduleId] + ?: throw Exception("Tried to access a non-existent registry") + + for (tag in virtualChildrenToDetach) { + registry.detachHandler(tag) + attachedVirtualHandlers.remove(tag) + } + } + private fun tryAttachNativeHandlersToChildView(childId: Int) { val registry = RNGestureHandlerModule.registries[moduleId] ?: throw Exception("Tried to access a non-existent registry") @@ -166,7 +179,7 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) { attachedHandlers.remove(tag) } - for (child in attachedLogicHandlers) { + for (child in attachedVirtualHandlers) { for (tag in child.value) { registry.detachHandler(tag) } @@ -174,12 +187,12 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) { } } - private fun ReadableArray.mapLogicChildren(): List = List(size()) { i -> + private fun ReadableArray.mapVirtualChildren(): List = List(size()) { i -> val child = getMap(i) ?: return@List null val handlerTags = child.getArray("handlerTags")?.toIntList().orEmpty() val viewTag = child.getInt("viewTag") - LogicChildren(handlerTags, viewTag) + VirtualChildren(handlerTags, viewTag) }.filterNotNull() private fun ReadableArray.toIntList(): List = List(size()) { getInt(it) } diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorViewManager.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorViewManager.kt index c8f4cb82d1..df898219d8 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorViewManager.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorViewManager.kt @@ -37,8 +37,8 @@ class RNGestureHandlerDetectorViewManager : view.setModuleId(value) } - override fun setLogicChildren(view: RNGestureHandlerDetectorView, value: ReadableArray?) { - view.setLogicChildren(value) + override fun setVirtualChildren(view: RNGestureHandlerDetectorView, value: ReadableArray?) { + view.setVirtualChildren(value) } override fun onDropViewInstance(view: RNGestureHandlerDetectorView) { diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerEvent.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerEvent.kt index 87917ef0bb..80966e6b20 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerEvent.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerEvent.kt @@ -20,7 +20,7 @@ class RNGestureHandlerEvent private constructor() : Event dataBuilder: GestureHandlerEventDataBuilder, eventHandlerType: EventHandlerType, ) { - val view = if (GestureHandler.usesNativeOrLogicDetector(handler.actionType)) { + val view = if (GestureHandler.usesNativeOrVirtualDetector(handler.actionType)) { handler.viewForEvents } else { handler.view!! @@ -39,7 +39,7 @@ class RNGestureHandlerEvent private constructor() : Event EVENTS_POOL.release(this) } - override fun getEventName() = if (GestureHandler.usesNativeOrLogicDetector(actionType)) { + override fun getEventName() = if (GestureHandler.usesNativeOrVirtualDetector(actionType)) { if (eventHandlerType == EventHandlerType.ForAnimated) { NATIVE_DETECTOR_ANIMATED_EVENT_NAME } else if (eventHandlerType == EventHandlerType.ForReanimated) { @@ -54,11 +54,11 @@ class RNGestureHandlerEvent private constructor() : Event } // Unfortunately getCoalescingKey is not considered when sending event to C++, therefore we have to disable coalescing in v3 - override fun canCoalesce() = !GestureHandler.usesNativeOrLogicDetector(actionType) + override fun canCoalesce() = !GestureHandler.usesNativeOrVirtualDetector(actionType) override fun getCoalescingKey() = coalescingKey - override fun getEventData(): WritableMap = if (GestureHandler.usesNativeOrLogicDetector(actionType)) { + override fun getEventData(): WritableMap = if (GestureHandler.usesNativeOrVirtualDetector(actionType)) { createNativeEventData(dataBuilder!!) } else { createEventData(dataBuilder!!) diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerEventDispatcher.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerEventDispatcher.kt index 731818578b..bcd04de546 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerEventDispatcher.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerEventDispatcher.kt @@ -71,7 +71,7 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React RNGestureHandlerEvent.createEventData(handlerFactory.createEventBuilder(handler)) sendEventForDeviceEvent(RNGestureHandlerEvent.EVENT_NAME, data) } - GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_LOGIC_DETECTOR -> { + GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR -> { val eventHandlerType = if (handler.dispatchesAnimatedEvents) { EventHandlerType.ForAnimated } else if (handler.dispatchesReanimatedEvents) { @@ -136,7 +136,7 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React sendEventForDeviceEvent(RNGestureHandlerStateChangeEvent.EVENT_NAME, data) } - GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_LOGIC_DETECTOR -> { + GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR -> { val eventHandlerType = if (handler.dispatchesReanimatedEvents) { EventHandlerType.ForReanimated } else { @@ -188,7 +188,7 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React val data = RNGestureHandlerTouchEvent.createEventData(handler) sendEventForDeviceEvent(RNGestureHandlerEvent.EVENT_NAME, data) } - GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_LOGIC_DETECTOR -> { + GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR -> { val eventHandlerType = if (handler.dispatchesReanimatedEvents) { EventHandlerType.ForReanimated } else { diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerStateChangeEvent.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerStateChangeEvent.kt index d04b337fb8..0f7b55c09d 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerStateChangeEvent.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerStateChangeEvent.kt @@ -23,7 +23,7 @@ class RNGestureHandlerStateChangeEvent private constructor() : Event, eventHandlerType: EventHandlerType, ) { - val view = if (GestureHandler.usesNativeOrLogicDetector(handler.actionType)) { + val view = if (GestureHandler.usesNativeOrVirtualDetector(handler.actionType)) { handler.viewForEvents } else { handler.view!! @@ -45,7 +45,7 @@ class RNGestureHandlerStateChangeEvent private constructor() : Event init(handler: T, actionType: Int, eventHandlerType: EventHandlerType) { - val view = if (GestureHandler.usesNativeOrLogicDetector(handler.actionType)) { + val view = if (GestureHandler.usesNativeOrVirtualDetector(handler.actionType)) { handler.viewForEvents } else { handler.view!! @@ -33,13 +33,13 @@ class RNGestureHandlerTouchEvent private constructor() : Event @property (nonatomic, nonnull) NSMutableSet *nativeHandlers; @property (nonatomic, nonnull) NSMutableSet *attachedHandlers; -@property (nonatomic) std::unordered_map attachedLogicHandlers; +@property (nonatomic) std::unordered_map attachedVirtualHandlers; @end @@ -56,12 +56,12 @@ - (void)willMoveToWindow:(RNGHWindow *)newWindow NSNumber *handlerTag = [NSNumber numberWithInt:handler]; [handlerManager.registry detachHandlerWithTag:handlerTag]; } - for (const auto &child : _attachedLogicHandlers) { + for (const auto &child : _attachedVirtualHandlers) { for (id handlerTag : child.second) { [handlerManager.registry detachHandlerWithTag:handlerTag]; } } - _attachedLogicHandlers.clear(); + _attachedVirtualHandlers.clear(); _attachedHandlers = [NSMutableSet set]; } else { const auto &props = *std::static_pointer_cast(_props); @@ -176,13 +176,13 @@ - (void)attachHandlers:(const std::vector &)handlerTags // case we cannot attach `NativeViewGestureHandlers` here and we have to do it in `didAddSubview` method. [_nativeHandlers addObject:@(tag)]; } else { - if (actionType == RNGestureHandlerActionTypeLogicDetector) { + if (actionType == RNGestureHandlerActionTypeVirtualDetector) { RNGHUIView *targetView = [handlerManager viewForReactTag:@(viewTag)]; if (targetView != nil) { [handlerManager attachGestureHandler:@(tag) toViewWithTag:@(viewTag) withActionType:actionType]; } else { - // Let's assume that if the native view for the logic detector hasn't been found, the hierarchy was folded + // Let's assume that if the native view for the virtual detector hasn't been found, the hierarchy was folded // into a single UIView. [handlerManager.registry attachHandlerWithTag:@(tag) toView:self withActionType:actionType]; [[handlerManager registry] handlerWithTag:@(tag)].virtualViewTag = @(viewTag); @@ -219,37 +219,37 @@ - (void)updateProps:(const Props::Shared &)propsBase oldProps:(const Props::Shar attachedHandlers:_attachedHandlers]; [super updateProps:propsBase oldProps:oldPropsBase]; - [self updateLogicChildren:newProps.logicChildren]; + [self updateVirtualChildren:newProps.virtualChildren]; // Override to force hittesting to work outside bounds self.clipsToBounds = NO; } -- (void)updateLogicChildren:(const std::vector &)logicChildren +- (void)updateVirtualChildren:(const std::vector &)virtualChildren { RNGestureHandlerManager *handlerManager = [RNGestureHandlerModule handlerManagerForModuleId:_moduleId]; react_native_assert(handlerManager != nullptr && "Tried to access a non-existent handler manager") - NSMutableSet *logicChildrenToDetach = [NSMutableSet set]; - for (const auto &child : _attachedLogicHandlers) { - [logicChildrenToDetach addObject:@(child.first)]; + NSMutableSet *virtualChildrenToDetach = [NSMutableSet set]; + for (const auto &child : _attachedVirtualHandlers) { + [virtualChildrenToDetach addObject:@(child.first)]; } - for (const auto &child : logicChildren) { - if (_attachedLogicHandlers.find(child.viewTag) == _attachedLogicHandlers.end()) { - _attachedLogicHandlers[child.viewTag] = [NSMutableSet set]; + for (const auto &child : virtualChildren) { + if (_attachedVirtualHandlers.find(child.viewTag) == _attachedVirtualHandlers.end()) { + _attachedVirtualHandlers[child.viewTag] = [NSMutableSet set]; } - [logicChildrenToDetach removeObject:@(child.viewTag)]; + [virtualChildrenToDetach removeObject:@(child.viewTag)]; [self attachHandlers:child.handlerTags - actionType:RNGestureHandlerActionTypeLogicDetector + actionType:RNGestureHandlerActionTypeVirtualDetector viewTag:child.viewTag - attachedHandlers:_attachedLogicHandlers[child.viewTag]]; + attachedHandlers:_attachedVirtualHandlers[child.viewTag]]; } - for (const NSNumber *tag : logicChildrenToDetach) { - for (id handlerTag : _attachedLogicHandlers[tag.intValue]) { + for (const NSNumber *tag : virtualChildrenToDetach) { + for (id handlerTag : _attachedVirtualHandlers[tag.intValue]) { [handlerManager.registry detachHandlerWithTag:handlerTag]; } } diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm index d206ddeb85..674db9a6c1 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm @@ -295,20 +295,20 @@ - (void)sendEvent:(RNGestureHandlerStateChange *)event // but results in a compilation error. { switch (actionType) { - case RNGestureHandlerActionTypeLogicDetector: { + case RNGestureHandlerActionTypeVirtualDetector: { NSNumber *hostDetectorTag = [_registry handlerWithTag:event.handlerTag].hostDetectorTag; detectorView = [self viewForReactTag:hostDetectorTag]; - [self sendNativeOrLogicEvent:event - withActionType:actionType - forHandlerType:eventHandlerType - forView:detectorView]; + [self sendNativeOrVirtualEvent:event + withActionType:actionType + forHandlerType:eventHandlerType + forView:detectorView]; break; } case RNGestureHandlerActionTypeNativeDetector: { - [self sendNativeOrLogicEvent:event - withActionType:actionType - forHandlerType:eventHandlerType - forView:detectorView]; + [self sendNativeOrVirtualEvent:event + withActionType:actionType + forHandlerType:eventHandlerType + forView:detectorView]; break; } @@ -455,10 +455,10 @@ - (void)sendEventForDeviceEvent:(RNGestureHandlerStateChange *)event [_eventDispatcher sendDeviceEventWithName:@"onGestureHandlerStateChange" body:body]; } -- (void)sendNativeOrLogicEvent:(RNGestureHandlerStateChange *)event - withActionType:(RNGestureHandlerActionType)actionType - forHandlerType:(RNGestureHandlerEventHandlerType)eventHandlerType - forView:(RNGHUIView *)detectorView +- (void)sendNativeOrVirtualEvent:(RNGestureHandlerStateChange *)event + withActionType:(RNGestureHandlerActionType)actionType + forHandlerType:(RNGestureHandlerEventHandlerType)eventHandlerType + forView:(RNGHUIView *)detectorView { if ([event isKindOfClass:[RNGestureHandlerEvent class]]) { switch (eventHandlerType) { diff --git a/packages/react-native-gesture-handler/src/ActionType.ts b/packages/react-native-gesture-handler/src/ActionType.ts index ced70acdfc..10391e17bf 100644 --- a/packages/react-native-gesture-handler/src/ActionType.ts +++ b/packages/react-native-gesture-handler/src/ActionType.ts @@ -4,17 +4,17 @@ export const ActionType = { JS_FUNCTION_OLD_API: 3, JS_FUNCTION_NEW_API: 4, NATIVE_DETECTOR: 5, - LOGIC_DETECTOR: 6, + VIRTUAL_DETECTOR: 6, } as const; // eslint-disable-next-line @typescript-eslint/no-redeclare -- backward compatibility; it can be used as a type and as a value export type ActionType = (typeof ActionType)[keyof typeof ActionType]; -export function usesNativeOrLogicDetector( +export function usesNativeOrVirtualDetector( actionType: ActionType | null ): boolean { return ( actionType === ActionType.NATIVE_DETECTOR || - actionType === ActionType.LOGIC_DETECTOR + actionType === ActionType.VIRTUAL_DETECTOR ); } diff --git a/packages/react-native-gesture-handler/src/specs/RNGestureHandlerDetectorNativeComponent.ts b/packages/react-native-gesture-handler/src/specs/RNGestureHandlerDetectorNativeComponent.ts index b48fa90821..c14f734d80 100644 --- a/packages/react-native-gesture-handler/src/specs/RNGestureHandlerDetectorNativeComponent.ts +++ b/packages/react-native-gesture-handler/src/specs/RNGestureHandlerDetectorNativeComponent.ts @@ -42,7 +42,7 @@ type GestureHandlerTouchEvent = Readonly<{ pointerType: Int32; }>; -export interface LogicChildrenProps { +export interface VirtualChildrenProps { handlerTags: Int32[]; viewTag: Int32; } @@ -58,7 +58,7 @@ export interface NativeProps extends ViewProps { handlerTags: Int32[]; moduleId: Int32; - logicChildren: LogicChildrenProps[]; + virtualChildren: VirtualChildrenProps[]; } export default codegenNativeComponent('RNGestureHandlerDetector', { diff --git a/packages/react-native-gesture-handler/src/v3/detectors/GestureDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/GestureDetector.tsx index ba4d468a11..ae93cd8022 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/GestureDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/GestureDetector.tsx @@ -6,8 +6,8 @@ import { GestureDetectorProps as LegacyGestureDetectorProps, GestureDetector as LegacyGestureDetector, } from '../../handlers/gestures/GestureDetector'; -import { DetectorContext } from './LogicDetector/useDetectorContext'; -import { LogicDetector } from './LogicDetector/LogicDetector'; +import { DetectorContext } from './VirtualDetector/useDetectorContext'; +import { VirtualDetector } from './VirtualDetector/VirtualDetector'; import { use } from 'react'; export function GestureDetector( @@ -22,7 +22,9 @@ export function GestureDetector( const context = use(DetectorContext); return context ? ( - )} /> + )} + /> ) : ( )} diff --git a/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.web.tsx b/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.web.tsx index 00115f2e87..68d4f41fbe 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.web.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.web.tsx @@ -9,10 +9,10 @@ export interface GestureHandlerDetectorProps extends PropsRef { handlerTags: number[]; moduleId: number; children?: React.ReactNode; - logicChildren?: Set; + virtualChildren?: Set; } -export interface LogicChildrenWeb { +export interface VirtualChildrenWeb { viewTag: number; handlerTags: number[]; viewRef: RefObject; @@ -27,7 +27,7 @@ const HostGestureDetector = (props: GestureHandlerDetectorProps) => { const propsRef = useRef(props); const attachedHandlers = useRef>(new Set()); const attachedNativeHandlers = useRef>(new Set()); - const attachedLogicHandlers = useRef>>(new Map()); + const attachedVirtualHandlers = useRef>>(new Map()); const detachHandlers = ( currentHandlerTags: Set, @@ -98,47 +98,47 @@ const HostGestureDetector = (props: GestureHandlerDetectorProps) => { return () => { detachHandlers(EMPTY_HANDLERS, attachedHandlers.current); - attachedLogicHandlers?.current.forEach((childHandlerTags) => { + attachedVirtualHandlers?.current.forEach((childHandlerTags) => { detachHandlers(EMPTY_HANDLERS, childHandlerTags); }); }; }, [handlerTags, children]); useEffect(() => { - const logicChildrenToDetach: Set = new Set( - attachedLogicHandlers.current.keys() + const virtualChildrenToDetach: Set = new Set( + attachedVirtualHandlers.current.keys() ); - props.logicChildren?.forEach((child) => { + props.virtualChildren?.forEach((child) => { if (child.viewRef.current == null) { // We must check whether viewRef is not null as otherwise we get an error when intercepting gesture detector // switches its component based on whether animated/reanimated events should run. return; } - if (!attachedLogicHandlers.current.has(child.viewTag)) { - attachedLogicHandlers.current.set(child.viewTag, new Set()); + if (!attachedVirtualHandlers.current.has(child.viewTag)) { + attachedVirtualHandlers.current.set(child.viewTag, new Set()); } - logicChildrenToDetach.delete(child.viewTag); + virtualChildrenToDetach.delete(child.viewTag); const currentHandlerTags = new Set(child.handlerTags); detachHandlers( currentHandlerTags, - attachedLogicHandlers.current.get(child.viewTag)! + attachedVirtualHandlers.current.get(child.viewTag)! ); attachHandlers( child.viewRef, propsRef, currentHandlerTags, - attachedLogicHandlers.current.get(child.viewTag)!, - ActionType.LOGIC_DETECTOR + attachedVirtualHandlers.current.get(child.viewTag)!, + ActionType.VIRTUAL_DETECTOR ); }); - logicChildrenToDetach.forEach((tag) => { - detachHandlers(EMPTY_HANDLERS, attachedLogicHandlers.current.get(tag)!); + virtualChildrenToDetach.forEach((tag) => { + detachHandlers(EMPTY_HANDLERS, attachedVirtualHandlers.current.get(tag)!); }); - }, [props.logicChildren]); + }, [props.virtualChildren]); return ( }> diff --git a/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/InterceptingGestureDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx similarity index 90% rename from packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/InterceptingGestureDetector.tsx rename to packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx index 4f71860b57..83ec28be86 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/InterceptingGestureDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx @@ -1,7 +1,7 @@ import React, { RefObject, useCallback, useRef, useState } from 'react'; import HostGestureDetector from '../HostGestureDetector'; import { - LogicChildren, + VirtualChildren, GestureHandlerEvent, DetectorCallbacks, } from '../../types'; @@ -21,9 +21,9 @@ export function InterceptingGestureDetector({ gesture, children, }: InterceptingGestureDetectorProps) { - const [logicChildren, setLogicChildren] = useState([]); + const [virtualChildren, setVirtualChildren] = useState([]); - const logicMethods = useRef< + const virtualMethods = useRef< Map>> >(new Map()); @@ -42,7 +42,7 @@ export function InterceptingGestureDetector({ const register = useCallback( ( - child: LogicChildren, + child: VirtualChildren, methods: RefObject>, forReanimated: boolean | undefined, forAnimated: boolean | undefined @@ -50,7 +50,7 @@ export function InterceptingGestureDetector({ setShouldUseReanimated(!!forReanimated); setDispatchesAnimatedEvents(!!forAnimated); - setLogicChildren((prev) => { + setVirtualChildren((prev) => { const index = prev.findIndex((c) => c.viewTag === child.viewTag); if (index !== -1) { const updated = [...prev]; @@ -62,7 +62,7 @@ export function InterceptingGestureDetector({ }); child.handlerTags.forEach((tag) => { - logicMethods.current.set(tag, methods); + virtualMethods.current.set(tag, methods); }); }, [] @@ -70,10 +70,10 @@ export function InterceptingGestureDetector({ const unregister = useCallback((childTag: number, handlerTags: number[]) => { handlerTags.forEach((tag) => { - logicMethods.current.delete(tag); + virtualMethods.current.delete(tag); }); - setLogicChildren((prev) => prev.filter((c) => c.viewTag !== childTag)); + setVirtualChildren((prev) => prev.filter((c) => c.viewTag !== childTag)); }, []); // It might happen only with ReanimatedNativeDetector @@ -91,7 +91,7 @@ export function InterceptingGestureDetector({ gesture.detectorCallbacks[key](e); } - logicMethods.current.forEach((ref) => { + virtualMethods.current.forEach((ref) => { const method = ref.current?.[key]; if (method) { method(e); @@ -112,7 +112,7 @@ export function InterceptingGestureDetector({ ); } - logicMethods.current.forEach((ref) => { + virtualMethods.current.forEach((ref) => { const handler = ref.current?.[key]; if (handler) { handlers.push( @@ -123,7 +123,7 @@ export function InterceptingGestureDetector({ return handlers; }, - [logicChildren, gesture?.detectorCallbacks] + [virtualChildren, gesture?.detectorCallbacks] ); const reanimatedEventHandler = Reanimated?.useComposedEventHandler( @@ -171,7 +171,6 @@ export function InterceptingGestureDetector({ onGestureHandlerReanimatedTouchEvent={ shouldUseReanimated ? reanimatedTouchEventHandler : undefined } - moduleId={globalThis._RNGH_MODULE_ID} handlerTags={ gesture ? isComposedGesture(gesture) @@ -180,7 +179,8 @@ export function InterceptingGestureDetector({ : [] } style={nativeDetectorStyles.detector} - logicChildren={logicChildren}> + virtualChildren={virtualChildren} + moduleId={globalThis._RNGH_MODULE_ID}> {children} diff --git a/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/LogicDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/VirtualDetector.tsx similarity index 80% rename from packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/LogicDetector.tsx rename to packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/VirtualDetector.tsx index 798769c2ee..ba1b9b68a8 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/LogicDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/VirtualDetector.tsx @@ -8,14 +8,14 @@ import { configureRelations } from '../utils'; import { tagMessage } from '../../../utils'; import { DetectorCallbacks } from '../../types'; -export function LogicDetector( +export function VirtualDetector( props: NativeDetectorProps ) { const context = useDetectorContext(); if (!context) { throw new Error( tagMessage( - 'Logic detector must be a descendant of an InterceptingGestureDecector' + 'Virtual detector must be a descendant of an InterceptingGestureDecector' ) ); } @@ -23,7 +23,7 @@ export function LogicDetector( const viewRef = useRef(null); const [viewTag, setViewTag] = useState(-1); - const logicMethods = useRef(props.gesture.detectorCallbacks); + const virtualMethods = useRef(props.gesture.detectorCallbacks); const handleRef = useCallback((node: any) => { viewRef.current = node; if (!node) { @@ -41,7 +41,7 @@ export function LogicDetector( }, []); useEffect(() => { - logicMethods.current = props.gesture.detectorCallbacks; + virtualMethods.current = props.gesture.detectorCallbacks; }, [props.gesture.detectorCallbacks]); useEffect(() => { @@ -53,18 +53,18 @@ export function LogicDetector( ? props.gesture.tags : [props.gesture.tag]; - const logicProps = { + const virtualProps = { viewTag, handlerTags, }; if (Platform.OS === 'web') { - Object.assign(logicProps, { viewRef }); + Object.assign(virtualProps, { viewRef }); } register( - logicProps, - logicMethods as RefObject>, + virtualProps, + virtualMethods as RefObject>, props.gesture.config.shouldUseReanimatedDetector, props.gesture.config.dispatchesAnimatedEvents ); diff --git a/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/useDetectorContext.ts b/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/useDetectorContext.ts similarity index 84% rename from packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/useDetectorContext.ts rename to packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/useDetectorContext.ts index 016f36cd84..2eecca7129 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/useDetectorContext.ts +++ b/packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/useDetectorContext.ts @@ -1,9 +1,9 @@ import { createContext, RefObject, use } from 'react'; -import { DetectorCallbacks, LogicChildren } from '../../types'; +import { DetectorCallbacks, VirtualChildren } from '../../types'; type DetectorContextType = { register: ( - child: LogicChildren, + child: VirtualChildren, methods: RefObject>, forReanimated: boolean | undefined, forAnimated: boolean | undefined diff --git a/packages/react-native-gesture-handler/src/v3/detectors/index.ts b/packages/react-native-gesture-handler/src/v3/detectors/index.ts index c2fc0375e5..f2242a697f 100644 --- a/packages/react-native-gesture-handler/src/v3/detectors/index.ts +++ b/packages/react-native-gesture-handler/src/v3/detectors/index.ts @@ -1,3 +1,3 @@ export type { GestureDetectorProps } from './common'; export { GestureDetector } from './GestureDetector'; -export { InterceptingGestureDetector } from './LogicDetector/InterceptingGestureDetector'; +export { InterceptingGestureDetector } from './VirtualDetector/InterceptingGestureDetector'; diff --git a/packages/react-native-gesture-handler/src/v3/types/DetectorTypes.ts b/packages/react-native-gesture-handler/src/v3/types/DetectorTypes.ts index c9368b778b..a14fd365cc 100644 --- a/packages/react-native-gesture-handler/src/v3/types/DetectorTypes.ts +++ b/packages/react-native-gesture-handler/src/v3/types/DetectorTypes.ts @@ -21,7 +21,7 @@ export type DetectorCallbacks = { onGestureHandlerAnimatedEvent: undefined | AnimatedEvent; }; -export type LogicChildren = { +export type VirtualChildren = { viewTag: number; handlerTags: number[]; }; diff --git a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts index 23f4560369..1f89bdc3f8 100644 --- a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts +++ b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts @@ -24,7 +24,7 @@ import { } from '../../handlers/gestureHandlerCommon'; import { PointerType } from '../../PointerType'; import { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate'; -import { ActionType, usesNativeOrLogicDetector } from '../../ActionType'; +import { ActionType, usesNativeOrVirtualDetector } from '../../ActionType'; import { tagMessage } from '../../utils'; import { GestureStateChangeEvent, @@ -401,7 +401,7 @@ export default abstract class GestureHandler implements IGestureHandler { return; } - if (usesNativeOrLogicDetector(this.actionType)) { + if (usesNativeOrVirtualDetector(this.actionType)) { invokeNullableMethod( this.forReanimated ? onGestureHandlerReanimatedTouchEvent @@ -426,7 +426,9 @@ export default abstract class GestureHandler implements IGestureHandler { onGestureHandlerReanimatedStateChange, }: PropsRef = this.propsRef!.current; - const resultEvent: ResultEvent = !usesNativeOrLogicDetector(this.actionType) + const resultEvent: ResultEvent = !usesNativeOrVirtualDetector( + this.actionType + ) ? this.transformEventData(newState, oldState) : this.lastSentState !== newState ? this.transformStateChangeEvent(newState, oldState) @@ -446,7 +448,7 @@ export default abstract class GestureHandler implements IGestureHandler { ); } if (this.state === State.ACTIVE) { - if (!usesNativeOrLogicDetector(this.actionType)) { + if (!usesNativeOrVirtualDetector(this.actionType)) { (resultEvent.nativeEvent as GestureHandlerNativeEvent).oldState = undefined; }