@react-native-oh-tpl/react-native-gesture-handler 2.12.9 → 2.14.1-2.14.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. package/DrawerLayout/index.ts +2 -0
  2. package/Swipeable/index.ts +2 -0
  3. package/harmony/gesture_handler/BuildProfile.ets +15 -3
  4. package/harmony/gesture_handler/hvigorfile.ts +1 -1
  5. package/harmony/gesture_handler/index.ets +2 -2
  6. package/harmony/gesture_handler/oh-package-lock.json5 +4 -3
  7. package/harmony/gesture_handler/oh-package.json5 +3 -3
  8. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +64 -18
  9. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +3 -3
  10. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +2 -2
  11. package/harmony/gesture_handler/src/main/cpp/{RNGestureHandlerButtonComponentInstance.h → componentInstances/RNGestureHandlerButtonComponentInstance.h} +2 -2
  12. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +242 -0
  13. package/harmony/gesture_handler/src/main/ets/{GestureHandler.ts → core/GestureHandler.ts} +54 -27
  14. package/harmony/gesture_handler/src/main/ets/{GestureHandlerOrchestrator.ts → core/GestureHandlerOrchestrator.ts} +122 -67
  15. package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +63 -0
  16. package/harmony/gesture_handler/src/main/ets/{Event.ts → core/IncomingEvent.ts} +30 -20
  17. package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
  18. package/harmony/gesture_handler/src/main/ets/{OutgoingEvent.ts → core/OutgoingEvent.ts} +1 -1
  19. package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
  20. package/harmony/gesture_handler/src/main/ets/{PointerTracker.ts → core/PointerTracker.ts} +4 -4
  21. package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
  22. package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
  23. package/harmony/gesture_handler/src/main/ets/{VelocityTracker.ts → core/VelocityTracker.ts} +13 -5
  24. package/harmony/gesture_handler/src/main/ets/core/View.ts +21 -0
  25. package/harmony/gesture_handler/src/main/ets/core/ViewFinder.ts +11 -0
  26. package/harmony/gesture_handler/src/main/ets/core/ViewRegistry.ts +8 -0
  27. package/harmony/gesture_handler/src/main/ets/core/index.ts +15 -0
  28. package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
  29. package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
  30. package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
  31. package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
  32. package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
  33. package/harmony/gesture_handler/src/main/ets/{NativeViewGestureHandler.ts → gesture-handlers/NativeViewGestureHandler.ts} +15 -15
  34. package/harmony/gesture_handler/src/main/ets/{PanGestureHandler.ts → gesture-handlers/PanGestureHandler.ts} +27 -13
  35. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
  36. package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
  37. package/harmony/gesture_handler/src/main/ets/{TapGestureHandler.ts → gesture-handlers/TapGestureHandler.ts} +11 -11
  38. package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
  39. package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
  40. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +8 -9
  41. package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerButton.ts → components/RNGestureHandlerButton.ts} +35 -36
  42. package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerRootView.ts → components/RNGestureHandlerRootView.ts} +23 -23
  43. package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
  44. package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -3
  45. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
  46. package/harmony/gesture_handler/src/main/ets/{GestureHandlerPackage.ts → rnoh/GestureHandlerPackage.ts} +4 -4
  47. package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
  48. package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
  49. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +98 -0
  50. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
  51. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerButton.ets → rnoh/RNGestureHandlerButton.ets} +3 -3
  52. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerModule.ts → rnoh/RNGestureHandlerModule.ts} +79 -29
  53. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerRootView.ets → rnoh/RNGestureHandlerRootView.ets} +3 -3
  54. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
  55. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
  56. package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +134 -0
  57. package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +97 -0
  58. package/harmony/gesture_handler/src/main/module.json5 +8 -6
  59. package/harmony/gesture_handler/ts.ts +2 -2
  60. package/harmony/gesture_handler.har +0 -0
  61. package/lib/commonjs/index.js +126 -141
  62. package/lib/commonjs/index.js.map +1 -1
  63. package/lib/module/index.js +13 -146
  64. package/lib/module/index.js.map +1 -1
  65. package/lib/typescript/index.d.ts +39 -1
  66. package/lib/typescript/index.d.ts.map +1 -1
  67. package/package.json +13 -10
  68. package/src/index.ts +140 -140
  69. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerPackage.h +0 -72
  70. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentInstance.h +0 -78
  71. package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +0 -53
  72. package/harmony/gesture_handler/src/main/ets/GestureHandlerArkUIAdapter.ts +0 -203
  73. package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +0 -45
  74. package/harmony/gesture_handler/src/main/ets/GestureHandlerRegistry.ts +0 -28
  75. package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +0 -109
  76. package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +0 -48
  77. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerArkTS.ts +0 -60
  78. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerCAPI.ts +0 -87
  79. package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +0 -23
  80. package/harmony/gesture_handler/src/main/ets/Vector2D.ts +0 -36
  81. package/harmony/gesture_handler/src/main/ets/View.ts +0 -71
  82. package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +0 -43
  83. package/harmony/gesture_handler/src/main/ets/pages/Index.ets +0 -17
  84. package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +0 -41
  85. /package/harmony/gesture_handler/src/main/ets/{CircularBuffer.ts → core/CircularBuffer.ts} +0 -0
  86. /package/harmony/gesture_handler/src/main/ets/{LeastSquareSolver.ts → core/LeastSquareSolver.ts} +0 -0
  87. /package/harmony/gesture_handler/src/main/ets/{RNGHError.ts → core/RNGHError.ts} +0 -0
  88. /package/harmony/gesture_handler/src/main/ets/{State.ts → core/State.ts} +0 -0
  89. /package/harmony/gesture_handler/src/main/ets/{types.ts → rnoh/types.ts} +0 -0
