react-native-reanimated 2.9.1 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/Common/cpp/AnimatedSensor/AnimatedSensorModule.cpp +4 -4
  2. package/Common/cpp/NativeModules/NativeReanimatedModule.cpp +38 -0
  3. package/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp +23 -0
  4. package/Common/cpp/headers/NativeModules/NativeReanimatedModule.h +8 -0
  5. package/Common/cpp/headers/NativeModules/NativeReanimatedModuleSpec.h +8 -0
  6. package/Common/cpp/headers/Tools/PlatformDepMethodsHolder.h +5 -0
  7. package/RNReanimated.podspec +22 -3
  8. package/android/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  9. package/android/.gradle/7.2/executionHistory/executionHistory.bin +0 -0
  10. package/android/.gradle/7.2/executionHistory/executionHistory.lock +0 -0
  11. package/android/.gradle/7.2/fileHashes/fileHashes.bin +0 -0
  12. package/android/.gradle/7.2/fileHashes/fileHashes.lock +0 -0
  13. package/android/.gradle/7.2/fileHashes/resourceHashesCache.bin +0 -0
  14. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  15. package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
  16. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  17. package/android/.gradle/checksums/checksums.lock +0 -0
  18. package/android/.gradle/checksums/md5-checksums.bin +0 -0
  19. package/android/.gradle/checksums/sha1-checksums.bin +0 -0
  20. package/android/CMakeLists.txt +214 -95
  21. package/android/build.gradle +247 -236
  22. package/android/react-native-reanimated-66-hermes.aar +0 -0
  23. package/android/react-native-reanimated-66-jsc.aar +0 -0
  24. package/android/react-native-reanimated-67-hermes.aar +0 -0
  25. package/android/react-native-reanimated-67-jsc.aar +0 -0
  26. package/android/react-native-reanimated-68-hermes.aar +0 -0
  27. package/android/react-native-reanimated-68-jsc.aar +0 -0
  28. package/android/react-native-reanimated-69-hermes.aar +0 -0
  29. package/android/react-native-reanimated-69-jsc.aar +0 -0
  30. package/android/react-native-reanimated-70-hermes.aar +0 -0
  31. package/android/react-native-reanimated-70-jsc.aar +0 -0
  32. package/{lib/types/lib/reanimated2/platform-specific/RNRenderer.web.d.ts → android/rnVersionPatch/70/.gitkeep} +0 -0
  33. package/android/src/main/cpp/NativeProxy.cpp +54 -20
  34. package/android/src/main/cpp/OnLoad.cpp +1 -0
  35. package/android/src/main/cpp/headers/NativeProxy.h +29 -0
  36. package/android/src/main/java/com/swmansion/reanimated/NativeProxy.java +25 -0
  37. package/android/src/main/java/com/swmansion/reanimated/NodesManager.java +3 -1
  38. package/android/src/main/java/com/swmansion/reanimated/keyboardObserver/ReanimatedKeyboardEventListener.java +165 -0
  39. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/AnimationsManager.java +19 -16
  40. package/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensor.java +5 -1
  41. package/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorType.java +1 -1
  42. package/ios/REANodesManager.m +31 -8
  43. package/ios/keyboardObserver/REAKeyboardEventObserver.h +17 -0
  44. package/ios/keyboardObserver/REAKeyboardEventObserver.m +198 -0
  45. package/ios/native/NativeProxy.mm +20 -1
  46. package/ios/native/REAInitializer.mm +8 -12
  47. package/ios/sensor/ReanimatedSensor.m +26 -17
  48. package/lib/index.js +11 -3
  49. package/lib/index.web.js +4 -0
  50. package/lib/reanimated2/Colors.js +1 -1
  51. package/lib/reanimated2/NativeMethods.js +3 -0
  52. package/lib/reanimated2/NativeReanimated/NativeReanimated.js +6 -0
  53. package/lib/reanimated2/animation/util.js +4 -1
  54. package/lib/reanimated2/commonTypes.js +8 -1
  55. package/lib/reanimated2/component/FlatList.js +5 -5
  56. package/lib/reanimated2/core.js +5 -4
  57. package/lib/reanimated2/frameCallback/FrameCallbackRegistryJS.js +32 -0
  58. package/lib/reanimated2/frameCallback/FrameCallbackRegistryUI.js +47 -0
  59. package/lib/reanimated2/globals.d.ts +3 -0
  60. package/lib/reanimated2/hook/index.js +2 -0
  61. package/lib/reanimated2/hook/useAnimatedKeyboard.js +31 -0
  62. package/lib/reanimated2/hook/useAnimatedSensor.js +3 -3
  63. package/lib/reanimated2/hook/useFrameCallback.js +23 -0
  64. package/lib/reanimated2/jestUtils.js +11 -3
  65. package/lib/reanimated2/js-reanimated/JSReanimated.js +7 -0
  66. package/lib/reanimated2/js-reanimated/global.js +33 -22
  67. package/lib/reanimated2/layoutReanimation/LayoutAnimationRepository.js +1 -1
  68. package/lib/types/{lib/Animated.d.ts → Animated.d.ts} +0 -0
  69. package/lib/types/{lib/ConfigHelper.d.ts → ConfigHelper.d.ts} +0 -0
  70. package/lib/types/{lib/ReanimatedEventEmitter.d.ts → ReanimatedEventEmitter.d.ts} +0 -0
  71. package/lib/types/{lib/ReanimatedModule.d.ts → ReanimatedModule.d.ts} +0 -0
  72. package/lib/types/{lib/ReanimatedModule.macos.d.ts → ReanimatedModule.macos.d.ts} +0 -0
  73. package/lib/types/{lib/ReanimatedModule.native.d.ts → ReanimatedModule.native.d.ts} +0 -0
  74. package/lib/types/{lib/ReanimatedModule.windows.d.ts → ReanimatedModule.windows.d.ts} +0 -0
  75. package/lib/types/{lib/ReanimatedModuleCompat.d.ts → ReanimatedModuleCompat.d.ts} +0 -0
  76. package/lib/types/{lib/createAnimatedComponent.d.ts → createAnimatedComponent.d.ts} +0 -0
  77. package/lib/types/index.d.ts +4 -0
  78. package/lib/types/{lib/index.d.ts → index.web.d.ts} +0 -1
  79. package/lib/types/{lib/reanimated2 → reanimated2}/Bezier.d.ts +0 -0
  80. package/lib/types/{lib/reanimated2 → reanimated2}/Colors.d.ts +0 -0
  81. package/lib/types/{lib/reanimated2 → reanimated2}/Easing.d.ts +0 -0
  82. package/lib/types/{lib/reanimated2 → reanimated2}/NativeMethods.d.ts +0 -0
  83. package/lib/types/{lib/reanimated2 → reanimated2}/NativeReanimated/NativeReanimated.d.ts +3 -1
  84. package/lib/types/{lib/reanimated2 → reanimated2}/NativeReanimated/index.d.ts +0 -0
  85. package/lib/types/{lib/reanimated2 → reanimated2}/PlatformChecker.d.ts +0 -0
  86. package/lib/types/{lib/reanimated2 → reanimated2}/PropAdapters.d.ts +0 -0
  87. package/lib/types/{lib/reanimated2 → reanimated2}/UpdateProps.d.ts +0 -0
  88. package/lib/types/{lib/reanimated2 → reanimated2}/ViewDescriptorsSet.d.ts +0 -0
  89. package/lib/types/{lib/reanimated2 → reanimated2}/WorkletEventHandler.d.ts +0 -0
  90. package/lib/types/{lib/reanimated2 → reanimated2}/__mocks__/MutableValue.d.ts +0 -0
  91. package/lib/types/{lib/reanimated2 → reanimated2}/__mocks__/NativeReanimated.d.ts +0 -0
  92. package/lib/types/{lib/reanimated2 → reanimated2}/__mocks__/NativeReanimated.native.d.ts +0 -0
  93. package/lib/types/{lib/reanimated2 → reanimated2}/animation/commonTypes.d.ts +0 -0
  94. package/lib/types/{lib/reanimated2 → reanimated2}/animation/decay.d.ts +0 -0
  95. package/lib/types/{lib/reanimated2 → reanimated2}/animation/delay.d.ts +0 -0
  96. package/lib/types/{lib/reanimated2 → reanimated2}/animation/index.d.ts +0 -0
  97. package/lib/types/{lib/reanimated2 → reanimated2}/animation/repeat.d.ts +0 -0
  98. package/lib/types/{lib/reanimated2 → reanimated2}/animation/sequence.d.ts +0 -0
  99. package/lib/types/{lib/reanimated2 → reanimated2}/animation/spring.d.ts +0 -0
  100. package/lib/types/{lib/reanimated2 → reanimated2}/animation/styleAnimation.d.ts +0 -0
  101. package/lib/types/{lib/reanimated2 → reanimated2}/animation/timing.d.ts +0 -0
  102. package/lib/types/{lib/reanimated2 → reanimated2}/animation/util.d.ts +0 -0
  103. package/lib/types/{lib/reanimated2 → reanimated2}/commonTypes.d.ts +12 -0
  104. package/lib/types/{lib/reanimated2 → reanimated2}/component/FlatList.d.ts +2 -2
  105. package/lib/types/{lib/reanimated2 → reanimated2}/component/Image.d.ts +0 -0
  106. package/lib/types/{lib/reanimated2 → reanimated2}/component/ScrollView.d.ts +0 -0
  107. package/lib/types/{lib/reanimated2 → reanimated2}/component/Text.d.ts +0 -0
  108. package/lib/types/{lib/reanimated2 → reanimated2}/component/View.d.ts +0 -0
  109. package/lib/types/{lib/reanimated2 → reanimated2}/core.d.ts +0 -0
  110. package/lib/types/reanimated2/frameCallback/FrameCallbackRegistryJS.d.ts +7 -0
  111. package/lib/types/reanimated2/frameCallback/FrameCallbackRegistryUI.d.ts +10 -0
  112. package/lib/types/{lib/reanimated2 → reanimated2}/hook/Hooks.d.ts +0 -0
  113. package/lib/types/{lib/reanimated2 → reanimated2}/hook/commonTypes.d.ts +0 -0
  114. package/lib/types/{lib/reanimated2 → reanimated2}/hook/index.d.ts +3 -0
  115. package/lib/types/{lib/reanimated2 → reanimated2}/hook/useAnimatedGestureHandler.d.ts +0 -0
  116. package/lib/types/reanimated2/hook/useAnimatedKeyboard.d.ts +2 -0
  117. package/lib/types/{lib/reanimated2 → reanimated2}/hook/useAnimatedReaction.d.ts +0 -0
  118. package/lib/types/{lib/reanimated2 → reanimated2}/hook/useAnimatedRef.d.ts +0 -0
  119. package/lib/types/{lib/reanimated2 → reanimated2}/hook/useAnimatedScrollHandler.d.ts +0 -0
  120. package/lib/types/{lib/reanimated2 → reanimated2}/hook/useAnimatedSensor.d.ts +1 -1
  121. package/lib/types/{lib/reanimated2 → reanimated2}/hook/useAnimatedStyle.d.ts +0 -0
  122. package/lib/types/{lib/reanimated2 → reanimated2}/hook/useDerivedValue.d.ts +0 -0
  123. package/lib/types/reanimated2/hook/useFrameCallback.d.ts +6 -0
  124. package/lib/types/{lib/reanimated2 → reanimated2}/hook/useSharedValue.d.ts +0 -0
  125. package/lib/types/{lib/reanimated2 → reanimated2}/hook/utils.d.ts +0 -0
  126. package/lib/types/{lib/reanimated2 → reanimated2}/index.d.ts +0 -0
  127. package/lib/types/{lib/reanimated2 → reanimated2}/interpolateColor.d.ts +0 -0
  128. package/lib/types/{lib/reanimated2 → reanimated2}/interpolation.d.ts +0 -0
  129. package/lib/types/{lib/reanimated2 → reanimated2}/jestUtils.d.ts +1 -1
  130. package/lib/types/{lib/reanimated2 → reanimated2}/js-reanimated/JSReanimated.d.ts +3 -1
  131. package/lib/types/{lib/reanimated2 → reanimated2}/js-reanimated/Mapper.d.ts +0 -0
  132. package/lib/types/{lib/reanimated2 → reanimated2}/js-reanimated/MapperRegistry.d.ts +0 -0
  133. package/lib/types/{lib/reanimated2 → reanimated2}/js-reanimated/MutableValue.d.ts +0 -0
  134. package/lib/types/{lib/reanimated2 → reanimated2}/js-reanimated/commonTypes.d.ts +0 -0
  135. package/lib/types/reanimated2/js-reanimated/global.d.ts +2 -0
  136. package/lib/types/{lib/reanimated2 → reanimated2}/js-reanimated/index.d.ts +0 -0
  137. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/LayoutAnimationRepository.d.ts +0 -0
  138. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/animationBuilder/BaseAnimationBuilder.d.ts +0 -0
  139. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/animationBuilder/ComplexAnimationBuilder.d.ts +0 -0
  140. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/animationBuilder/Keyframe.d.ts +0 -0
  141. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/animationBuilder/commonTypes.d.ts +0 -0
  142. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/animationBuilder/index.d.ts +0 -0
  143. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Bounce.d.ts +0 -0
  144. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Default.d.ts +0 -0
  145. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Fade.d.ts +0 -0
  146. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Flip.d.ts +0 -0
  147. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Lightspeed.d.ts +0 -0
  148. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Pinwheel.d.ts +0 -0
  149. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Roll.d.ts +0 -0
  150. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Rotate.d.ts +0 -0
  151. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Slide.d.ts +0 -0
  152. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Stretch.d.ts +0 -0
  153. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/Zoom.d.ts +0 -0
  154. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultAnimations/index.d.ts +0 -0
  155. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultTransitions/CurvedTransition.d.ts +0 -0
  156. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultTransitions/EntryExitTransition.d.ts +0 -0
  157. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultTransitions/FadingTransition.d.ts +0 -0
  158. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultTransitions/JumpingTransition.d.ts +0 -0
  159. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultTransitions/LinearTransition.d.ts +0 -0
  160. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultTransitions/SequencedTransition.d.ts +0 -0
  161. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/defaultTransitions/index.d.ts +0 -0
  162. package/lib/types/{lib/reanimated2 → reanimated2}/layoutReanimation/index.d.ts +0 -0
  163. package/lib/types/{lib/reanimated2 → reanimated2}/mock.d.ts +0 -0
  164. package/lib/types/{lib/reanimated2 → reanimated2}/platform-specific/RNRenderer.d.ts +0 -0
  165. package/lib/types/reanimated2/platform-specific/RNRenderer.web.d.ts +0 -0
  166. package/lib/types/{lib/reanimated2 → reanimated2}/utils.d.ts +0 -0
  167. package/lib/types/{lib/setAndForwardRef.d.ts → setAndForwardRef.d.ts} +0 -0
  168. package/mock.js +1 -0
  169. package/package.json +5 -6
  170. package/plugin.js +7 -16
  171. package/react-native-reanimated.d.ts +55 -4
  172. package/src/index.ts +11 -3
  173. package/src/index.web.ts +5 -0
  174. package/src/reanimated2/Colors.ts +1 -1
  175. package/src/reanimated2/NativeMethods.ts +5 -0
  176. package/src/reanimated2/NativeReanimated/NativeReanimated.ts +9 -0
  177. package/src/reanimated2/animation/util.ts +8 -1
  178. package/src/reanimated2/commonTypes.ts +15 -0
  179. package/src/reanimated2/component/FlatList.tsx +29 -19
  180. package/src/reanimated2/core.ts +8 -8
  181. package/src/reanimated2/frameCallback/FrameCallbackRegistryJS.ts +43 -0
  182. package/src/reanimated2/frameCallback/FrameCallbackRegistryUI.ts +64 -0
  183. package/src/reanimated2/globals.d.ts +3 -0
  184. package/src/reanimated2/hook/index.ts +3 -0
  185. package/src/reanimated2/hook/useAnimatedKeyboard.ts +35 -0
  186. package/src/reanimated2/hook/useAnimatedSensor.ts +5 -5
  187. package/src/reanimated2/hook/useFrameCallback.ts +39 -0
  188. package/src/reanimated2/jestUtils.ts +11 -3
  189. package/src/reanimated2/js-reanimated/JSReanimated.ts +16 -1
  190. package/src/reanimated2/js-reanimated/global.ts +41 -29
  191. package/src/reanimated2/layoutReanimation/LayoutAnimationRepository.ts +1 -1
  192. package/android/react-native-reanimated-65-hermes.aar +0 -0
  193. package/android/react-native-reanimated-65-jsc.aar +0 -0
  194. package/lib/types/lib/reanimated2/js-reanimated/global.d.ts +0 -1
  195. package/lib/types/react-native-reanimated-tests.d.ts +0 -1
