react-native-windows 0.0.0-canary.508 → 0.0.0-canary.511
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.
- package/.flowconfig +3 -1
- package/Libraries/Animated/NativeAnimatedHelper.js +212 -93
- package/Libraries/Animated/NativeAnimatedModule.js +3 -0
- package/Libraries/Animated/NativeAnimatedTurboModule.js +3 -0
- package/Libraries/Animated/nodes/AnimatedColor.js +49 -28
- package/Libraries/Animated/nodes/AnimatedProps.js +1 -5
- package/Libraries/Animated/nodes/AnimatedStyle.js +1 -5
- package/Libraries/Animated/nodes/AnimatedValue.js +11 -4
- package/Libraries/Animated/nodes/AnimatedValueXY.js +27 -0
- package/Libraries/Animated/useAnimatedProps.js +1 -0
- package/Libraries/BatchedBridge/MessageQueue.js +16 -9
- package/Libraries/Blob/FileReader.js +0 -6
- package/Libraries/Components/ScrollView/ScrollView.js +2 -2
- package/Libraries/Components/TextInput/TextInput.js +1 -1
- package/Libraries/Components/TextInput/TextInput.windows.js +1 -1
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Lists/VirtualizeUtils.js +27 -18
- package/Libraries/Lists/VirtualizedList.js +3 -2
- package/Libraries/Lists/__tests__/VirtualizeUtils-test.js +14 -13
- package/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js +3 -0
- package/Libraries/Performance/PureComponentDebug.js +1 -0
- package/Libraries/PermissionsAndroid/NativePermissionsAndroid.js +7 -1
- package/Libraries/PermissionsAndroid/PermissionsAndroid.js +12 -0
- package/Libraries/Pressability/Pressability.js +3 -4
- package/Libraries/Pressability/Pressability.windows.js +3 -4
- package/Libraries/ReactNative/ReactNativeFeatureFlags.js +12 -0
- package/Libraries/StyleSheet/splitLayoutProps.js +2 -0
- package/Libraries/Types/CoreEventTypes.js +128 -11
- package/Libraries/Types/CoreEventTypes.windows.js +138 -22
- package/Libraries/Utilities/codegenNativeCommands.js +10 -1
- package/Microsoft.ReactNative.Managed/packages.lock.json +4 -4
- package/PropertySheets/Generated/PackageVersion.g.props +1 -1
- package/PropertySheets/JSEngine.props +1 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/graphics/RectangleEdges.h +100 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/YGValue.h +94 -0
- package/Shared/InspectorPackagerConnection.cpp +2 -2
- package/Shared/OInstance.cpp +15 -11
- package/codegen/NativeAnimatedModuleSpec.g.h +6 -0
- package/codegen/NativeAnimatedTurboModuleSpec.g.h +6 -0
- package/package.json +8 -8
- package/stubs/double-conversion/double-conversion.h +18 -9
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h +0 -87
package/.flowconfig
CHANGED
|
@@ -98,6 +98,8 @@ suppress_type=$FlowFixMeProps
|
|
|
98
98
|
suppress_type=$FlowFixMeState
|
|
99
99
|
suppress_type=$FlowFixMeEmpty
|
|
100
100
|
|
|
101
|
+
experimental.env_mode=ssa
|
|
102
|
+
|
|
101
103
|
[lints]
|
|
102
104
|
sketchy-null-number=warn
|
|
103
105
|
sketchy-null-mixed=warn
|
|
@@ -118,4 +120,4 @@ untyped-import
|
|
|
118
120
|
untyped-type-import
|
|
119
121
|
|
|
120
122
|
[version]
|
|
121
|
-
^0.
|
|
123
|
+
^0.179.0
|
|
@@ -20,7 +20,10 @@ import type {
|
|
|
20
20
|
} from './NativeAnimatedModule';
|
|
21
21
|
import type {AnimationConfig, EndCallback} from './animations/Animation';
|
|
22
22
|
import type {InterpolationConfigType} from './nodes/AnimatedInterpolation';
|
|
23
|
+
import ReactNativeFeatureFlags from '../ReactNative/ReactNativeFeatureFlags';
|
|
23
24
|
import invariant from 'invariant';
|
|
25
|
+
import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter';
|
|
26
|
+
import type {EventSubscription} from '../vendor/emitter/EventEmitter';
|
|
24
27
|
|
|
25
28
|
// TODO T69437152 @petetheheat - Delete this fork when Fabric ships to 100%.
|
|
26
29
|
const NativeAnimatedModule =
|
|
@@ -36,24 +39,82 @@ let nativeEventEmitter;
|
|
|
36
39
|
let waitingForQueuedOperations = new Set();
|
|
37
40
|
let queueOperations = false;
|
|
38
41
|
let queue: Array<() => void> = [];
|
|
42
|
+
// $FlowFixMe
|
|
43
|
+
let singleOpQueue: Array<any> = [];
|
|
44
|
+
|
|
45
|
+
const useSingleOpBatching =
|
|
46
|
+
Platform.OS === 'android' &&
|
|
47
|
+
!!NativeAnimatedModule?.queueAndExecuteBatchedOperations &&
|
|
48
|
+
ReactNativeFeatureFlags.animatedShouldUseSingleOp();
|
|
49
|
+
let flushQueueTimeout = null;
|
|
50
|
+
|
|
51
|
+
const eventListenerGetValueCallbacks = {};
|
|
52
|
+
const eventListenerAnimationFinishedCallbacks = {};
|
|
53
|
+
let globalEventEmitterGetValueListener: ?EventSubscription = null;
|
|
54
|
+
let globalEventEmitterAnimationFinishedListener: ?EventSubscription = null;
|
|
55
|
+
|
|
56
|
+
const nativeOps: ?typeof NativeAnimatedModule = useSingleOpBatching
|
|
57
|
+
? ((function () {
|
|
58
|
+
const apis = [
|
|
59
|
+
'createAnimatedNode', // 1
|
|
60
|
+
'updateAnimatedNodeConfig', // 2
|
|
61
|
+
'getValue', // 3
|
|
62
|
+
'startListeningToAnimatedNodeValue', // 4
|
|
63
|
+
'stopListeningToAnimatedNodeValue', // 5
|
|
64
|
+
'connectAnimatedNodes', // 6
|
|
65
|
+
'disconnectAnimatedNodes', // 7
|
|
66
|
+
'startAnimatingNode', // 8
|
|
67
|
+
'stopAnimation', // 9
|
|
68
|
+
'setAnimatedNodeValue', // 10
|
|
69
|
+
'setAnimatedNodeOffset', // 11
|
|
70
|
+
'flattenAnimatedNodeOffset', // 12
|
|
71
|
+
'extractAnimatedNodeOffset', // 13
|
|
72
|
+
'connectAnimatedNodeToView', // 14
|
|
73
|
+
'disconnectAnimatedNodeFromView', // 15
|
|
74
|
+
'restoreDefaultValues', // 16
|
|
75
|
+
'dropAnimatedNode', // 17
|
|
76
|
+
'addAnimatedEventToView', // 18
|
|
77
|
+
'removeAnimatedEventFromView', // 19
|
|
78
|
+
'addListener', // 20
|
|
79
|
+
'removeListener', // 21
|
|
80
|
+
];
|
|
81
|
+
return apis.reduce((acc, functionName, i) => {
|
|
82
|
+
// These indices need to be kept in sync with the indices in native (see NativeAnimatedModule in Java, or the equivalent for any other native platform).
|
|
83
|
+
acc[functionName] = i + 1;
|
|
84
|
+
return acc;
|
|
85
|
+
}, {});
|
|
86
|
+
})(): $FlowFixMe)
|
|
87
|
+
: NativeAnimatedModule;
|
|
39
88
|
|
|
40
89
|
/**
|
|
41
|
-
*
|
|
42
|
-
* the native module methods
|
|
90
|
+
* Wrappers around NativeAnimatedModule to provide flow and autocomplete support for
|
|
91
|
+
* the native module methods, and automatic queue management on Android
|
|
43
92
|
*/
|
|
44
93
|
const API = {
|
|
45
94
|
getValue: function (
|
|
46
95
|
tag: number,
|
|
47
96
|
saveValueCallback: (value: number) => void,
|
|
48
97
|
): void {
|
|
49
|
-
invariant(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
98
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
99
|
+
if (useSingleOpBatching) {
|
|
100
|
+
if (saveValueCallback) {
|
|
101
|
+
eventListenerGetValueCallbacks[tag] = saveValueCallback;
|
|
102
|
+
}
|
|
103
|
+
// $FlowFixMe
|
|
104
|
+
API.queueOperation(nativeOps.getValue, tag);
|
|
105
|
+
} else {
|
|
106
|
+
API.queueOperation(nativeOps.getValue, tag, saveValueCallback);
|
|
107
|
+
}
|
|
53
108
|
},
|
|
54
109
|
setWaitingForIdentifier: function (id: string): void {
|
|
55
110
|
waitingForQueuedOperations.add(id);
|
|
56
111
|
queueOperations = true;
|
|
112
|
+
if (
|
|
113
|
+
ReactNativeFeatureFlags.animatedShouldDebounceQueueFlush() &&
|
|
114
|
+
flushQueueTimeout
|
|
115
|
+
) {
|
|
116
|
+
clearTimeout(flushQueueTimeout);
|
|
117
|
+
}
|
|
57
118
|
},
|
|
58
119
|
unsetWaitingForIdentifier: function (id: string): void {
|
|
59
120
|
waitingForQueuedOperations.delete(id);
|
|
@@ -64,73 +125,103 @@ const API = {
|
|
|
64
125
|
}
|
|
65
126
|
},
|
|
66
127
|
disableQueue: function (): void {
|
|
128
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
129
|
+
|
|
130
|
+
if (ReactNativeFeatureFlags.animatedShouldDebounceQueueFlush()) {
|
|
131
|
+
const prevTimeout = flushQueueTimeout;
|
|
132
|
+
clearImmediate(prevTimeout);
|
|
133
|
+
flushQueueTimeout = setImmediate(API.flushQueue);
|
|
134
|
+
} else {
|
|
135
|
+
API.flushQueue();
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
flushQueue: function (): void {
|
|
67
139
|
invariant(NativeAnimatedModule, 'Native animated module is not available');
|
|
140
|
+
flushQueueTimeout = null;
|
|
68
141
|
|
|
69
|
-
|
|
70
|
-
|
|
142
|
+
// Early returns before calling any APIs
|
|
143
|
+
if (useSingleOpBatching && singleOpQueue.length === 0) {
|
|
144
|
+
return;
|
|
71
145
|
}
|
|
72
|
-
|
|
73
|
-
|
|
146
|
+
if (!useSingleOpBatching && queue.length === 0) {
|
|
147
|
+
return;
|
|
74
148
|
}
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
149
|
+
|
|
150
|
+
if (useSingleOpBatching) {
|
|
151
|
+
// Set up event listener for callbacks if it's not set up
|
|
152
|
+
if (
|
|
153
|
+
!globalEventEmitterGetValueListener ||
|
|
154
|
+
!globalEventEmitterAnimationFinishedListener
|
|
155
|
+
) {
|
|
156
|
+
setupGlobalEventEmitterListeners();
|
|
157
|
+
}
|
|
158
|
+
// Single op batching doesn't use callback functions, instead we
|
|
159
|
+
// use RCTDeviceEventEmitter. This reduces overhead of sending lots of
|
|
160
|
+
// JSI functions across to native code; but also, TM infrastructure currently
|
|
161
|
+
// does not support packing a function into native arrays.
|
|
162
|
+
NativeAnimatedModule.queueAndExecuteBatchedOperations?.(singleOpQueue);
|
|
163
|
+
singleOpQueue.length = 0;
|
|
164
|
+
} else {
|
|
165
|
+
Platform.OS === 'android' && NativeAnimatedModule.startOperationBatch?.();
|
|
166
|
+
for (let q = 0, l = queue.length; q < l; q++) {
|
|
167
|
+
queue[q]();
|
|
168
|
+
}
|
|
169
|
+
queue.length = 0;
|
|
170
|
+
Platform.OS === 'android' &&
|
|
171
|
+
NativeAnimatedModule.finishOperationBatch?.();
|
|
78
172
|
}
|
|
79
173
|
},
|
|
80
|
-
queueOperation:
|
|
174
|
+
queueOperation: <Args: $ReadOnlyArray<mixed>, Fn: (...Args) => void>(
|
|
175
|
+
fn: Fn,
|
|
176
|
+
...args: Args
|
|
177
|
+
): void => {
|
|
178
|
+
if (useSingleOpBatching) {
|
|
179
|
+
// Get the command ID from the queued function, and push that ID and any arguments needed to execute the operation
|
|
180
|
+
// $FlowFixMe: surprise, fn is actually a number
|
|
181
|
+
singleOpQueue.push(fn, ...args);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
81
185
|
// If queueing is explicitly on, *or* the queue has not yet
|
|
82
186
|
// been flushed, use the queue. This is to prevent operations
|
|
83
187
|
// from being executed out of order.
|
|
84
188
|
if (queueOperations || queue.length !== 0) {
|
|
85
|
-
queue.push(fn);
|
|
189
|
+
queue.push(() => fn(...args));
|
|
86
190
|
} else {
|
|
87
|
-
fn();
|
|
191
|
+
fn(...args);
|
|
88
192
|
}
|
|
89
193
|
},
|
|
90
194
|
createAnimatedNode: function (tag: number, config: AnimatedNodeConfig): void {
|
|
91
|
-
invariant(
|
|
92
|
-
API.queueOperation(
|
|
93
|
-
NativeAnimatedModule.createAnimatedNode(tag, config),
|
|
94
|
-
);
|
|
195
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
196
|
+
API.queueOperation(nativeOps.createAnimatedNode, tag, config);
|
|
95
197
|
},
|
|
96
198
|
updateAnimatedNodeConfig: function (
|
|
97
199
|
tag: number,
|
|
98
200
|
config: AnimatedNodeConfig,
|
|
99
201
|
): void {
|
|
100
|
-
invariant(
|
|
101
|
-
if (
|
|
102
|
-
API.queueOperation(
|
|
103
|
-
// $FlowIgnore[not-a-function] - checked above
|
|
104
|
-
NativeAnimatedModule.updateAnimatedNodeConfig(tag, config),
|
|
105
|
-
);
|
|
202
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
203
|
+
if (nativeOps.updateAnimatedNodeConfig) {
|
|
204
|
+
API.queueOperation(nativeOps.updateAnimatedNodeConfig, tag, config);
|
|
106
205
|
}
|
|
107
206
|
},
|
|
108
207
|
startListeningToAnimatedNodeValue: function (tag: number) {
|
|
109
|
-
invariant(
|
|
110
|
-
API.queueOperation(
|
|
111
|
-
NativeAnimatedModule.startListeningToAnimatedNodeValue(tag),
|
|
112
|
-
);
|
|
208
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
209
|
+
API.queueOperation(nativeOps.startListeningToAnimatedNodeValue, tag);
|
|
113
210
|
},
|
|
114
211
|
stopListeningToAnimatedNodeValue: function (tag: number) {
|
|
115
|
-
invariant(
|
|
116
|
-
API.queueOperation(
|
|
117
|
-
NativeAnimatedModule.stopListeningToAnimatedNodeValue(tag),
|
|
118
|
-
);
|
|
212
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
213
|
+
API.queueOperation(nativeOps.stopListeningToAnimatedNodeValue, tag);
|
|
119
214
|
},
|
|
120
215
|
connectAnimatedNodes: function (parentTag: number, childTag: number): void {
|
|
121
|
-
invariant(
|
|
122
|
-
API.queueOperation(
|
|
123
|
-
NativeAnimatedModule.connectAnimatedNodes(parentTag, childTag),
|
|
124
|
-
);
|
|
216
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
217
|
+
API.queueOperation(nativeOps.connectAnimatedNodes, parentTag, childTag);
|
|
125
218
|
},
|
|
126
219
|
disconnectAnimatedNodes: function (
|
|
127
220
|
parentTag: number,
|
|
128
221
|
childTag: number,
|
|
129
222
|
): void {
|
|
130
|
-
invariant(
|
|
131
|
-
API.queueOperation(
|
|
132
|
-
NativeAnimatedModule.disconnectAnimatedNodes(parentTag, childTag),
|
|
133
|
-
);
|
|
223
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
224
|
+
API.queueOperation(nativeOps.disconnectAnimatedNodes, parentTag, childTag);
|
|
134
225
|
},
|
|
135
226
|
startAnimatingNode: function (
|
|
136
227
|
animationId: number,
|
|
@@ -138,84 +229,85 @@ const API = {
|
|
|
138
229
|
config: AnimatingNodeConfig,
|
|
139
230
|
endCallback: EndCallback,
|
|
140
231
|
): void {
|
|
141
|
-
invariant(
|
|
142
|
-
|
|
143
|
-
|
|
232
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
233
|
+
if (useSingleOpBatching) {
|
|
234
|
+
if (endCallback) {
|
|
235
|
+
eventListenerAnimationFinishedCallbacks[animationId] = endCallback;
|
|
236
|
+
}
|
|
237
|
+
// $FlowFixMe
|
|
238
|
+
API.queueOperation(
|
|
239
|
+
nativeOps.startAnimatingNode,
|
|
240
|
+
animationId,
|
|
241
|
+
nodeTag,
|
|
242
|
+
config,
|
|
243
|
+
);
|
|
244
|
+
} else {
|
|
245
|
+
API.queueOperation(
|
|
246
|
+
nativeOps.startAnimatingNode,
|
|
144
247
|
animationId,
|
|
145
248
|
nodeTag,
|
|
146
249
|
config,
|
|
147
250
|
endCallback,
|
|
148
|
-
)
|
|
149
|
-
|
|
251
|
+
);
|
|
252
|
+
}
|
|
150
253
|
},
|
|
151
254
|
stopAnimation: function (animationId: number) {
|
|
152
|
-
invariant(
|
|
153
|
-
API.queueOperation(
|
|
255
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
256
|
+
API.queueOperation(nativeOps.stopAnimation, animationId);
|
|
154
257
|
},
|
|
155
258
|
setAnimatedNodeValue: function (nodeTag: number, value: number): void {
|
|
156
|
-
invariant(
|
|
157
|
-
API.queueOperation(
|
|
158
|
-
NativeAnimatedModule.setAnimatedNodeValue(nodeTag, value),
|
|
159
|
-
);
|
|
259
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
260
|
+
API.queueOperation(nativeOps.setAnimatedNodeValue, nodeTag, value);
|
|
160
261
|
},
|
|
161
262
|
setAnimatedNodeOffset: function (nodeTag: number, offset: number): void {
|
|
162
|
-
invariant(
|
|
163
|
-
API.queueOperation(
|
|
164
|
-
NativeAnimatedModule.setAnimatedNodeOffset(nodeTag, offset),
|
|
165
|
-
);
|
|
263
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
264
|
+
API.queueOperation(nativeOps.setAnimatedNodeOffset, nodeTag, offset);
|
|
166
265
|
},
|
|
167
266
|
flattenAnimatedNodeOffset: function (nodeTag: number): void {
|
|
168
|
-
invariant(
|
|
169
|
-
API.queueOperation(
|
|
170
|
-
NativeAnimatedModule.flattenAnimatedNodeOffset(nodeTag),
|
|
171
|
-
);
|
|
267
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
268
|
+
API.queueOperation(nativeOps.flattenAnimatedNodeOffset, nodeTag);
|
|
172
269
|
},
|
|
173
270
|
extractAnimatedNodeOffset: function (nodeTag: number): void {
|
|
174
|
-
invariant(
|
|
175
|
-
API.queueOperation(
|
|
176
|
-
NativeAnimatedModule.extractAnimatedNodeOffset(nodeTag),
|
|
177
|
-
);
|
|
271
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
272
|
+
API.queueOperation(nativeOps.extractAnimatedNodeOffset, nodeTag);
|
|
178
273
|
},
|
|
179
274
|
connectAnimatedNodeToView: function (nodeTag: number, viewTag: number): void {
|
|
180
|
-
invariant(
|
|
181
|
-
API.queueOperation(
|
|
182
|
-
NativeAnimatedModule.connectAnimatedNodeToView(nodeTag, viewTag),
|
|
183
|
-
);
|
|
275
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
276
|
+
API.queueOperation(nativeOps.connectAnimatedNodeToView, nodeTag, viewTag);
|
|
184
277
|
},
|
|
185
278
|
disconnectAnimatedNodeFromView: function (
|
|
186
279
|
nodeTag: number,
|
|
187
280
|
viewTag: number,
|
|
188
281
|
): void {
|
|
189
|
-
invariant(
|
|
190
|
-
API.queueOperation(
|
|
191
|
-
|
|
282
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
283
|
+
API.queueOperation(
|
|
284
|
+
nativeOps.disconnectAnimatedNodeFromView,
|
|
285
|
+
nodeTag,
|
|
286
|
+
viewTag,
|
|
192
287
|
);
|
|
193
288
|
},
|
|
194
289
|
restoreDefaultValues: function (nodeTag: number): void {
|
|
195
|
-
invariant(
|
|
290
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
196
291
|
// Backwards compat with older native runtimes, can be removed later.
|
|
197
|
-
if (
|
|
198
|
-
API.queueOperation(
|
|
199
|
-
NativeAnimatedModule.restoreDefaultValues(nodeTag),
|
|
200
|
-
);
|
|
292
|
+
if (nativeOps.restoreDefaultValues != null) {
|
|
293
|
+
API.queueOperation(nativeOps.restoreDefaultValues, nodeTag);
|
|
201
294
|
}
|
|
202
295
|
},
|
|
203
296
|
dropAnimatedNode: function (tag: number): void {
|
|
204
|
-
invariant(
|
|
205
|
-
API.queueOperation(
|
|
297
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
298
|
+
API.queueOperation(nativeOps.dropAnimatedNode, tag);
|
|
206
299
|
},
|
|
207
300
|
addAnimatedEventToView: function (
|
|
208
301
|
viewTag: number,
|
|
209
302
|
eventName: string,
|
|
210
303
|
eventMapping: EventMapping,
|
|
211
304
|
) {
|
|
212
|
-
invariant(
|
|
213
|
-
API.queueOperation(
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
),
|
|
305
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
306
|
+
API.queueOperation(
|
|
307
|
+
nativeOps.addAnimatedEventToView,
|
|
308
|
+
viewTag,
|
|
309
|
+
eventName,
|
|
310
|
+
eventMapping,
|
|
219
311
|
);
|
|
220
312
|
},
|
|
221
313
|
removeAnimatedEventFromView(
|
|
@@ -223,17 +315,44 @@ const API = {
|
|
|
223
315
|
eventName: string,
|
|
224
316
|
animatedNodeTag: number,
|
|
225
317
|
) {
|
|
226
|
-
invariant(
|
|
227
|
-
API.queueOperation(
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
),
|
|
318
|
+
invariant(nativeOps, 'Native animated module is not available');
|
|
319
|
+
API.queueOperation(
|
|
320
|
+
nativeOps.removeAnimatedEventFromView,
|
|
321
|
+
viewTag,
|
|
322
|
+
eventName,
|
|
323
|
+
animatedNodeTag,
|
|
233
324
|
);
|
|
234
325
|
},
|
|
235
326
|
};
|
|
236
327
|
|
|
328
|
+
function setupGlobalEventEmitterListeners() {
|
|
329
|
+
globalEventEmitterGetValueListener = RCTDeviceEventEmitter.addListener(
|
|
330
|
+
'onNativeAnimatedModuleGetValue',
|
|
331
|
+
function (params) {
|
|
332
|
+
const {tag} = params;
|
|
333
|
+
const callback = eventListenerGetValueCallbacks[tag];
|
|
334
|
+
if (!callback) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
callback(params.value);
|
|
338
|
+
delete eventListenerGetValueCallbacks[tag];
|
|
339
|
+
},
|
|
340
|
+
);
|
|
341
|
+
globalEventEmitterAnimationFinishedListener =
|
|
342
|
+
RCTDeviceEventEmitter.addListener(
|
|
343
|
+
'onNativeAnimatedModuleAnimationFinished',
|
|
344
|
+
function (params) {
|
|
345
|
+
const {animationId} = params;
|
|
346
|
+
const callback = eventListenerAnimationFinishedCallbacks[animationId];
|
|
347
|
+
if (!callback) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
callback(params);
|
|
351
|
+
delete eventListenerAnimationFinishedCallbacks[animationId];
|
|
352
|
+
},
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
237
356
|
/**
|
|
238
357
|
* Styles allowed by the native animated implementation.
|
|
239
358
|
*
|
|
@@ -64,6 +64,9 @@ export interface Spec extends TurboModule {
|
|
|
64
64
|
// Events
|
|
65
65
|
+addListener: (eventName: string) => void;
|
|
66
66
|
+removeListeners: (count: number) => void;
|
|
67
|
+
|
|
68
|
+
// All of the above in a batched mode
|
|
69
|
+
+queueAndExecuteBatchedOperations?: (operationsAndArgs: Array<any>) => void;
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
export default (TurboModuleRegistry.get<Spec>('NativeAnimatedModule'): ?Spec);
|
|
@@ -64,6 +64,9 @@ export interface Spec extends TurboModule {
|
|
|
64
64
|
// Events
|
|
65
65
|
+addListener: (eventName: string) => void;
|
|
66
66
|
+removeListeners: (count: number) => void;
|
|
67
|
+
|
|
68
|
+
// All of the above in a batched mode
|
|
69
|
+
+queueAndExecuteBatchedOperations?: (operationsAndArgs: Array<any>) => void;
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
export default (TurboModuleRegistry.get<Spec>(
|
|
@@ -21,7 +21,12 @@ import type {ColorValue} from '../../StyleSheet/StyleSheet';
|
|
|
21
21
|
import type {NativeColorValue} from '../../StyleSheet/PlatformColorValueTypes';
|
|
22
22
|
import type {ProcessedColorValue} from '../../StyleSheet/processColor';
|
|
23
23
|
|
|
24
|
-
type
|
|
24
|
+
export type AnimatedColorConfig = $ReadOnly<{
|
|
25
|
+
useNativeDriver: boolean,
|
|
26
|
+
}>;
|
|
27
|
+
|
|
28
|
+
type ColorListenerCallback = (value: ColorValue) => mixed;
|
|
29
|
+
|
|
25
30
|
export type RgbaValue = {
|
|
26
31
|
+r: number,
|
|
27
32
|
+g: number,
|
|
@@ -29,6 +34,7 @@ export type RgbaValue = {
|
|
|
29
34
|
+a: number,
|
|
30
35
|
...
|
|
31
36
|
};
|
|
37
|
+
|
|
32
38
|
type RgbaAnimatedValue = {
|
|
33
39
|
+r: AnimatedValue,
|
|
34
40
|
+g: AnimatedValue,
|
|
@@ -37,6 +43,8 @@ type RgbaAnimatedValue = {
|
|
|
37
43
|
...
|
|
38
44
|
};
|
|
39
45
|
|
|
46
|
+
const NativeAnimatedAPI = NativeAnimatedHelper.API;
|
|
47
|
+
|
|
40
48
|
const defaultColor: RgbaValue = {r: 0, g: 0, b: 0, a: 1.0};
|
|
41
49
|
let _uniqueId = 1;
|
|
42
50
|
|
|
@@ -116,7 +124,10 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
|
|
116
124
|
...
|
|
117
125
|
} = {};
|
|
118
126
|
|
|
119
|
-
constructor(
|
|
127
|
+
constructor(
|
|
128
|
+
valueIn?: ?(RgbaValue | RgbaAnimatedValue | ColorValue),
|
|
129
|
+
config?: ?AnimatedColorConfig,
|
|
130
|
+
) {
|
|
120
131
|
super();
|
|
121
132
|
let value: RgbaValue | RgbaAnimatedValue | ColorValue =
|
|
122
133
|
valueIn ?? defaultColor;
|
|
@@ -144,12 +155,9 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
|
|
144
155
|
this.g = new AnimatedValue(initColor.g);
|
|
145
156
|
this.b = new AnimatedValue(initColor.b);
|
|
146
157
|
this.a = new AnimatedValue(initColor.a);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
this.__makeNative();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
158
|
+
}
|
|
159
|
+
if (this.nativeColor || (config && config.useNativeDriver)) {
|
|
160
|
+
this.__makeNative();
|
|
153
161
|
}
|
|
154
162
|
}
|
|
155
163
|
|
|
@@ -158,34 +166,43 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
|
|
158
166
|
* and update all the bound properties.
|
|
159
167
|
*/
|
|
160
168
|
setValue(value: RgbaValue | ColorValue): void {
|
|
161
|
-
|
|
169
|
+
let shouldUpdateNodeConfig = false;
|
|
170
|
+
if (this.__isNative) {
|
|
171
|
+
const nativeTag = this.__getNativeTag();
|
|
172
|
+
NativeAnimatedAPI.setWaitingForIdentifier(nativeTag.toString());
|
|
173
|
+
}
|
|
162
174
|
|
|
163
175
|
const processedColor: RgbaValue | NativeColorValue =
|
|
164
176
|
processColor(value) ?? defaultColor;
|
|
165
177
|
if (isRgbaValue(processedColor)) {
|
|
166
|
-
// $FlowIgnore[incompatible-
|
|
167
|
-
const rgbaValue: RgbaValue =
|
|
178
|
+
// $FlowIgnore[incompatible-type] - Type is verified above
|
|
179
|
+
const rgbaValue: RgbaValue = processedColor;
|
|
168
180
|
this.r.setValue(rgbaValue.r);
|
|
169
181
|
this.g.setValue(rgbaValue.g);
|
|
170
182
|
this.b.setValue(rgbaValue.b);
|
|
171
183
|
this.a.setValue(rgbaValue.a);
|
|
184
|
+
if (this.nativeColor != null) {
|
|
185
|
+
this.nativeColor = null;
|
|
186
|
+
shouldUpdateNodeConfig = true;
|
|
187
|
+
}
|
|
172
188
|
} else {
|
|
173
|
-
// $FlowIgnore[incompatible-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (!this.__isNative) {
|
|
179
|
-
this.__makeNative();
|
|
189
|
+
// $FlowIgnore[incompatible-type] - Type is verified above
|
|
190
|
+
const nativeColor: NativeColorValue = processedColor;
|
|
191
|
+
if (this.nativeColor !== nativeColor) {
|
|
192
|
+
this.nativeColor = nativeColor;
|
|
193
|
+
shouldUpdateNodeConfig = true;
|
|
180
194
|
}
|
|
195
|
+
}
|
|
181
196
|
|
|
197
|
+
if (this.__isNative) {
|
|
182
198
|
const nativeTag = this.__getNativeTag();
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
199
|
+
if (shouldUpdateNodeConfig) {
|
|
200
|
+
NativeAnimatedAPI.updateAnimatedNodeConfig(
|
|
201
|
+
nativeTag,
|
|
202
|
+
this.__getNativeConfig(),
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
NativeAnimatedAPI.unsetWaitingForIdentifier(nativeTag.toString());
|
|
189
206
|
}
|
|
190
207
|
}
|
|
191
208
|
|
|
@@ -272,7 +289,7 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
|
|
272
289
|
* final value after stopping the animation, which is useful for updating
|
|
273
290
|
* state to match the animation position with layout.
|
|
274
291
|
*/
|
|
275
|
-
stopAnimation(callback?:
|
|
292
|
+
stopAnimation(callback?: ColorListenerCallback): void {
|
|
276
293
|
this.r.stopAnimation();
|
|
277
294
|
this.g.stopAnimation();
|
|
278
295
|
this.b.stopAnimation();
|
|
@@ -283,7 +300,7 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
|
|
283
300
|
/**
|
|
284
301
|
* Stops any animation and resets the value to its original.
|
|
285
302
|
*/
|
|
286
|
-
resetAnimation(callback?:
|
|
303
|
+
resetAnimation(callback?: ColorListenerCallback): void {
|
|
287
304
|
this.r.resetAnimation();
|
|
288
305
|
this.g.resetAnimation();
|
|
289
306
|
this.b.resetAnimation();
|
|
@@ -291,8 +308,12 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
|
|
291
308
|
callback && callback(this.__getValue());
|
|
292
309
|
}
|
|
293
310
|
|
|
294
|
-
__getValue():
|
|
295
|
-
|
|
311
|
+
__getValue(): ColorValue {
|
|
312
|
+
if (this.nativeColor != null) {
|
|
313
|
+
return this.nativeColor;
|
|
314
|
+
} else {
|
|
315
|
+
return `rgba(${this.r.__getValue()}, ${this.g.__getValue()}, ${this.b.__getValue()}, ${this.a.__getValue()})`;
|
|
316
|
+
}
|
|
296
317
|
}
|
|
297
318
|
|
|
298
319
|
__attach(): void {
|
|
@@ -41,11 +41,7 @@ class AnimatedProps extends AnimatedNode {
|
|
|
41
41
|
for (const key in this._props) {
|
|
42
42
|
const value = this._props[key];
|
|
43
43
|
if (value instanceof AnimatedNode) {
|
|
44
|
-
|
|
45
|
-
// We cannot use value of natively driven nodes this way as the value we have access from
|
|
46
|
-
// JS may not be up to date.
|
|
47
|
-
props[key] = value.__getValue();
|
|
48
|
-
}
|
|
44
|
+
props[key] = value.__getValue();
|
|
49
45
|
} else if (value instanceof AnimatedEvent) {
|
|
50
46
|
props[key] = value.__getHandler();
|
|
51
47
|
} else {
|
|
@@ -39,11 +39,7 @@ class AnimatedStyle extends AnimatedWithChildren {
|
|
|
39
39
|
for (const key in style) {
|
|
40
40
|
const value = style[key];
|
|
41
41
|
if (value instanceof AnimatedNode) {
|
|
42
|
-
|
|
43
|
-
// We cannot use value of natively driven nodes this way as the value we have access from
|
|
44
|
-
// JS may not be up to date.
|
|
45
|
-
updatedStyle[key] = value.__getValue();
|
|
46
|
-
}
|
|
42
|
+
updatedStyle[key] = value.__getValue();
|
|
47
43
|
} else if (value && !Array.isArray(value) && typeof value === 'object') {
|
|
48
44
|
// Support animating nested values (for example: shadowOffset.height)
|
|
49
45
|
updatedStyle[key] = this._walkStyleAndGetValues(value);
|
|
@@ -20,6 +20,10 @@ import type Animation, {EndCallback} from '../animations/Animation';
|
|
|
20
20
|
import type {InterpolationConfigType} from './AnimatedInterpolation';
|
|
21
21
|
import type AnimatedTracking from './AnimatedTracking';
|
|
22
22
|
|
|
23
|
+
export type AnimatedValueConfig = $ReadOnly<{
|
|
24
|
+
useNativeDriver: boolean,
|
|
25
|
+
}>;
|
|
26
|
+
|
|
23
27
|
const NativeAnimatedAPI = NativeAnimatedHelper.API;
|
|
24
28
|
|
|
25
29
|
/**
|
|
@@ -87,7 +91,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
|
|
87
91
|
_animation: ?Animation;
|
|
88
92
|
_tracking: ?AnimatedTracking;
|
|
89
93
|
|
|
90
|
-
constructor(value: number) {
|
|
94
|
+
constructor(value: number, config?: ?AnimatedValueConfig) {
|
|
91
95
|
super();
|
|
92
96
|
if (typeof value !== 'number') {
|
|
93
97
|
throw new Error('AnimatedValue: Attempting to set value to undefined');
|
|
@@ -95,6 +99,9 @@ class AnimatedValue extends AnimatedWithChildren {
|
|
|
95
99
|
this._startingValue = this._value = value;
|
|
96
100
|
this._offset = 0;
|
|
97
101
|
this._animation = null;
|
|
102
|
+
if (config && config.useNativeDriver) {
|
|
103
|
+
this.__makeNative();
|
|
104
|
+
}
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
__detach() {
|
|
@@ -127,9 +134,9 @@ class AnimatedValue extends AnimatedWithChildren {
|
|
|
127
134
|
!this.__isNative /* don't perform a flush for natively driven values */,
|
|
128
135
|
);
|
|
129
136
|
if (this.__isNative) {
|
|
130
|
-
_executeAsAnimatedBatch(this.__getNativeTag().toString(), () =>
|
|
131
|
-
NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value)
|
|
132
|
-
|
|
137
|
+
_executeAsAnimatedBatch(this.__getNativeTag().toString(), () =>
|
|
138
|
+
NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value),
|
|
139
|
+
);
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
|