software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
5.83k stars 952 forks source link

Web `Orchestrator` refactor. #2819

Closed m-bert closed 1 month ago

m-bert commented 1 month ago

Description

While working on #2759 I've decided that it will be good idea to also introduce some changes into web version of orchestrator.

While this PR is mostly a refactor, it also brings other changes, for example it adds awaitingHandlersTags set which is used on android (current implementation was unsafe).

Unfortunately change made in GestureHandler.ts reverts #2802, but it is necessary for orchestration process to work. We will find better way to solve this problem in follow-up PR.

Test plan

Tested on the following code: ```jsx import React from 'react'; import { StyleSheet, View } from 'react-native'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import Animated from 'react-native-reanimated'; const log = (e: any, handler: string) => console.log(`[${e.handlerTag}][${handler}]: ${e.state}`); const orangeTapGesture = Gesture.Tap() .runOnJS(true) .maxDeltaX(5) .onBegin((e) => log(e, 'Orange tap')) .onStart((e) => log(e, 'Orange tap')) .onFinalize((e, success) => { log(e, 'Orange tap'); if (success) { console.log('---> Orange Tap <---'); } }); const orangeDoubleTapGesture = Gesture.Tap() .numberOfTaps(2) .runOnJS(true) .onBegin((e) => log(e, 'Orange Double Tap')) .onStart((e) => log(e, 'Orange Double Tap')) .onFinalize((e, success) => { log(e, 'Orange Double Tap'); if (success) { console.log('---> Orange Double Tap <---'); } }); const blueTapGesture = Gesture.Tap() .runOnJS(true) .requireExternalGestureToFail(orangeTapGesture, orangeDoubleTapGesture) .onBegin((e) => log(e, 'Blue Tap')) .onStart((e) => log(e, 'Blue Tap')) .onFinalize((e, success) => { log(e, 'Blue Tap'); if (success) { console.log('---> Blue Tap <---'); } }); const blueDoubleTapGesture = Gesture.Tap() .numberOfTaps(2) .runOnJS(true) .onBegin((e) => log(e, 'Blue Double Tap')) .onStart((e) => log(e, 'Blue Double Tap')) .onFinalize((e, success) => { log(e, 'Blue Double Tap'); if (success) { console.log('---> Blue Double Tap <---'); } }); const redLongPressGesture = Gesture.LongPress() .runOnJS(true) .onBegin((e) => log(e, 'Red Longpress')) .onStart((e) => log(e, 'Red Longpress')) .onFinalize((e, success) => { log(e, 'Red Longpress'); if (success) { console.log('---> Red Longpress <---'); } }); const redDoubleTapGesture = Gesture.Tap() .numberOfTaps(2) .runOnJS(true) .onBegin((e) => log(e, 'Red Double Tap')) .onStart((e) => log(e, 'Red Double Tap')) .onFinalize((e, success) => { log(e, 'Red Double Tap'); if (success) { console.log('---> Red Double Tap <---'); } }); const Showcase = () => { const gesture = Gesture.Race(redDoubleTapGesture, redLongPressGesture); return ( ); }; export default Showcase; const Blue = () => { const composedGesture = Gesture.Exclusive( blueDoubleTapGesture, blueTapGesture ); return ( ); }; const Orange = () => { const composedGesture = Gesture.Exclusive( orangeDoubleTapGesture, orangeTapGesture ); return ( ); }; const styles = StyleSheet.create({ center: { display: 'flex', justifyContent: 'space-around', alignItems: 'center', }, outer: { backgroundColor: 'red', width: 400, height: 400, borderRadius: 200, }, blue: { width: 250, height: 250, backgroundColor: 'blue', borderRadius: 175, }, orange: { width: 100, height: 100, backgroundColor: 'orange', borderRadius: 50, }, }); ```