@@ -1,24 +1,28 @@
1
1
  import type { GestureHandlerOrchestrator } from "./GestureHandlerOrchestrator"
2
2
  import type { PointerTracker } from "./PointerTracker"
3
3
  import type { View } from "./View"
4
- import type { EventDispatcher } from "./EventDispatcher"
5
4
  import type { InteractionManager } from "./InteractionManager"
6
5
  import type { RNGHLogger } from './RNGHLogger'
6
+ import { OutgoingEventDispatcher } from "./OutgoingEventDispatcher"
7
7
  import { State, getStateName } from "./State"
8
- import { HitSlop, Directions, AdaptedEvent, PointerType, TouchEventType, EventType } from "./Event"
8
+ import { HitSlop, Directions, IncomingEvent, PointerType, TouchEventType, EventType } from "./IncomingEvent"
9
9
  import { GestureStateChangeEvent, GestureTouchEvent, TouchData } from "./OutgoingEvent"
10
10
 
11
11
 
12
+ export type GHTag = number
13
+
12
14
  export interface Handler {
13
- handlerTag: number;
15
+ handlerTag: GHTag;
14
16
  }
15
17
 
16
18
  export const DEFAULT_TOUCH_SLOP = 15;
17
19
 
18
20
  export interface GestureConfig {
19
21
  enabled?: boolean;
22
+ manualActivation?: boolean;
20
23
  simultaneousHandlers?: Handler[] | null;
21
24
  waitFor?: Handler[] | null;
25
+ blocksHandlers?: Handler[] | null;
22
26
  hitSlop?: HitSlop;
23
27
  shouldCancelWhenOutside?: boolean;
24
28
  activateAfterLongPress?: number;
@@ -49,7 +53,7 @@ export interface GestureConfig {
49
53
  maxDeltaY?: number;
50
54
  shouldActivateOnStart?: boolean;
51
55
  disallowInterruption?: boolean;
52
- direction?: typeof Directions;
56
+ direction?: Directions;
53
57
  needsPointerData?: boolean
54
58
  // --- Tap
55
59
  minNumberOfPointers?: number
@@ -61,6 +65,10 @@ export interface ScrollLocker {
61
65
  lockScrollContainingViewTag(viewTag: number): () => void
62
66
  }
63
67
 
68
+ export interface RNGestureResponder {
69
+ lock: (viewTag: number) => () => void
70
+ }
71
+
64
72
  export type GestureHandlerDependencies = {
65
73
  handlerTag: number
66
74
  orchestrator: GestureHandlerOrchestrator
@@ -68,6 +76,7 @@ export type GestureHandlerDependencies = {
68
76
  interactionManager: InteractionManager
69
77
  logger: RNGHLogger
70
78
  scrollLocker: ScrollLocker
79
+ rnGestureResponder: RNGestureResponder
71
80
  }
72
81
 
73
82
  export abstract class GestureHandler<TGestureConfig extends GestureConfig = GestureConfig> {
@@ -86,10 +95,11 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
86
95
  protected handlerTag: number
87
96
  protected orchestrator: GestureHandlerOrchestrator
88
97
  protected tracker: PointerTracker
89
- protected eventDispatcher: EventDispatcher
98
+ protected eventDispatcher: OutgoingEventDispatcher
90
99
  protected interactionManager: InteractionManager
91
100
  protected logger: RNGHLogger
92
101
  protected scrollLocker: ScrollLocker
102
+ protected rnGestureResponder: RNGestureResponder
93
103
 
94
104
  constructor(deps: GestureHandlerDependencies
95
105
  ) {
@@ -99,15 +109,16 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
99
109
  this.interactionManager = deps.interactionManager
100
110
  this.logger = deps.logger
101
111
  this.scrollLocker = deps.scrollLocker
112
+ this.rnGestureResponder = deps.rnGestureResponder
102
113
  }
103
114
 
104
- public setEventDispatcher(eventDispatcher: EventDispatcher) {
115
+ public setEventDispatcher(eventDispatcher: OutgoingEventDispatcher) {
105
116
  // TurboModule provides info about kind of event dispatcher when attaching GH to a view, not when GH is created.
106
117
  // This method must be called before any other
107
118
  this.eventDispatcher = eventDispatcher
108
119
  }
109
120
 
110
- public onPointerDown(e: AdaptedEvent) {
121
+ public onPointerDown(e: IncomingEvent) {
111
122
  this.logger.info("onPointerDown")
112
123
  this.orchestrator.registerHandlerIfNotPresent(this);
113
124
  this.pointerType = e.pointerType;
@@ -119,7 +130,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
119
130
  }
120
131
  }
121
132
 
122
- protected sendTouchEvent(e: AdaptedEvent) {
133
+ protected sendTouchEvent(e: IncomingEvent) {
123
134
  if (!this.config.enabled) {
124
135
  return;
125
136
  }
@@ -133,7 +144,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
133
144
  }
134
145
  }
135
146
 
136
- protected transformToTouchEvent(event: AdaptedEvent): GestureTouchEvent | undefined {
147
+ protected transformToTouchEvent(event: IncomingEvent): GestureTouchEvent | undefined {
137
148
  const rect = this.view.getBoundingRect();
138
149
 
139
150
  const all: TouchData[] = [];
@@ -226,22 +237,22 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
226
237
  };
227
238
  }
228
239
 
229
- public onPointerUp(e: AdaptedEvent): void {
240
+ public onPointerUp(e: IncomingEvent): void {
230
241
  this.logger.info("onPointerUp")
231
242
  if (this.config.needsPointerData) this.sendTouchEvent(e)
232
243
  }
233
244
 
234
- public onAdditionalPointerAdd(e: AdaptedEvent): void {
245
+ public onAdditionalPointerAdd(e: IncomingEvent): void {
235
246
  this.logger.info("onAdditionalPointerAdd")
236
247
  if (this.config.needsPointerData) this.sendTouchEvent(e)
237
248
  }
238
249
 
239
- public onAdditionalPointerRemove(e: AdaptedEvent): void {
250
+ public onAdditionalPointerRemove(e: IncomingEvent): void {
240
251
  this.logger.info("onAdditionalPointerRemove")
241
252
  if (this.config.needsPointerData) this.sendTouchEvent(e)
242
253
  }
243
254
 
244
- public onPointerMove(e: AdaptedEvent): void {
255
+ public onPointerMove(e: IncomingEvent): void {
245
256
  this.logger.info("onPointerMove")
246
257
  this.tryToSendMoveEvent(false);
247
258
  if (this.config.needsPointerData) {
@@ -265,14 +276,14 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
265
276
  }
266
277
  }
267
278
 
268
- public onPointerEnter(e: AdaptedEvent): void {
279
+ public onPointerEnter(e: IncomingEvent): void {
269
280
  this.logger.info("onPointerEnter")
270
281
  if (this.config.needsPointerData) {
271
282
  this.sendTouchEvent(e)
272
283
  }
273
284
  }
274
285
 
275
- public onPointerOut(e: AdaptedEvent): void {
286
+ public onPointerOut(e: IncomingEvent): void {
276
287
  this.logger.info("onPointerOut")
277
288
  if (this.shouldCancelWhenOutside) {
278
289
  switch (this.currentState) {
@@ -290,7 +301,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
290
301
  }
291
302
  }
292
303
 
293
- public onPointerCancel(e: AdaptedEvent): void {
304
+ public onPointerCancel(e: IncomingEvent): void {
294
305
  this.logger.info("onPointerCancel")
295
306
  if (this.config.needsPointerData) {
296
307
  this.sendTouchEvent(e);
@@ -299,7 +310,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
299
310
  this.reset();
300
311
  }
301
312
 
302
- public onPointerOutOfBounds(e: AdaptedEvent): void {
313
+ public onPointerOutOfBounds(e: IncomingEvent): void {
303
314
  this.logger.info("onPointerOutOfBounds")
304
315
  this.tryToSendMoveEvent(true);
305
316
  if (this.config.needsPointerData) {
@@ -403,7 +414,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
403
414
 
404
415
  public activate(): void {
405
416
  this.logger.info("activate")
406
- if (this.currentState === State.UNDETERMINED || this.currentState === State.BEGAN) {
417
+ if (!this.config.manualActivation || this.currentState === State.UNDETERMINED || this.currentState === State.BEGAN) {
407
418
  this.moveToState(State.ACTIVE)
408
419
  }
409
420
  }
@@ -417,7 +428,11 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
417
428
  this.cancelTouches()
418
429
  }
419
430
  this.orchestrator.onHandlerStateChange(this, state, oldState)
420
- this.stateDidChange(state, oldState)
431
+ this.onStateChange(state, oldState)
432
+
433
+ if (!this.isEnabled() && this.isFinished()) {
434
+ this.currentState = State.UNDETERMINED;
435
+ }
421
436
  }
422
437
 
423
438
  private isFinished() {
@@ -464,8 +479,8 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
464
479
  this.eventDispatcher.onGestureHandlerEvent(cancelEvent)
465
480
  }
466
481
 
467
- protected stateDidChange(newState: State, oldState: State) {
468
- this.logger.info(`stateDidChange from ${getStateName(oldState)} to ${getStateName(newState)}`)
482
+ protected onStateChange(newState: State, oldState: State) {
483
+ this.logger.info(`onStateChange: from ${getStateName(oldState)} to ${getStateName(newState)}`)
469
484
  }
470
485
 
471
486
 
@@ -535,14 +550,16 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
535
550
  oldState: State,
536
551
  newState: State
537
552
  }): void {
538
- this.logger.info(`sendEvent`)
553
+ const logger = this.logger.cloneWithPrefix(`sendEvent(newState=${getStateName(newState)}, oldState=${getStateName(oldState)})`)
539
554
  const stateChangeEvent = this.createStateChangeEvent(newState, oldState);
540
555
  if (this.lastSentState !== newState) {
541
556
  this.lastSentState = newState;
557
+ logger.debug("calling onGestureHandlerStateChange")
542
558
  this.eventDispatcher.onGestureHandlerStateChange(stateChangeEvent);
543
559
  }
544
560
  if (this.currentState === State.ACTIVE) {
545
561
  stateChangeEvent.oldState = undefined;
562
+ logger.debug("calling onGestureHandlerEvent")
546
563
  this.eventDispatcher.onGestureHandlerEvent(stateChangeEvent);
547
564
  }
548
565
  }
@@ -562,8 +579,14 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
562
579
  };
563
580
  }
564
581
 
565
- protected transformNativeEvent() {
566
- return {};
582
+ protected transformNativeEvent(): Record<string, unknown> {
583
+ const rect = this.view.getBoundingRect();
584
+ return {
585
+ x: this.tracker.getLastAvgX() - rect.x,
586
+ y: this.tracker.getLastAvgY() - rect.y,
587
+ absoluteX: this.tracker.getLastAvgX(),
588
+ absoluteY: this.tracker.getLastAvgY(),
589
+ };
567
590
  }
568
591
 
569
592
  setAwaiting(isAwaiting: boolean): void {
@@ -583,11 +606,14 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
583
606
  }
584
607
 
585
608
  shouldWaitFor(otherHandler: GestureHandler): boolean {
586
- return (
609
+ const logger = this.logger.cloneWithPrefix(`shouldWaitFor(${otherHandler.getTag()})`)
610
+ const result = (
587
611
  this !== otherHandler &&
588
612
  (this.shouldWaitForHandlerFailure(otherHandler) ||
589
613
  otherHandler.shouldRequireToWaitForFailure(this))
590
614
  );
615
+ logger.debug(result)
616
+ return result
591
617
  }
592
618
 
593
619
  reset(): void {
@@ -595,7 +621,6 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
595
621
  this.tracker.resetTracker();
596
622
  this.onReset();
597
623
  this.resetProgress();
598
- // TODO: reset ArkUIAdapters
599
624
  // this.eventManagers.forEach((manager: EventManager) =>
600
625
  // manager.resetManager()
601
626
  // );
@@ -640,8 +665,10 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
640
665
  }
641
666
 
642
667
  shouldRecognizeSimultaneously(otherHandler: GestureHandler): boolean {
643
- if (otherHandler === this)
668
+ this.logger.cloneWithPrefix(`shouldRecognizeSimultaneously(${otherHandler.getTag()})`).debug("")
669
+ if (otherHandler === this) {
644
670
  return true;
671
+ }
645
672
  return this.interactionManager.shouldRecognizeSimultaneously(this, otherHandler);
646
673
  }
647
674
 
@@ -1,6 +1,6 @@
1
1
  import { GestureHandler } from "./GestureHandler"
2
- import { State } from "./State"
3
- import { PointerType } from "./Event"
2
+ import { State, getStateName } from "./State"
3
+ import { PointerType } from "./IncomingEvent"
4
4
  import { RNGHLogger } from "./RNGHLogger"
5
5
 
6
6
  export class GestureHandlerOrchestrator {
@@ -13,92 +13,133 @@ export class GestureHandlerOrchestrator {
13
13
  }
14
14
 
15
15
  public onHandlerStateChange(handler: GestureHandler, newState: State, oldState: State, sendIfDisabled?: boolean) {
16
- this.logger.info("onHandlerStateChange")
17
- if (this.shouldCancelStateChange(handler, sendIfDisabled)) return;
16
+ const logger = this.logger.cloneWithPrefix(`onHandlerStateChange(handler=${handler.getTag()}, newState=${getStateName(newState)}, oldState=${getStateName(oldState)})`)
17
+ logger.debug("start")
18
+
19
+ if (!handler.isEnabled() && !sendIfDisabled) {
20
+ return;
21
+ }
22
+
23
+ // this.handlingChangeSemaphore += 1;
24
+
18
25
  if (this.isFinishedState(newState)) {
19
- this.handleChangingToFinishedState(handler, newState)
26
+ this.awaitingHandlers.forEach((otherHandler) => {
27
+ if (otherHandler.shouldWaitFor(handler)) {
28
+ if (newState === State.END) {
29
+ otherHandler?.cancel();
30
+ if (otherHandler.getState() === State.END) {
31
+ // Handle edge case, where discrete gestures end immediately after activation thus
32
+ // their state is set to END and when the gesture they are waiting for activates they
33
+ // should be cancelled, however `cancel` was never sent as gestures were already in the END state.
34
+ // Send synthetic BEGAN -> CANCELLED to properly handle JS logic
35
+ otherHandler.sendEvent({ newState: State.CANCELLED, oldState: State.BEGAN });
36
+ }
37
+ otherHandler?.setAwaiting(false);
38
+ } else {
39
+ this.tryActivate(otherHandler);
40
+ }
41
+ }
42
+ });
20
43
  }
44
+
21
45
  if (newState === State.ACTIVE) {
22
- this.tryActivate(handler)
46
+ this.tryActivate(handler);
23
47
  } else if (oldState === State.ACTIVE || oldState === State.END) {
24
48
  if (handler.isActive()) {
25
- handler.sendEvent({ newState, oldState })
26
- } else if (oldState === State.ACTIVE && (newState === State.CANCELLED || newState === State.FAILED)) {
27
- // Handle edge case where handler awaiting for another one tries to activate but finishes
28
- // before the other would not send state change event upon ending. Note that we only want
29
- // to do this if the newState is either CANCELLED or FAILED, if it is END we still want to
30
- // wait for the other handler to finish as in that case synthetic events will be sent by the
31
- // makeActive method.
32
- handler.sendEvent({ newState, oldState: State.BEGAN })
49
+ handler.sendEvent({ newState, oldState });
50
+ } else if (
51
+ oldState === State.ACTIVE &&
52
+ (newState === State.CANCELLED || newState === State.FAILED)
53
+ ) {
54
+ handler.sendEvent({ newState, oldState: State.BEGAN });
33
55
  }
34
- } else if (newState !== State.CANCELLED || oldState !== State.UNDETERMINED) {
35
- // If handler is changing state from UNDETERMINED to CANCELLED, the state change event shouldn't
36
- // be sent. Handler hasn't yet began so it may not be initialized which results in crashes.
37
- // If it doesn't crash, there may be some weird behavior on JS side, as `onFinalize` will be
38
- // called without calling `onBegin` first.
39
- handler.sendEvent({ newState, oldState })
56
+ } else if (
57
+ oldState !== State.UNDETERMINED ||
58
+ newState !== State.CANCELLED
59
+ ) {
60
+ handler.sendEvent({ newState, oldState });
40
61
  }
41
- this.cleanUpHandlers(handler)
42
- }
43
62
 
44
- private isFinishedState(state: State) {
45
- return [State.END, State.FAILED, State.CANCELLED].includes(state)
46
- }
63
+ // this.handlingChangeSemaphore -= 1;
47
64
 
48
- private shouldCancelStateChange(handler: GestureHandler, sendIfDisabled?: boolean) {
49
- const isHandlerDisabled = !handler.isEnabled()
50
- return!sendIfDisabled && isHandlerDisabled
65
+ this.cleanUpFinishedHandlers();
66
+ if (!this.awaitingHandlers.has(handler)) {
67
+ this.cleanupAwaitingHandlers(handler);
68
+ }
51
69
  }
52
70
 
53
- private handleChangingToFinishedState(handler: GestureHandler, newState: State) {
54
- this.awaitingHandlers.forEach(awaitingHandler => {
55
- if (handler.shouldWaitFor(awaitingHandler)) {
56
- if (newState === State.END) {
57
- awaitingHandler.cancel()
58
- if (awaitingHandler.getState() === State.END) {
59
- // Handle edge case, where discrete gestures end immediately after activation thus
60
- // their state is set to END and when the gesture they are waiting for activates they
61
- // should be cancelled, however `cancel` was never sent as gestures were already in the END state.
62
- // Send synthetic BEGAN -> CANCELLED to properly handle JS logic
63
- awaitingHandler.sendEvent({ newState: State.CANCELLED, oldState: State.BEGAN })
64
- }
65
- awaitingHandler.setAwaiting(false)
66
- } else {
67
- this.tryActivate(awaitingHandler)
68
- }
69
- }
70
- })
71
+ private isFinishedState(state: State) {
72
+ return [State.END, State.FAILED, State.CANCELLED].includes(state)
71
73
  }
72
74
 
73
75
  private tryActivate(handler: GestureHandler): void {
76
+ const logger = this.logger.cloneWithPrefix(`tryActivate(${handler.getTag()})`)
77
+ logger.debug({
78
+ gestureHandlers: this.gestureHandlers.map(gh => gh.getTag()),
79
+ awaitingHandlers: Array.from(this.awaitingHandlers).map(gh => gh.getTag()),
80
+ handlersToCancel: this.handlersToCancel.map(gh => gh.getTag())
81
+ })
82
+ if (this.shouldBeCancelledByFinishedHandler(handler)) {
83
+ logger.debug("failed to activate - cancelling")
84
+ handler.cancel();
85
+ return;
86
+ }
74
87
  if (this.hasOtherHandlerToWaitFor(handler)) {
75
- this.addAwaitingHandler(handler)
76
- } else if (handler.getState() !== State.CANCELLED && handler.getState() !== State.FAILED) {
77
- if (this.shouldActivate(handler)) {
78
- this.makeActive(handler);
79
- } else {
80
- switch (handler.getState()) {
81
- case State.ACTIVE:
82
- handler.fail();
83
- break;
84
- case State.BEGAN:
85
- handler.cancel();
86
- break;
87
- }
88
- }
88
+ this.addAwaitingHandler(handler);
89
+ logger.debug("request ignored - has other handler waiting")
90
+ return;
91
+ }
92
+ const handlerState = handler.getState();
93
+ if (handlerState === State.CANCELLED || handlerState === State.FAILED) {
94
+ logger.debug("request ignored - handler is in cancelled or failed state")
95
+ return;
96
+ }
97
+ if (this.shouldActivate(handler)) {
98
+ logger.debug("activating")
99
+ this.makeActive(handler);
100
+ return;
101
+ }
102
+ if (handlerState === State.ACTIVE) {
103
+ logger.debug("failed to activate - handler is already active, marking as fail")
104
+ handler.fail();
105
+ return;
106
+ }
107
+ if (handlerState === State.BEGAN) {
108
+ logger.debug("handler is in BEGAN state but shouldActivate returned false - cancelling")
109
+ handler.cancel();
89
110
  }
90
111
  }
91
112
 
113
+ private shouldBeCancelledByFinishedHandler(
114
+ handler: GestureHandler
115
+ ): boolean {
116
+ const shouldBeCancelled = (otherHandler: GestureHandler) => {
117
+ return (
118
+ handler.shouldWaitFor(otherHandler) &&
119
+ otherHandler.getState() === State.END
120
+ );
121
+ };
122
+ return this.gestureHandlers.some(shouldBeCancelled);
123
+ }
124
+
92
125
  private hasOtherHandlerToWaitFor(handler: GestureHandler): boolean {
126
+ const logger = this.logger.cloneWithPrefix(`hasOtherHandlerToWaitFor(handler=${handler.getTag()})`)
93
127
  for (const otherHandler of this.gestureHandlers) {
94
- if (!this.isFinishedState(otherHandler.getState()) && otherHandler.shouldWaitFor(handler)) {
128
+ if (otherHandler === handler) {
129
+ return false
130
+ }
131
+ if (!this.isFinishedState(otherHandler.getState()) && handler.shouldWaitFor(otherHandler)) {
132
+ logger.debug("true")
95
133
  return true
96
134
  }
97
135
  }
136
+ logger.debug("false")
98
137
  return false;
99
138
  }
100
139
 
101
140
  private addAwaitingHandler(handler: GestureHandler) {
141
+ const logger = this.logger.cloneWithPrefix(`addAwaitingHandler(handlerTag=${handler.getTag()})`)
142
+ logger.debug({ awaitingHandlers: this.awaitingHandlers })
102
143
  if (!this.awaitingHandlers.has(handler)) {
103
144
  this.awaitingHandlers.add(handler)
104
145
  handler.setAwaiting(true)
@@ -119,17 +160,29 @@ export class GestureHandlerOrchestrator {
119
160
  handler: GestureHandler,
120
161
  otherHandler: GestureHandler
121
162
  }): boolean {
122
- if (this.canRunSimultaneously(handler, otherHandler))
163
+ const logger = this.logger.cloneWithPrefix(`shouldHandlerBeCancelledByOtherHandler(${handler.getTag()}, ${otherHandler.getTag()})`)
164
+ if (this.canRunSimultaneously(handler, otherHandler)) {
165
+ logger.debug("false")
123
166
  return false;
124
- if (handler !== otherHandler && (handler.isAwaiting() || handler.getState() === State.ACTIVE))
125
- return handler.shouldBeCancelledByOther(otherHandler)
126
- return this.checkOverlap(handler, otherHandler)
167
+ }
168
+ if (handler !== otherHandler && (handler.isAwaiting() || handler.getState() === State.ACTIVE)) {
169
+ const result = handler.shouldBeCancelledByOther(otherHandler)
170
+ logger.debug(`${result} (1)`)
171
+ return result
172
+ }
173
+ const result = this.checkOverlap(handler, otherHandler)
174
+ logger.debug(`${result} (2)`)
175
+ return result;
127
176
  }
128
177
 
129
178
  private canRunSimultaneously(handlerA: GestureHandler, handlerB: GestureHandler) {
130
- return handlerA === handlerB
179
+ const logger = this.logger.cloneWithPrefix("canRunSimultaneously")
180
+ const result = handlerA === handlerB
131
181
  || handlerA.shouldRecognizeSimultaneously(handlerB)
132
182
  || handlerB.shouldRecognizeSimultaneously(handlerA)
183
+
184
+ logger.debug({ result, handlerA: handlerA.getTag(), handlerB: handlerB.getTag() })
185
+ return result
133
186
  }
134
187
 
135
188
  private checkOverlap(
@@ -222,6 +275,8 @@ export class GestureHandlerOrchestrator {
222
275
  }
223
276
 
224
277
  private cleanupAwaitingHandlers(handler: GestureHandler): void {
278
+ const logger = this.logger.cloneWithPrefix(`cleanupAwaitingHandlers(handler=${handler.getTag()})`)
279
+ logger.debug({ awaitingHandlers: this.awaitingHandlers })
225
280
  for (const awaitingHandler of this.awaitingHandlers) {
226
281
  if (
227
282
  awaitingHandler.isAwaiting() &&
@@ -241,7 +296,7 @@ export class GestureHandlerOrchestrator {
241
296
  }
242
297
 
243
298
  public registerHandlerIfNotPresent(handler: GestureHandler) {
244
- this.logger.info("registerHandlerIfNotPresent")
299
+ this.logger.info(`registerHandlerIfNotPresent(${handler.getTag()})`)
245
300
  if (this.gestureHandlers.includes(handler)) return;
246
301
  this.gestureHandlers.push(handler);
247
302
  handler.setActive(false);
@@ -0,0 +1,63 @@
1
+ import { GestureHandler } from "./GestureHandler"
2
+ import { View } from "./View"
3
+ import { RNGHLogger } from "./RNGHLogger"
4
+ import { ViewRegistry } from "./ViewRegistry"
5
+
6
+ export class GestureHandlerRegistry {
7
+ private gestureHandlerByHandlerTag: Map<number, GestureHandler> = new Map()
8
+ private gestureHandlersByViewTag: Map<number, Set<GestureHandler>> = new Map()
9
+ private viewRegistry: ViewRegistry | undefined
10
+ private logger: RNGHLogger
11
+
12
+ constructor(viewRegistry: ViewRegistry | undefined, logger: RNGHLogger) {
13
+ this.logger = logger.cloneWithPrefix("GestureHandlerRegistry")
14
+ this.viewRegistry = viewRegistry
15
+ }
16
+
17
+ public addGestureHandler(gestureHandler: GestureHandler) {
18
+ this.gestureHandlerByHandlerTag.set(gestureHandler.getTag(), gestureHandler)
19
+ }
20
+
21
+ public bindGestureHandlerWithView(gestureHandlerTag: number, view: View) {
22
+ this.logger.cloneWithPrefix("bindGestureHandlerWithView").debug({gestureHandlerTag, viewTag: view.getTag()})
23
+ const viewTag = view.getTag()
24
+ if (!this.gestureHandlersByViewTag.has(viewTag))
25
+ this.gestureHandlersByViewTag.set(viewTag, new Set())
26
+ const gestureHandler = this.gestureHandlerByHandlerTag.get(gestureHandlerTag)
27
+ this.gestureHandlersByViewTag.get(viewTag).add(gestureHandler)
28
+ gestureHandler.onViewAttached(view)
29
+ }
30
+
31
+ public getGestureHandlersByViewTag(viewTag: number): GestureHandler[] {
32
+ return Array.from(this.gestureHandlersByViewTag.get(viewTag) ?? [])
33
+ }
34
+
35
+ public removeGestureHandlerByHandlerTag(handlerTag: number) {
36
+ const gestureHandler = this.gestureHandlerByHandlerTag.get(handlerTag)
37
+ if (!gestureHandler) {
38
+ return;
39
+ }
40
+ const viewTag = gestureHandler.getView()?.getTag();
41
+ if (viewTag) {
42
+ const gestureHandlers = this.gestureHandlersByViewTag.get(viewTag)
43
+ if (gestureHandlers) {
44
+ gestureHandlers.delete(gestureHandler)
45
+ if (gestureHandlers.size === 0) {
46
+ this.gestureHandlersByViewTag.delete(viewTag)
47
+ this.viewRegistry?.deleteByTag(viewTag)
48
+ }
49
+ }
50
+ }
51
+ if (gestureHandler.getView()) {
52
+ // Handler is in "prepared" state which means it is registered in the orchestrator and can
53
+ // receive touch events. This means that before we remove it from the registry we need to
54
+ // "cancel" it so that orchestrator does no longer keep a reference to it.
55
+ gestureHandler.cancel()
56
+ }
57
+ this.gestureHandlerByHandlerTag.delete(handlerTag)
58
+ }
59
+
60
+ public getGestureHandlerByHandlerTag(handlerTag: number): GestureHandler {
61
+ return this.gestureHandlerByHandlerTag.get(handlerTag)
62
+ }
63
+ }
@@ -9,13 +9,30 @@ export interface HitSlop {
9
9
  height?: number;
10
10
  }
11
11
 
12
+ const RIGHT = 1;
13
+ const LEFT = 2;
14
+ const UP = 4;
15
+ const DOWN = 8;
16
+
12
17
  export const Directions = {
13
- RIGHT: 1,
14
- LEFT: 2,
15
- UP: 4,
16
- DOWN: 8,
18
+ RIGHT: RIGHT,
19
+ LEFT: LEFT,
20
+ UP: UP,
21
+ DOWN: DOWN,
17
22
  } as const;
18
23
 
24
+ export type Directions = typeof Directions[keyof typeof Directions];
25
+
26
+ export const DiagonalDirections = {
27
+ UP_RIGHT: UP | RIGHT,
28
+ DOWN_RIGHT: DOWN | RIGHT,
29
+ UP_LEFT: UP | LEFT,
30
+ DOWN_LEFT: DOWN | LEFT,
31
+ } as const;
32
+
33
+ export type DiagonalDirections =
34
+ typeof DiagonalDirections[keyof typeof DiagonalDirections];
35
+
19
36
  export enum PointerType {
20
37
  NONE = 'none',
21
38
  MOUSE = 'mouse',
@@ -24,14 +41,14 @@ export enum PointerType {
24
41
  }
25
42
 
26
43
  export enum EventType {
27
- DOWN,
28
- ADDITIONAL_POINTER_DOWN,
29
- UP,
30
- ADDITIONAL_POINTER_UP,
31
- MOVE,
32
- ENTER,
33
- OUT,
34
- CANCEL,
44
+ DOWN = "DOWN",
45
+ ADDITIONAL_POINTER_DOWN = "ADDITIONAL_POINTER_DOWN",
46
+ UP = "UP",
47
+ ADDITIONAL_POINTER_UP = "ADDITIONAL_POINTER_UP",
48
+ MOVE = "MOVE",
49
+ ENTER = "ENTER",
50
+ OUT = "OUT",
51
+ CANCEL = "CANCEL",
35
52
  }
36
53
 
37
54
  export type Touch = {id: number, x: number, y: number, absoluteX: number, absoluteY: number}
@@ -44,7 +61,7 @@ export enum TouchEventType {
44
61
  CANCELLED = 4,
45
62
  }
46
63
 
47
- export interface AdaptedEvent {
64
+ export interface IncomingEvent {
48
65
  x: number;
49
66
  y: number;
50
67
  offsetX: number;
@@ -59,10 +76,3 @@ export interface AdaptedEvent {
59
76
  touchEventType?: TouchEventType;
60
77
  }
61
78
 
62
- export interface TrackerElement {
63
- lastX: number;
64
- lastY: number;
65
- timeStamp: number;
66
- velocityX: number;
67
- velocityY: number;
68
- }