@@ -0,0 +1,198 @@
1
+ #import "REAKeyboardEventObserver.h"
2
+ #import <Foundation/Foundation.h>
3
+ #import <React/RCTDefines.h>
4
+ #import <React/RCTUIManager.h>
5
+
6
+ typedef NS_ENUM(NSUInteger, KeyboardState) {
7
+ UNKNOWN = 0,
8
+ OPENING = 1,
9
+ OPEN = 2,
10
+ CLOSING = 3,
11
+ CLOSED = 4,
12
+ };
13
+
14
+ @implementation REAKeyboardEventObserver {
15
+ NSNumber *_nextListenerId;
16
+ NSMutableDictionary *_listeners;
17
+ CADisplayLink *displayLink;
18
+ int _windowsCount;
19
+ UIView *_keyboardView;
20
+ KeyboardState _state;
21
+ }
22
+
23
+ - (instancetype)init
24
+ {
25
+ self = [super init];
26
+ _listeners = [[NSMutableDictionary alloc] init];
27
+ _nextListenerId = @0;
28
+ _state = UNKNOWN;
29
+ return self;
30
+ }
31
+
32
+ // copied from
33
+ // https://github.com/tonlabs/UIKit/blob/bd5651e4723d547bde0cb86ca1c27813cedab4a9/casts/keyboard/ios/UIKitKeyboardIosFrameListener.m
34
+ - (UIView *)findKeyboardView
35
+ {
36
+ for (UIWindow *window in [UIApplication.sharedApplication.windows objectEnumerator]) {
37
+ if ([window isKindOfClass:NSClassFromString(@"UITextEffectsWindow")]) {
38
+ for (UIView *containerView in window.subviews) {
39
+ if ([containerView isKindOfClass:NSClassFromString(@"UIInputSetContainerView")]) {
40
+ for (UIView *hostView in containerView.subviews) {
41
+ if ([hostView isKindOfClass:NSClassFromString(@"UIInputSetHostView")]) {
42
+ return hostView;
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ return nil;
50
+ }
51
+
52
+ - (UIView *)getKeyboardView
53
+ {
54
+ /**
55
+ * If the count of windows has changed it means there might be a new UITextEffectsWindow,
56
+ * thus we have to obtain a new `keyboardView`
57
+ */
58
+ int windowsCount = [UIApplication.sharedApplication.windows count];
59
+
60
+ if (_keyboardView == nil || windowsCount != _windowsCount) {
61
+ _keyboardView = [self findKeyboardView];
62
+ _windowsCount = windowsCount;
63
+ }
64
+ return _keyboardView;
65
+ }
66
+
67
+ #if TARGET_OS_TV
68
+ - (int)subscribeForKeyboardEvents:(KeyboardEventListenerBlock)listener
69
+ {
70
+ NSLog(@"Keyboard handling is not supported on tvOS");
71
+ return 0;
72
+ }
73
+
74
+ - (void)unsubscribeFromKeyboardEvents:(int)listenerId
75
+ {
76
+ NSLog(@"Keyboard handling is not supported on tvOS");
77
+ }
78
+ #else
79
+
80
+ - (void)runAnimation
81
+ {
82
+ displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateKeyboardFrame)];
83
+ [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
84
+ }
85
+
86
+ - (void)stopAnimation
87
+ {
88
+ [displayLink invalidate];
89
+ displayLink = nil;
90
+ [self updateKeyboardFrame];
91
+ }
92
+
93
+ - (void)updateKeyboardFrame
94
+ {
95
+ UIView *keyboardView = [self getKeyboardView];
96
+ if (keyboardView == nil) {
97
+ return;
98
+ }
99
+
100
+ CGFloat keyboardHeight = [self computeKeyboardHeight:keyboardView];
101
+ for (NSString *key in _listeners.allKeys) {
102
+ ((KeyboardEventListenerBlock)_listeners[key])(_state, keyboardHeight);
103
+ }
104
+ }
105
+
106
+ - (CGFloat)computeKeyboardHeight:(UIView *)keyboardView
107
+ {
108
+ CGFloat keyboardFrameY = [keyboardView.layer presentationLayer].frame.origin.y;
109
+ CGFloat keyboardWindowH = keyboardView.window.bounds.size.height;
110
+ CGFloat keyboardHeight = keyboardWindowH - keyboardFrameY;
111
+ return keyboardHeight;
112
+ }
113
+
114
+ - (void)keyboardWillShow:(NSNotification *)notification
115
+ {
116
+ _state = OPENING;
117
+ [self runAnimation];
118
+ }
119
+
120
+ - (void)keyboardDidShow:(NSNotification *)notification
121
+ {
122
+ _state = OPEN;
123
+ [self stopAnimation];
124
+ }
125
+
126
+ - (void)keyboardWillHide:(NSNotification *)notification
127
+ {
128
+ _state = CLOSING;
129
+ [self runAnimation];
130
+ }
131
+
132
+ - (void)keyboardDidHide:(NSNotification *)notification
133
+ {
134
+ _state = CLOSED;
135
+ [self stopAnimation];
136
+ }
137
+
138
+ - (int)subscribeForKeyboardEvents:(KeyboardEventListenerBlock)listener
139
+ {
140
+ NSNumber *listenerId = [_nextListenerId copy];
141
+ _nextListenerId = [NSNumber numberWithInt:[_nextListenerId intValue] + 1];
142
+ if ([_listeners count] == 0) {
143
+ NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
144
+
145
+ [notificationCenter addObserver:self
146
+ selector:@selector(keyboardWillHide:)
147
+ name:UIKeyboardWillHideNotification
148
+ object:nil];
149
+
150
+ [notificationCenter addObserver:self
151
+ selector:@selector(keyboardWillShow:)
152
+ name:UIKeyboardWillShowNotification
153
+ object:nil];
154
+
155
+ [notificationCenter addObserver:self
156
+ selector:@selector(keyboardDidHide:)
157
+ name:UIKeyboardDidHideNotification
158
+ object:nil];
159
+
160
+ [notificationCenter addObserver:self
161
+ selector:@selector(keyboardDidShow:)
162
+ name:UIKeyboardDidShowNotification
163
+ object:nil];
164
+ }
165
+
166
+ [_listeners setObject:listener forKey:listenerId];
167
+ if (_state == UNKNOWN) {
168
+ [self recognizeInitialKeyboardState];
169
+ }
170
+ return [listenerId intValue];
171
+ }
172
+
173
+ - (void)unsubscribeFromKeyboardEvents:(int)listenerId
174
+ {
175
+ NSNumber *_listenerId = [NSNumber numberWithInt:listenerId];
176
+ [_listeners removeObjectForKey:_listenerId];
177
+ if ([_listeners count] == 0) {
178
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
179
+ }
180
+ }
181
+
182
+ - (void)recognizeInitialKeyboardState
183
+ {
184
+ RCTExecuteOnMainQueue(^() {
185
+ UIView *keyboardView = [self getKeyboardView];
186
+ if (keyboardView == nil) {
187
+ self->_state = CLOSED;
188
+ } else {
189
+ CGFloat keyboardHeight = [self computeKeyboardHeight:keyboardView];
190
+ self->_state = keyboardHeight == 0 ? CLOSED : OPEN;
191
+ }
192
+ [self updateKeyboardFrame];
193
+ });
194
+ }
195
+
196
+ #endif
197
+
198
+ @end
@@ -4,6 +4,7 @@
4
4
  #import <RNReanimated/REAAnimationsManager.h>
5
5
  #import <RNReanimated/REAIOSErrorHandler.h>
6
6
  #import <RNReanimated/REAIOSScheduler.h>
7
+ #import <RNReanimated/REAKeyboardEventObserver.h>
7
8
  #import <RNReanimated/REAModule.h>
8
9
  #import <RNReanimated/REANodesManager.h>
9
10
  #import <RNReanimated/REAUIManager.h>
@@ -297,6 +298,21 @@ std::shared_ptr<NativeReanimatedModule> createReanimatedModule(
297
298
  auto unregisterSensorFunction = [=](int sensorId) { [reanimatedSensorContainer unregisterSensor:sensorId]; };
298
299
  // end sensors
299
300
 
301
+ // keyboard events
302
+
303
+ static REAKeyboardEventObserver *keyboardObserver = [[REAKeyboardEventObserver alloc] init];
304
+ auto subscribeForKeyboardEventsFunction =
305
+ [](std::function<void(int keyboardState, int height)> keyboardEventDataUpdater) {
306
+ return [keyboardObserver subscribeForKeyboardEvents:^(int keyboardState, int height) {
307
+ keyboardEventDataUpdater(keyboardState, height);
308
+ }];
309
+ };
310
+
311
+ auto unsubscribeFromKeyboardEventsFunction = [](int listenerId) {
312
+ [keyboardObserver unsubscribeFromKeyboardEvents:listenerId];
313
+ };
314
+ // end keyboard events
315
+
300
316
  PlatformDepMethodsHolder platformDepMethodsHolder = {
301
317
  requestRender,
302
318
  propUpdater,
@@ -306,7 +322,10 @@ std::shared_ptr<NativeReanimatedModule> createReanimatedModule(
306
322
  registerSensorFunction,
307
323
  unregisterSensorFunction,
308
324
  setGestureStateFunction,
309
- configurePropsFunction};
325
+ configurePropsFunction,
326
+ subscribeForKeyboardEventsFunction,
327
+ unsubscribeFromKeyboardEventsFunction,
328
+ };
310
329
 
311
330
  module = std::make_shared<NativeReanimatedModule>(
312
331
  jsInvoker,
@@ -45,20 +45,16 @@ JSIExecutor::RuntimeInstaller REAJSIExecutorRuntimeInstaller(
45
45
  auto callInvoker = std::make_shared<react::BridgeJSCallInvoker>(bridge.reactInstance);
46
46
  auto reanimatedModule = reanimated::createReanimatedModule(bridge, callInvoker);
47
47
  #endif
48
- auto workletRuntimeValue = runtime
49
- .global()
50
- .getProperty(runtime, "ArrayBuffer")
51
- .asObject(runtime)
52
- .asFunction(runtime)
53
- .callAsConstructor(runtime, {static_cast<double>(sizeof(void*))});
54
- uintptr_t* workletRuntimeData = reinterpret_cast<uintptr_t*>(
55
- workletRuntimeValue.getObject(runtime).getArrayBuffer(runtime).data(runtime));
48
+ auto workletRuntimeValue = runtime.global()
49
+ .getProperty(runtime, "ArrayBuffer")
50
+ .asObject(runtime)
51
+ .asFunction(runtime)
52
+ .callAsConstructor(runtime, {static_cast<double>(sizeof(void *))});
53
+ uintptr_t *workletRuntimeData =
54
+ reinterpret_cast<uintptr_t *>(workletRuntimeValue.getObject(runtime).getArrayBuffer(runtime).data(runtime));
56
55
  workletRuntimeData[0] = reinterpret_cast<uintptr_t>(reanimatedModule->runtime.get());
57
56
 
58
- runtime.global().setProperty(
59
- runtime,
60
- "_WORKLET_RUNTIME",
61
- workletRuntimeValue);
57
+ runtime.global().setProperty(runtime, "_WORKLET_RUNTIME", workletRuntimeValue);
62
58
 
63
59
  runtime.global().setProperty(
64
60
  runtime,
@@ -7,7 +7,11 @@
7
7
  {
8
8
  self = [super init];
9
9
  _sensorType = sensorType;
10
- _interval = interval / 1000; // in seconds
10
+ if (interval == -1) {
11
+ _interval = 1.0 / UIScreen.mainScreen.maximumFramesPerSecond;
12
+ } else {
13
+ _interval = interval / 1000.0; // in seconds
14
+ }
11
15
  _setter = setter;
12
16
  _motionManager = [[CMMotionManager alloc] init];
13
17
  return self;
@@ -59,18 +63,21 @@
59
63
  }
60
64
  [_motionManager setAccelerometerUpdateInterval:_interval];
61
65
  [_motionManager startAccelerometerUpdates];
62
- [_motionManager
63
- startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue]
64
- withHandler:^(CMAccelerometerData *sensorData, NSError *error) {
65
- double currentTime = [[NSProcessInfo processInfo] systemUptime];
66
- if (currentTime - self->_lastTimestamp < self->_interval) {
67
- return;
68
- }
69
- double data[] = {
70
- sensorData.acceleration.x, sensorData.acceleration.y, sensorData.acceleration.z};
71
- self->_setter(data);
72
- self->_lastTimestamp = currentTime;
73
- }];
66
+ [_motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue]
67
+ withHandler:^(CMAccelerometerData *sensorData, NSError *error) {
68
+ double currentTime = [[NSProcessInfo processInfo] systemUptime];
69
+ if (currentTime - self->_lastTimestamp < self->_interval) {
70
+ return;
71
+ }
72
+ double G = 9.81;
73
+ // convert G to m/s^2
74
+ double data[] = {
75
+ sensorData.acceleration.x * G,
76
+ sensorData.acceleration.y * G,
77
+ sensorData.acceleration.z * G};
78
+ self->_setter(data);
79
+ self->_lastTimestamp = currentTime;
80
+ }];
74
81
 
75
82
  return true;
76
83
  }
@@ -89,7 +96,10 @@
89
96
  if (currentTime - self->_lastTimestamp < self->_interval) {
90
97
  return;
91
98
  }
92
- double data[] = {sensorData.gravity.x, sensorData.gravity.y, sensorData.gravity.z};
99
+ double G = 9.81;
100
+ // convert G to m/s^2
101
+ double data[] = {
102
+ sensorData.gravity.x * G, sensorData.gravity.y * G, sensorData.gravity.z * G};
93
103
  self->_setter(data);
94
104
  self->_lastTimestamp = currentTime;
95
105
  }];
@@ -128,7 +138,7 @@
128
138
  [_motionManager setDeviceMotionUpdateInterval:_interval];
129
139
 
130
140
  [_motionManager setShowsDeviceMovementDisplay:YES];
131
- [_motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical
141
+ [_motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical
132
142
  toQueue:[NSOperationQueue mainQueue]
133
143
  withHandler:^(CMDeviceMotion *sensorData, NSError *error) {
134
144
  double currentTime = [[NSProcessInfo processInfo] systemUptime];
@@ -143,8 +153,7 @@
143
153
  attitude.quaternion.w,
144
154
  attitude.yaw,
145
155
  attitude.pitch,
146
- attitude.roll
147
- };
156
+ attitude.roll};
148
157
  self->_setter(data);
149
158
  self->_lastTimestamp = currentTime;
150
159
  }];
package/lib/index.js CHANGED
@@ -1,6 +1,14 @@
1
- // tree-shaken side effects
2
- import './reanimated2/js-reanimated/global';
1
+ import * as Animated from './Animated';
2
+ import webGlobalIsInitialized from './reanimated2/js-reanimated/global';
3
+ if (!webGlobalIsInitialized) {
4
+ /*
5
+ `webGlobalIsInitialized` should always be `true`,
6
+ but we need to use `webGlobalIsInitialized` somewhere to ensure function execution,
7
+ in another way, the bundler can remove unused variables.
8
+ */
9
+ console.error('[Reanimated] Unable to initialize global objects for web.');
10
+ }
3
11
  // @ts-ignore backward compatibility with treeshaking
4
12
  export * from './reanimated1';
5
13
  export * from './reanimated2';
6
- export * as default from './Animated';
14
+ export default Animated;
@@ -0,0 +1,4 @@
1
+ // tree-shaken side effects
2
+ import './reanimated2/js-reanimated/global';
3
+ export * from './reanimated2';
4
+ export * as default from './Animated'; // If this line fails, you probably forgot some installation steps. Check out the installation guide here: https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation/ 1) Make sure reanimated's babel plugin is installed in your babel.config.js (you should have 'react-native-reanimated/plugin' listed there - also see the above link for details) 2) Make sure you reset build cache after updating the config, run: yarn start --reset-cache
@@ -9,7 +9,7 @@
9
9
  import { Platform } from 'react-native';
10
10
  import { makeRemote, makeShareable, isConfigured } from './core';
11
11
  // var INTEGER = '[-+]?\\d+';
12
- const NUMBER = '[-+]?\\d*\\.?\\d+';
12
+ const NUMBER = '[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)';
13
13
  const PERCENTAGE = NUMBER + '%';
14
14
  function call(...args) {
15
15
  'worklet';
@@ -22,6 +22,9 @@ export function measure(animatedRef) {
22
22
  if (result.x === -1234567) {
23
23
  throw new Error(`The view with tag ${viewTag} could not be measured`);
24
24
  }
25
+ if (isNaN(result.x)) {
26
+ console.warn('Trying to measure a component which gets view-flattened on Android. To disable view-flattening, set `collapsable={false}` on this component.');
27
+ }
25
28
  return result;
26
29
  }
27
30
  export function scrollTo(animatedRef, x, y, animated) {
@@ -47,4 +47,10 @@ export class NativeReanimated {
47
47
  configureProps(uiProps, nativeProps) {
48
48
  this.InnerNativeModule.configureProps(uiProps, nativeProps);
49
49
  }
50
+ subscribeForKeyboardEvents(keyboardEventData) {
51
+ return this.InnerNativeModule.subscribeForKeyboardEvents(keyboardEventData);
52
+ }
53
+ unsubscribeFromKeyboardEvents(listenerId) {
54
+ this.InnerNativeModule.unsubscribeFromKeyboardEvents(listenerId);
55
+ }
50
56
  }
@@ -47,7 +47,10 @@ function decorateAnimation(animation) {
47
47
  animation.startValue = strippedValue;
48
48
  animation.toValue = strippedToValue;
49
49
  if (previousAnimation && previousAnimation !== animation) {
50
- previousAnimation.current = previousAnimation.strippedCurrent;
50
+ const { prefix: paPrefix, suffix: paSuffix, strippedValue: paStrippedValue, } = recognizePrefixSuffix(previousAnimation.current);
51
+ previousAnimation.current = paStrippedValue;
52
+ previousAnimation.__prefix = paPrefix;
53
+ previousAnimation.__suffix = paSuffix;
51
54
  }
52
55
  baseOnStart(animation, strippedValue, timestamp, previousAnimation);
53
56
  animation.current =
@@ -1 +1,8 @@
1
- export {};
1
+ export var KeyboardState;
2
+ (function (KeyboardState) {
3
+ KeyboardState[KeyboardState["UNKNOWN"] = 0] = "UNKNOWN";
4
+ KeyboardState[KeyboardState["OPENING"] = 1] = "OPENING";
5
+ KeyboardState[KeyboardState["OPEN"] = 2] = "OPEN";
6
+ KeyboardState[KeyboardState["CLOSING"] = 3] = "CLOSING";
7
+ KeyboardState[KeyboardState["CLOSED"] = 4] = "CLOSED";
8
+ })(KeyboardState || (KeyboardState = {}));
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import React from 'react';
12
+ import React, { forwardRef } from 'react';
13
13
  import { FlatList } from 'react-native';
14
14
  import ReanimatedView from './View';
15
15
  import createAnimatedComponent from '../../createAnimatedComponent';
@@ -22,9 +22,9 @@ const createCellRenderer = (itemLayoutAnimation) => {
22
22
  };
23
23
  return cellRenderer;
24
24
  };
25
- const ReanimatedFlatlist = (_a) => {
26
- var { itemLayoutAnimation } = _a, restProps = __rest(_a, ["itemLayoutAnimation"]);
25
+ const ReanimatedFlatlist = forwardRef((props, ref) => {
26
+ const { itemLayoutAnimation } = props, restProps = __rest(props, ["itemLayoutAnimation"]);
27
27
  const cellRenderer = React.useMemo(() => createCellRenderer(itemLayoutAnimation), []);
28
- return (<AnimatedFlatList {...restProps} CellRendererComponent={cellRenderer}/>);
29
- };
28
+ return (<AnimatedFlatList ref={ref} {...restProps} CellRendererComponent={cellRenderer}/>);
29
+ });
30
30
  export default ReanimatedFlatlist;
@@ -11,10 +11,13 @@ if (global._setGlobalConsole === undefined) {
11
11
  const testWorklet = () => {
12
12
  'worklet';
13
13
  };
14
+ const throwUninitializedReanimatedException = () => {
15
+ throw new Error("Failed to initialize react-native-reanimated library, make sure you followed installation steps here: https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation/ \n1) Make sure reanimated's babel plugin is installed in your babel.config.js (you should have 'react-native-reanimated/plugin' listed there - also see the above link for details) \n2) Make sure you reset build cache after updating the config, run: yarn start --reset-cache");
16
+ };
14
17
  export const checkPluginState = (throwError = true) => {
15
18
  if (!testWorklet.__workletHash && !shouldBeUseWeb()) {
16
19
  if (throwError) {
17
- throw new Error("Reanimated 2 failed to create a worklet, maybe you forgot to add Reanimated's babel plugin?");
20
+ throwUninitializedReanimatedException();
18
21
  }
19
22
  return false;
20
23
  }
@@ -24,9 +27,7 @@ export const isConfigured = (throwError = false) => {
24
27
  return checkPluginState(throwError);
25
28
  };
26
29
  export const isConfiguredCheck = () => {
27
- if (!isConfigured(true)) {
28
- throw new Error('If you want to use Reanimated 2 then go through our installation steps https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation');
29
- }
30
+ checkPluginState(true);
30
31
  };
31
32
  function pushFrame(frame) {
32
33
  NativeReanimatedModule.pushFrame(frame);
@@ -0,0 +1,32 @@
1
+ import { runOnUI } from '../core';
2
+ import { prepareUIRegistry } from './FrameCallbackRegistryUI';
3
+ export default class FrameCallbackRegistryJS {
4
+ constructor() {
5
+ this.nextCallbackId = 0;
6
+ prepareUIRegistry();
7
+ }
8
+ registerFrameCallback(callback) {
9
+ if (!callback) {
10
+ return -1;
11
+ }
12
+ const callbackId = this.nextCallbackId;
13
+ this.nextCallbackId++;
14
+ runOnUI(() => {
15
+ 'worklet';
16
+ global._frameCallbackRegistry.registerFrameCallback(callback, callbackId);
17
+ })();
18
+ return callbackId;
19
+ }
20
+ unregisterFrameCallback(frameCallbackId) {
21
+ runOnUI(() => {
22
+ 'worklet';
23
+ global._frameCallbackRegistry.unregisterFrameCallback(frameCallbackId);
24
+ })();
25
+ }
26
+ manageStateFrameCallback(frameCallbackId, state) {
27
+ runOnUI(() => {
28
+ 'worklet';
29
+ global._frameCallbackRegistry.manageStateFrameCallback(frameCallbackId, state);
30
+ })();
31
+ }
32
+ }
@@ -0,0 +1,47 @@
1
+ import { runOnUI } from '../core';
2
+ export const prepareUIRegistry = runOnUI(() => {
3
+ 'worklet';
4
+ const frameCallbackRegistry = {
5
+ frameCallbackRegistry: new Map(),
6
+ frameCallbackActive: new Set(),
7
+ isFrameCallbackRunning: false,
8
+ runCallbacks() {
9
+ const loop = () => {
10
+ this.frameCallbackActive.forEach((key) => {
11
+ const callback = this.frameCallbackRegistry.get(key);
12
+ callback();
13
+ });
14
+ if (this.frameCallbackActive.size > 0) {
15
+ requestAnimationFrame(loop);
16
+ }
17
+ else {
18
+ this.isFrameCallbackRunning = false;
19
+ }
20
+ };
21
+ if (!this.isFrameCallbackRunning) {
22
+ requestAnimationFrame(loop);
23
+ this.isFrameCallbackRunning = true;
24
+ }
25
+ },
26
+ registerFrameCallback(callback, callbackId) {
27
+ this.frameCallbackRegistry.set(callbackId, callback);
28
+ },
29
+ unregisterFrameCallback(frameCallbackId) {
30
+ this.manageStateFrameCallback(frameCallbackId, false);
31
+ this.frameCallbackRegistry.delete(frameCallbackId);
32
+ },
33
+ manageStateFrameCallback(frameCallbackId, state) {
34
+ if (frameCallbackId === -1) {
35
+ return;
36
+ }
37
+ if (state) {
38
+ this.frameCallbackActive.add(frameCallbackId);
39
+ this.runCallbacks();
40
+ }
41
+ else {
42
+ this.frameCallbackActive.delete(frameCallbackId);
43
+ }
44
+ },
45
+ };
46
+ global._frameCallbackRegistry = frameCallbackRegistry;
47
+ });
@@ -1,5 +1,6 @@
1
1
  import { AnimatedStyle, StyleProps } from './commonTypes';
2
2
  import { ReanimatedConsole } from './core';
3
+ import FrameCallbackRegistryUI from './frameCallback/FrameCallbackRegistryUI';
3
4
  import { MeasuredDimensions } from './NativeMethods';
4
5
  import { NativeReanimated } from './NativeReanimated/NativeReanimated';
5
6
  declare global {
@@ -30,6 +31,7 @@ declare global {
30
31
  const ReanimatedDataMock: {
31
32
  now: () => number;
32
33
  };
34
+ const _frameCallbackRegistry: FrameCallbackRegistryUI;
33
35
  namespace NodeJS {
34
36
  interface Global {
35
37
  _setGlobalConsole: (console?: ReanimatedConsole) => void;
@@ -55,6 +57,7 @@ declare global {
55
57
  ReanimatedDataMock: {
56
58
  now: () => number;
57
59
  };
60
+ _frameCallbackRegistry: FrameCallbackRegistryUI;
58
61
  }
59
62
  }
60
63
  }
@@ -7,3 +7,5 @@ export { useAnimatedRef } from './useAnimatedRef';
7
7
  export { useAnimatedScrollHandler, } from './useAnimatedScrollHandler';
8
8
  export { useDerivedValue } from './useDerivedValue';
9
9
  export { useAnimatedSensor, SensorType } from './useAnimatedSensor';
10
+ export { useFrameCallback } from './useFrameCallback';
11
+ export { useAnimatedKeyboard } from './useAnimatedKeyboard';
@@ -0,0 +1,31 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import NativeReanimated from '../NativeReanimated';
3
+ import { makeMutable } from '../core';
4
+ import { KeyboardState } from '../commonTypes';
5
+ export function useAnimatedKeyboard() {
6
+ const ref = useRef(null);
7
+ const listenerId = useRef(-1);
8
+ const isSubscribed = useRef(false);
9
+ if (ref.current === null) {
10
+ const keyboardEventData = {
11
+ state: makeMutable(KeyboardState.UNKNOWN),
12
+ height: makeMutable(0),
13
+ };
14
+ listenerId.current =
15
+ NativeReanimated.subscribeForKeyboardEvents(keyboardEventData);
16
+ ref.current = keyboardEventData;
17
+ isSubscribed.current = true;
18
+ }
19
+ useEffect(() => {
20
+ if (isSubscribed.current === false && ref.current !== null) {
21
+ // subscribe again after Fast Refresh
22
+ listenerId.current = NativeReanimated.subscribeForKeyboardEvents(ref.current);
23
+ isSubscribed.current = true;
24
+ }
25
+ return () => {
26
+ NativeReanimated.unsubscribeFromKeyboardEvents(listenerId.current);
27
+ isSubscribed.current = false;
28
+ };
29
+ }, []);
30
+ return ref.current;
31
+ }
@@ -21,7 +21,7 @@ export function useAnimatedSensor(sensorType, userConfig) {
21
21
  },
22
22
  });
23
23
  if (ref.current.sensor === null) {
24
- ref.current.config = Object.assign({ interval: 10 }, userConfig);
24
+ ref.current.config = Object.assign({ interval: 'auto' }, userConfig);
25
25
  let sensorData;
26
26
  if (sensorType === SensorType.ROTATION) {
27
27
  sensorData = {
@@ -44,8 +44,8 @@ export function useAnimatedSensor(sensorType, userConfig) {
44
44
  ref.current.sensor = makeMutable(sensorData);
45
45
  }
46
46
  useEffect(() => {
47
- ref.current.config = Object.assign({ interval: 10 }, userConfig);
48
- const id = NativeReanimated.registerSensor(sensorType, ref.current.config.interval, ref.current.sensor);
47
+ ref.current.config = Object.assign({ interval: 'auto' }, userConfig);
48
+ const id = NativeReanimated.registerSensor(sensorType, ref.current.config.interval === 'auto' ? -1 : ref.current.config.interval, ref.current.sensor);
49
49
  if (id !== -1) {
50
50
  // if sensor is available
51
51
  ref.current.unregister = () => NativeReanimated.unregisterSensor(id);
@@ -0,0 +1,23 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import FrameCallbackRegistryJS from '../frameCallback/FrameCallbackRegistryJS';
3
+ const frameCallbackRegistry = new FrameCallbackRegistryJS();
4
+ export function useFrameCallback(callback, autostart = true) {
5
+ const ref = useRef({
6
+ setActive: (isActive) => {
7
+ frameCallbackRegistry.manageStateFrameCallback(ref.current.callbackId, isActive);
8
+ ref.current.isActive = isActive;
9
+ },
10
+ isActive: autostart,
11
+ callbackId: -1,
12
+ });
13
+ useEffect(() => {
14
+ ref.current.callbackId =
15
+ frameCallbackRegistry.registerFrameCallback(callback);
16
+ ref.current.setActive(ref.current.isActive);
17
+ return () => {
18
+ frameCallbackRegistry.unregisterFrameCallback(ref.current.callbackId);
19
+ ref.current.callbackId = -1;
20
+ };
21
+ }, [callback, autostart]);
22
+ return ref.current;
23
+ }