react-native-tvos 0.76.2-0 → 0.76.5-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.
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Text/TextInput/RCTBaseTextInputView.mm +1 -0
- package/React/Base/RCTVersion.m +1 -1
- package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h +1 -1
- package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +8 -18
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h +3 -0
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +17 -18
- package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +8 -2
- package/React/Views/RCTFont.h +2 -0
- package/React/Views/RCTFont.mm +4 -5
- package/React/Views/RCTTVView.h +3 -8
- package/React/Views/RCTView.h +19 -0
- package/React/Views/ScrollView/RCTScrollView.h +3 -1
- package/React/Views/ScrollView/RCTScrollView.m +6 -0
- package/ReactAndroid/api/ReactAndroid.api +2 -0
- package/ReactAndroid/cmake-utils/ReactNative-application.cmake +2 -3
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/hermes-engine/build.gradle.kts +4 -0
- package/ReactAndroid/src/main/java/com/facebook/react/HeadlessJsTaskService.java +12 -13
- package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +8 -2
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +11 -3
- package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +11 -3
- package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt +25 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTFontUtils.mm +10 -10
- package/ReactCommon/react/renderer/uimanager/UIManager.cpp +29 -8
- package/ReactCommon/react/runtime/ReactInstance.cpp +39 -35
- package/ReactCommon/react/runtime/ReactInstance.h +2 -1
- package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm +3 -2
- package/jest/setup.js +5 -1
- package/package.json +8 -8
- package/scripts/codegen/generate-artifacts-executor.js +68 -7
- package/sdks/hermesc/osx-bin/hermes +0 -0
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/sdks/hermesc/win64-bin/msvcp140.dll +0 -0
- package/sdks/hermesc/win64-bin/vcruntime140.dll +0 -0
- package/sdks/hermesc/win64-bin/vcruntime140_1.dll +0 -0
package/React/Base/RCTVersion.m
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
/**
|
|
11
11
|
* UIView class for root <ModalHostView> component.
|
|
12
12
|
*/
|
|
13
|
-
@interface RCTModalHostViewComponentView : RCTViewComponentView
|
|
13
|
+
@interface RCTModalHostViewComponentView : RCTViewComponentView <UIAdaptivePresentationControllerDelegate>
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Subclasses may override this method and present the modal on different view controller.
|
|
@@ -189,9 +189,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
189
189
|
completion:(void (^)(void))completion
|
|
190
190
|
{
|
|
191
191
|
UIViewController *controller = [self reactViewController];
|
|
192
|
-
[
|
|
193
|
-
animated:animated
|
|
194
|
-
completion:completion];
|
|
192
|
+
[controller presentViewController:modalViewController animated:animated completion:completion];
|
|
195
193
|
}
|
|
196
194
|
|
|
197
195
|
- (void)dismissViewController:(UIViewController *)modalViewController
|
|
@@ -206,6 +204,8 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
206
204
|
{
|
|
207
205
|
BOOL shouldBePresented = !_isPresented && _shouldPresent && self.window;
|
|
208
206
|
if (shouldBePresented) {
|
|
207
|
+
self.viewController.presentationController.delegate = self;
|
|
208
|
+
|
|
209
209
|
_isPresented = YES;
|
|
210
210
|
[self presentViewController:self.viewController
|
|
211
211
|
animated:_shouldAnimatePresentation
|
|
@@ -331,24 +331,14 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
331
331
|
[childComponentView removeFromSuperview];
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
-
#pragma mark -
|
|
334
|
+
#pragma mark - UIAdaptivePresentationControllerDelegate
|
|
335
335
|
|
|
336
|
-
- (
|
|
336
|
+
- (void)presentationControllerDidAttemptToDismiss:(UIPresentationController *)controller
|
|
337
337
|
{
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
if ([topController isKindOfClass:[UINavigationController class]]) {
|
|
343
|
-
UINavigationController *navigationController = (UINavigationController *)topController;
|
|
344
|
-
topController = navigationController.visibleViewController;
|
|
345
|
-
return [self _topMostViewControllerFrom:topController];
|
|
346
|
-
} else if ([topController isKindOfClass:[UITabBarController class]]) {
|
|
347
|
-
UITabBarController *tabBarController = (UITabBarController *)topController;
|
|
348
|
-
topController = tabBarController.selectedViewController;
|
|
349
|
-
return [self _topMostViewControllerFrom:topController];
|
|
338
|
+
auto eventEmitter = [self modalEventEmitter];
|
|
339
|
+
if (eventEmitter) {
|
|
340
|
+
eventEmitter->onRequestClose({});
|
|
350
341
|
}
|
|
351
|
-
return topController;
|
|
352
342
|
}
|
|
353
343
|
|
|
354
344
|
@end
|
|
@@ -38,6 +38,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
38
38
|
/** Focus area of newly-activated text input relative to the window to compare against UIKeyboardFrameBegin/End */
|
|
39
39
|
@property (nonatomic, assign) CGRect firstResponderFocus;
|
|
40
40
|
|
|
41
|
+
/** newly-activated text input outside of the scroll view */
|
|
42
|
+
@property (nonatomic, weak) UIView *firstResponderViewOutsideScrollView;
|
|
43
|
+
|
|
41
44
|
/*
|
|
42
45
|
* Returns the subview of the scroll view that the component uses to mount all subcomponents into. That's useful to
|
|
43
46
|
* separate component views from auxiliary views to be able to reliably implement pull-to-refresh- and RTL-related
|
|
@@ -194,16 +194,18 @@ RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInt
|
|
|
194
194
|
UIViewAnimationCurve curve =
|
|
195
195
|
(UIViewAnimationCurve)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
|
|
196
196
|
CGRect keyboardEndFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
|
197
|
+
CGRect keyboardBeginFrame = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
|
|
197
198
|
|
|
198
199
|
CGPoint absoluteViewOrigin = [self convertPoint:self.bounds.origin toView:nil];
|
|
199
200
|
CGFloat scrollViewLowerY = isInverted ? absoluteViewOrigin.y : absoluteViewOrigin.y + self.bounds.size.height;
|
|
200
201
|
|
|
201
202
|
UIEdgeInsets newEdgeInsets = _scrollView.contentInset;
|
|
202
203
|
CGFloat inset = MAX(scrollViewLowerY - keyboardEndFrame.origin.y, 0);
|
|
204
|
+
const auto &props = static_cast<const ScrollViewProps &>(*_props);
|
|
203
205
|
if (isInverted) {
|
|
204
|
-
newEdgeInsets.top = MAX(inset,
|
|
206
|
+
newEdgeInsets.top = MAX(inset, props.contentInset.top);
|
|
205
207
|
} else {
|
|
206
|
-
newEdgeInsets.bottom = MAX(inset,
|
|
208
|
+
newEdgeInsets.bottom = MAX(inset, props.contentInset.bottom);
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
CGPoint newContentOffset = _scrollView.contentOffset;
|
|
@@ -215,21 +217,18 @@ RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInt
|
|
|
215
217
|
from:self
|
|
216
218
|
forEvent:nil]) {
|
|
217
219
|
if (CGRectEqualToRect(_firstResponderFocus, CGRectNull)) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
if (focusEnd > keyboardEndFrame.origin.y) {
|
|
231
|
-
// Text field active region is below visible area with keyboard - update diff to bring into view
|
|
232
|
-
contentDiff = keyboardEndFrame.origin.y - focusEnd;
|
|
220
|
+
UIView *inputAccessoryView = _firstResponderViewOutsideScrollView.inputAccessoryView;
|
|
221
|
+
if (inputAccessoryView) {
|
|
222
|
+
// Text input view is within the inputAccessoryView.
|
|
223
|
+
contentDiff = keyboardEndFrame.origin.y - keyboardBeginFrame.origin.y;
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
// Inner text field focused
|
|
227
|
+
CGFloat focusEnd = CGRectGetMaxY(self.firstResponderFocus);
|
|
228
|
+
if (focusEnd > keyboardEndFrame.origin.y) {
|
|
229
|
+
// Text field active region is below visible area with keyboard - update diff to bring into view
|
|
230
|
+
contentDiff = keyboardEndFrame.origin.y - focusEnd;
|
|
231
|
+
}
|
|
233
232
|
}
|
|
234
233
|
}
|
|
235
234
|
|
|
@@ -255,7 +254,7 @@ RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInt
|
|
|
255
254
|
animations:^{
|
|
256
255
|
self->_scrollView.contentInset = newEdgeInsets;
|
|
257
256
|
self->_scrollView.verticalScrollIndicatorInsets = newEdgeInsets;
|
|
258
|
-
[self
|
|
257
|
+
[self scrollTo:newContentOffset.x y:newContentOffset.y animated:NO];
|
|
259
258
|
}
|
|
260
259
|
completion:nil];
|
|
261
260
|
}
|
|
@@ -126,6 +126,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
|
|
126
126
|
{
|
|
127
127
|
if (![self isDescendantOfView:scrollView.scrollView] || !_backedTextInputView.isFirstResponder) {
|
|
128
128
|
// View is outside scroll view or it's not a first responder.
|
|
129
|
+
scrollView.firstResponderViewOutsideScrollView = _backedTextInputView;
|
|
129
130
|
return;
|
|
130
131
|
}
|
|
131
132
|
|
|
@@ -443,10 +444,15 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
|
|
443
444
|
|
|
444
445
|
- (void)textInputDidChangeSelection
|
|
445
446
|
{
|
|
446
|
-
[self _updateTypingAttributes];
|
|
447
447
|
if (_comingFromJS) {
|
|
448
448
|
return;
|
|
449
449
|
}
|
|
450
|
+
|
|
451
|
+
// T207198334: Setting a new AttributedString (_comingFromJS) will trigger a selection change before the backing
|
|
452
|
+
// string is updated, so indicies won't point to what we want yet. Only respond to user selection change, and let
|
|
453
|
+
// `_setAttributedString` handle updating typing attributes if content changes.
|
|
454
|
+
[self _updateTypingAttributes];
|
|
455
|
+
|
|
450
456
|
const auto &props = static_cast<const TextInputProps &>(*_props);
|
|
451
457
|
if (props.traits.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
|
|
452
458
|
[self textInputDidChange];
|
|
@@ -716,7 +722,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
|
|
716
722
|
// https://github.com/facebook/react-native/blob/3102a58df38d96f3dacef0530e4dbb399037fcd2/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/SetSpanOperation.kt#L30
|
|
717
723
|
- (void)_updateTypingAttributes
|
|
718
724
|
{
|
|
719
|
-
if (_backedTextInputView.attributedText.length > 0) {
|
|
725
|
+
if (_backedTextInputView.attributedText.length > 0 && _backedTextInputView.selectedTextRange != nil) {
|
|
720
726
|
NSUInteger offsetStart = [_backedTextInputView offsetFromPosition:_backedTextInputView.beginningOfDocument
|
|
721
727
|
toPosition:_backedTextInputView.selectedTextRange.start];
|
|
722
728
|
|
package/React/Views/RCTFont.h
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#import <React/RCTConvert.h>
|
|
11
11
|
|
|
12
12
|
typedef UIFont * (^RCTFontHandler)(CGFloat fontSize, NSString *fontWeightDescription);
|
|
13
|
+
typedef CGFloat RCTFontWeight;
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* React Native will use the System font for rendering by default. If you want to
|
|
@@ -19,6 +20,7 @@ typedef UIFont * (^RCTFontHandler)(CGFloat fontSize, NSString *fontWeightDescrip
|
|
|
19
20
|
*/
|
|
20
21
|
RCT_EXTERN void RCTSetDefaultFontHandler(RCTFontHandler handler);
|
|
21
22
|
RCT_EXTERN BOOL RCTHasFontHandlerSet(void);
|
|
23
|
+
RCT_EXTERN RCTFontWeight RCTGetFontWeight(UIFont *font);
|
|
22
24
|
|
|
23
25
|
@interface RCTFont : NSObject
|
|
24
26
|
|
package/React/Views/RCTFont.mm
CHANGED
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
#import <CoreText/CoreText.h>
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
static RCTFontWeight weightOfFont(UIFont *font)
|
|
14
|
+
RCTFontWeight RCTGetFontWeight(UIFont *font)
|
|
16
15
|
{
|
|
17
16
|
static NSArray<NSString *> *weightSuffixes;
|
|
18
17
|
static NSArray<NSNumber *> *fontWeights;
|
|
@@ -405,7 +404,7 @@ RCT_ARRAY_CONVERTER(RCTFontVariantDescriptor)
|
|
|
405
404
|
if (font) {
|
|
406
405
|
familyName = font.familyName ?: defaultFontFamily;
|
|
407
406
|
fontSize = font.pointSize ?: defaultFontSize;
|
|
408
|
-
fontWeight =
|
|
407
|
+
fontWeight = RCTGetFontWeight(font);
|
|
409
408
|
isItalic = isItalicFont(font);
|
|
410
409
|
isCondensed = isCondensedFont(font);
|
|
411
410
|
}
|
|
@@ -453,7 +452,7 @@ RCT_ARRAY_CONVERTER(RCTFontVariantDescriptor)
|
|
|
453
452
|
// It's actually a font name, not a font family name,
|
|
454
453
|
// but we'll do what was meant, not what was said.
|
|
455
454
|
familyName = font.familyName;
|
|
456
|
-
fontWeight = weight ? fontWeight :
|
|
455
|
+
fontWeight = weight ? fontWeight : RCTGetFontWeight(font);
|
|
457
456
|
isItalic = style ? isItalic : isItalicFont(font);
|
|
458
457
|
isCondensed = isCondensedFont(font);
|
|
459
458
|
} else {
|
|
@@ -476,7 +475,7 @@ RCT_ARRAY_CONVERTER(RCTFontVariantDescriptor)
|
|
|
476
475
|
for (NSString *name in names) {
|
|
477
476
|
UIFont *match = [UIFont fontWithName:name size:fontSize];
|
|
478
477
|
if (isItalic == isItalicFont(match) && isCondensed == isCondensedFont(match)) {
|
|
479
|
-
CGFloat testWeight =
|
|
478
|
+
CGFloat testWeight = RCTGetFontWeight(match);
|
|
480
479
|
if (ABS(testWeight - fontWeight) < ABS(closestWeight - fontWeight)) {
|
|
481
480
|
font = match;
|
|
482
481
|
closestWeight = testWeight;
|
package/React/Views/RCTTVView.h
CHANGED
|
@@ -57,18 +57,13 @@
|
|
|
57
57
|
@property (nonatomic, assign) BOOL trapFocusLeft;
|
|
58
58
|
@property (nonatomic, assign) BOOL trapFocusRight;
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
* Focus
|
|
63
|
-
*/
|
|
60
|
+
// These handlers are defined in RCTView
|
|
61
|
+
/*
|
|
64
62
|
@property (nonatomic, copy) RCTBubblingEventBlock onFocus;
|
|
65
63
|
@property (nonatomic, copy) RCTBubblingEventBlock onBlur;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* TV Press Handlers
|
|
69
|
-
*/
|
|
70
64
|
@property (nonatomic, copy) RCTDirectEventBlock onPressIn;
|
|
71
65
|
@property (nonatomic, copy) RCTDirectEventBlock onPressOut;
|
|
66
|
+
*/
|
|
72
67
|
|
|
73
68
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
|
74
69
|
|
package/React/Views/RCTView.h
CHANGED
|
@@ -123,6 +123,25 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
|
|
|
123
123
|
|
|
124
124
|
@property (nonatomic, assign) RCTCursor cursor;
|
|
125
125
|
|
|
126
|
+
#if TARGET_OS_TV
|
|
127
|
+
// For Paper, all views on TV might have focus, blur, pressIn, pressOut handlers,
|
|
128
|
+
// so we need to add these properties here and not in RCTTVView,
|
|
129
|
+
// since some views do not inherit from RCTTVView.
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Focus
|
|
133
|
+
*/
|
|
134
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onFocus;
|
|
135
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onBlur;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* TV Press Handlers
|
|
139
|
+
*/
|
|
140
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPressIn;
|
|
141
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPressOut;
|
|
142
|
+
|
|
143
|
+
#endif // TARGET_OS_TV
|
|
144
|
+
|
|
126
145
|
/**
|
|
127
146
|
* (Experimental and unused for Paper) Pointer event handlers.
|
|
128
147
|
*/
|
|
@@ -56,9 +56,11 @@
|
|
|
56
56
|
@property (nonatomic, assign) BOOL snapToEnd;
|
|
57
57
|
@property (nonatomic, copy) NSString *snapToAlignment;
|
|
58
58
|
@property (nonatomic, assign) BOOL inverted;
|
|
59
|
+
@property (nonatomic, assign) BOOL showsScrollIndex;
|
|
59
60
|
/** Focus area of newly-activated text input relative to the window to compare against UIKeyboardFrameBegin/End */
|
|
60
61
|
@property (nonatomic, assign) CGRect firstResponderFocus;
|
|
61
|
-
|
|
62
|
+
/** newly-activated text input outside of the scroll view */
|
|
63
|
+
@property (nonatomic, weak) UIView *firstResponderViewOutsideScrollView;
|
|
62
64
|
|
|
63
65
|
// NOTE: currently these event props are only declared so we can export the
|
|
64
66
|
// event names to JS - we don't call the blocks directly because scroll events
|
|
@@ -363,6 +363,12 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
|
|
|
363
363
|
if (!didFocusExternalTextField && focusEnd > endFrame.origin.y) {
|
|
364
364
|
// Text field active region is below visible area with keyboard - update diff to bring into view
|
|
365
365
|
contentDiff = endFrame.origin.y - focusEnd;
|
|
366
|
+
} else {
|
|
367
|
+
UIView *inputAccessoryView = _firstResponderViewOutsideScrollView.inputAccessoryView;
|
|
368
|
+
if (inputAccessoryView) {
|
|
369
|
+
// Text input view is within the inputAccessoryView.
|
|
370
|
+
contentDiff = endFrame.origin.y - beginFrame.origin.y;
|
|
371
|
+
}
|
|
366
372
|
}
|
|
367
373
|
} else if (endFrame.origin.y <= beginFrame.origin.y) {
|
|
368
374
|
// Keyboard opened for other reason
|
|
@@ -7280,6 +7280,8 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper {
|
|
|
7280
7280
|
public static final field SNAP_ALIGNMENT_END I
|
|
7281
7281
|
public static final field SNAP_ALIGNMENT_START I
|
|
7282
7282
|
public static final fun addScrollListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ScrollListener;)V
|
|
7283
|
+
public static final fun dispatchMomentumEndOnAnimationEnd (Landroid/view/ViewGroup;)V
|
|
7284
|
+
public static final fun emitLayoutChangeEvent (Landroid/view/ViewGroup;)V
|
|
7283
7285
|
public static final fun emitLayoutEvent (Landroid/view/ViewGroup;)V
|
|
7284
7286
|
public static final fun emitScrollBeginDragEvent (Landroid/view/ViewGroup;)V
|
|
7285
7287
|
public static final fun emitScrollEndDragEvent (Landroid/view/ViewGroup;FF)V
|
|
@@ -31,9 +31,8 @@ if(CCACHE_FOUND)
|
|
|
31
31
|
endif(CCACHE_FOUND)
|
|
32
32
|
|
|
33
33
|
set(BUILD_DIR ${PROJECT_BUILD_DIR})
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
endif()
|
|
34
|
+
file(TO_CMAKE_PATH "${BUILD_DIR}" BUILD_DIR)
|
|
35
|
+
file(TO_CMAKE_PATH "${REACT_ANDROID_DIR}" REACT_ANDROID_DIR)
|
|
37
36
|
|
|
38
37
|
file(GLOB input_SRC CONFIGURE_DEPENDS
|
|
39
38
|
${REACT_ANDROID_DIR}/cmake-utils/default-app-setup/*.cpp
|
|
@@ -38,9 +38,13 @@ fun getSDKPath(): String {
|
|
|
38
38
|
fun getSDKManagerPath(): String {
|
|
39
39
|
val metaSdkManagerPath = File("${getSDKPath()}/cmdline-tools/latest/bin/sdkmanager")
|
|
40
40
|
val ossSdkManagerPath = File("${getSDKPath()}/tools/bin/sdkmanager")
|
|
41
|
+
val windowsMetaSdkManagerPath = File("${getSDKPath()}/cmdline-tools/latest/bin/sdkmanager.bat")
|
|
42
|
+
val windowsOssSdkManagerPath = File("${getSDKPath()}/tools/bin/sdkmanager.bat")
|
|
41
43
|
return when {
|
|
42
44
|
metaSdkManagerPath.exists() -> metaSdkManagerPath.absolutePath
|
|
45
|
+
windowsMetaSdkManagerPath.exists() -> windowsMetaSdkManagerPath.absolutePath
|
|
43
46
|
ossSdkManagerPath.exists() -> ossSdkManagerPath.absolutePath
|
|
47
|
+
windowsOssSdkManagerPath.exists() -> windowsOssSdkManagerPath.absolutePath
|
|
44
48
|
else -> throw GradleException("Could not find sdkmanager executable.")
|
|
45
49
|
}
|
|
46
50
|
}
|
|
@@ -179,31 +179,30 @@ public abstract class HeadlessJsTaskService extends Service implements HeadlessJ
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
private void createReactContextAndScheduleTask(final HeadlessJsTaskConfig taskConfig) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
final ReactInstanceManager reactInstanceManager =
|
|
186
|
-
getReactNativeHost().getReactInstanceManager();
|
|
187
|
-
|
|
188
|
-
reactInstanceManager.addReactInstanceEventListener(
|
|
182
|
+
if (ReactFeatureFlags.enableBridgelessArchitecture) {
|
|
183
|
+
final ReactHost reactHost = getReactHost();
|
|
184
|
+
reactHost.addReactInstanceEventListener(
|
|
189
185
|
new ReactInstanceEventListener() {
|
|
190
186
|
@Override
|
|
191
187
|
public void onReactContextInitialized(@NonNull ReactContext reactContext) {
|
|
192
188
|
invokeStartTask(reactContext, taskConfig);
|
|
193
|
-
|
|
189
|
+
reactHost.removeReactInstanceEventListener(this);
|
|
194
190
|
}
|
|
195
191
|
});
|
|
196
|
-
|
|
197
|
-
} else {
|
|
198
|
-
|
|
192
|
+
reactHost.start();
|
|
193
|
+
} else {
|
|
194
|
+
final ReactInstanceManager reactInstanceManager =
|
|
195
|
+
getReactNativeHost().getReactInstanceManager();
|
|
196
|
+
|
|
197
|
+
reactInstanceManager.addReactInstanceEventListener(
|
|
199
198
|
new ReactInstanceEventListener() {
|
|
200
199
|
@Override
|
|
201
200
|
public void onReactContextInitialized(@NonNull ReactContext reactContext) {
|
|
202
201
|
invokeStartTask(reactContext, taskConfig);
|
|
203
|
-
|
|
202
|
+
reactInstanceManager.removeReactInstanceEventListener(this);
|
|
204
203
|
}
|
|
205
204
|
});
|
|
206
|
-
|
|
205
|
+
reactInstanceManager.createReactContextInBackground();
|
|
207
206
|
}
|
|
208
207
|
}
|
|
209
208
|
}
|
|
@@ -449,12 +449,18 @@ public class FabricUIManager
|
|
|
449
449
|
|
|
450
450
|
@Override
|
|
451
451
|
public void markActiveTouchForTag(int surfaceId, int reactTag) {
|
|
452
|
-
mMountingManager.getSurfaceManager(surfaceId)
|
|
452
|
+
SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(surfaceId);
|
|
453
|
+
if (surfaceMountingManager != null) {
|
|
454
|
+
surfaceMountingManager.markActiveTouchForTag(reactTag);
|
|
455
|
+
}
|
|
453
456
|
}
|
|
454
457
|
|
|
455
458
|
@Override
|
|
456
459
|
public void sweepActiveTouchForTag(int surfaceId, int reactTag) {
|
|
457
|
-
mMountingManager.getSurfaceManager(surfaceId)
|
|
460
|
+
SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(surfaceId);
|
|
461
|
+
if (surfaceMountingManager != null) {
|
|
462
|
+
surfaceMountingManager.sweepActiveTouchForTag(reactTag);
|
|
463
|
+
}
|
|
458
464
|
}
|
|
459
465
|
|
|
460
466
|
/**
|
package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java
CHANGED
|
@@ -1552,12 +1552,20 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
|
|
|
1552
1552
|
DEFAULT_FLING_ANIMATOR.cancel();
|
|
1553
1553
|
|
|
1554
1554
|
// Update the fling animator with new values
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
.setIntValues(start, end);
|
|
1555
|
+
int duration = ReactScrollViewHelper.getDefaultScrollAnimationDuration(getContext());
|
|
1556
|
+
DEFAULT_FLING_ANIMATOR.setDuration(duration).setIntValues(start, end);
|
|
1558
1557
|
|
|
1559
1558
|
// Start the animator
|
|
1560
1559
|
DEFAULT_FLING_ANIMATOR.start();
|
|
1560
|
+
|
|
1561
|
+
if (mSendMomentumEvents) {
|
|
1562
|
+
int xVelocity = 0;
|
|
1563
|
+
if (duration > 0) {
|
|
1564
|
+
xVelocity = (end - start) / duration;
|
|
1565
|
+
}
|
|
1566
|
+
ReactScrollViewHelper.emitScrollMomentumBeginEvent(this, xVelocity, 0);
|
|
1567
|
+
ReactScrollViewHelper.dispatchMomentumEndOnAnimationEnd(this);
|
|
1568
|
+
}
|
|
1561
1569
|
}
|
|
1562
1570
|
|
|
1563
1571
|
@Override
|
|
@@ -1366,12 +1366,20 @@ public class ReactScrollView extends ScrollView
|
|
|
1366
1366
|
DEFAULT_FLING_ANIMATOR.cancel();
|
|
1367
1367
|
|
|
1368
1368
|
// Update the fling animator with new values
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
.setIntValues(start, end);
|
|
1369
|
+
int duration = ReactScrollViewHelper.getDefaultScrollAnimationDuration(getContext());
|
|
1370
|
+
DEFAULT_FLING_ANIMATOR.setDuration(duration).setIntValues(start, end);
|
|
1372
1371
|
|
|
1373
1372
|
// Start the animator
|
|
1374
1373
|
DEFAULT_FLING_ANIMATOR.start();
|
|
1374
|
+
|
|
1375
|
+
if (mSendMomentumEvents) {
|
|
1376
|
+
int yVelocity = 0;
|
|
1377
|
+
if (duration > 0) {
|
|
1378
|
+
yVelocity = (end - start) / duration;
|
|
1379
|
+
}
|
|
1380
|
+
ReactScrollViewHelper.emitScrollMomentumBeginEvent(this, 0, yVelocity);
|
|
1381
|
+
ReactScrollViewHelper.dispatchMomentumEndOnAnimationEnd(this);
|
|
1382
|
+
}
|
|
1375
1383
|
}
|
|
1376
1384
|
|
|
1377
1385
|
@NonNull
|
|
@@ -412,6 +412,31 @@ public object ReactScrollViewHelper {
|
|
|
412
412
|
})
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
+
@JvmStatic
|
|
416
|
+
public fun <T> dispatchMomentumEndOnAnimationEnd(scrollView: T) where
|
|
417
|
+
T : HasFlingAnimator?,
|
|
418
|
+
T : HasScrollEventThrottle?,
|
|
419
|
+
T : ViewGroup {
|
|
420
|
+
scrollView
|
|
421
|
+
.getFlingAnimator()
|
|
422
|
+
.addListener(
|
|
423
|
+
object : Animator.AnimatorListener {
|
|
424
|
+
override fun onAnimationStart(animator: Animator) = Unit
|
|
425
|
+
|
|
426
|
+
override fun onAnimationEnd(animator: Animator) {
|
|
427
|
+
emitScrollMomentumEndEvent(scrollView)
|
|
428
|
+
animator.removeListener(this)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
override fun onAnimationCancel(animator: Animator) {
|
|
432
|
+
emitScrollMomentumEndEvent(scrollView)
|
|
433
|
+
animator.removeListener(this)
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
override fun onAnimationRepeat(animator: Animator) = Unit
|
|
437
|
+
})
|
|
438
|
+
}
|
|
439
|
+
|
|
415
440
|
@JvmStatic
|
|
416
441
|
public fun <T> predictFinalScrollPosition(
|
|
417
442
|
scrollView: T,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#import "RCTFontUtils.h"
|
|
9
9
|
#import <CoreText/CoreText.h>
|
|
10
|
+
#import <React/RCTFont.h>
|
|
10
11
|
|
|
11
12
|
#import <algorithm>
|
|
12
13
|
#import <cmath>
|
|
@@ -45,12 +46,6 @@ static RCTFontProperties RCTResolveFontProperties(
|
|
|
45
46
|
return fontProperties;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
static UIFontWeight RCTGetFontWeight(UIFont *font)
|
|
49
|
-
{
|
|
50
|
-
NSDictionary *traits = [font.fontDescriptor objectForKey:UIFontDescriptorTraitsAttribute];
|
|
51
|
-
return [traits[UIFontWeightTrait] doubleValue];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
49
|
static RCTFontStyle RCTGetFontStyle(UIFont *font)
|
|
55
50
|
{
|
|
56
51
|
NSDictionary *traits = [font.fontDescriptor objectForKey:UIFontDescriptorTraitsAttribute];
|
|
@@ -165,17 +160,22 @@ UIFont *RCTFontWithFontProperties(RCTFontProperties fontProperties)
|
|
|
165
160
|
font = RCTDefaultFontWithFontProperties(fontProperties);
|
|
166
161
|
} else {
|
|
167
162
|
NSArray<NSString *> *fontNames = [UIFont fontNamesForFamilyName:fontProperties.family];
|
|
163
|
+
UIFontWeight fontWeight = fontProperties.weight;
|
|
168
164
|
|
|
169
165
|
if (fontNames.count == 0) {
|
|
170
166
|
// Gracefully handle being given a font name rather than font family, for
|
|
171
167
|
// example: "Helvetica Light Oblique" rather than just "Helvetica".
|
|
172
168
|
font = [UIFont fontWithName:fontProperties.family size:effectiveFontSize];
|
|
173
|
-
|
|
174
|
-
|
|
169
|
+
if (font) {
|
|
170
|
+
fontNames = [UIFont fontNamesForFamilyName:font.familyName];
|
|
171
|
+
fontWeight = fontWeight ?: RCTGetFontWeight(font);
|
|
172
|
+
} else {
|
|
175
173
|
// Failback to system font.
|
|
176
174
|
font = [UIFont systemFontOfSize:effectiveFontSize weight:fontProperties.weight];
|
|
177
175
|
}
|
|
178
|
-
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (fontNames.count > 0) {
|
|
179
179
|
// Get the closest font that matches the given weight for the fontFamily
|
|
180
180
|
CGFloat closestWeight = INFINITY;
|
|
181
181
|
for (NSString *name in fontNames) {
|
|
@@ -186,7 +186,7 @@ UIFont *RCTFontWithFontProperties(RCTFontProperties fontProperties)
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
CGFloat testWeight = RCTGetFontWeight(fontMatch);
|
|
189
|
-
if (ABS(testWeight -
|
|
189
|
+
if (ABS(testWeight - fontWeight) < ABS(closestWeight - fontWeight)) {
|
|
190
190
|
font = fontMatch;
|
|
191
191
|
closestWeight = testWeight;
|
|
192
192
|
}
|
|
@@ -126,20 +126,41 @@ std::shared_ptr<ShadowNode> UIManager::cloneNode(
|
|
|
126
126
|
|
|
127
127
|
if (!rawProps.isEmpty()) {
|
|
128
128
|
if (family.nativeProps_DEPRECATED != nullptr) {
|
|
129
|
+
// 1. update the nativeProps_DEPRECATED props.
|
|
130
|
+
//
|
|
131
|
+
// In this step, we want the most recent value for the props
|
|
132
|
+
// managed by setNativeProps.
|
|
129
133
|
// Values in `rawProps` patch (take precedence over)
|
|
130
|
-
// `nativeProps_DEPRECATED`. For example, if both
|
|
131
|
-
// and `rawProps` contain key 'A'.
|
|
132
|
-
// was previously in
|
|
134
|
+
// `nativeProps_DEPRECATED`. For example, if both
|
|
135
|
+
// `nativeProps_DEPRECATED` and `rawProps` contain key 'A'.
|
|
136
|
+
// Value from `rawProps` overrides what was previously in
|
|
137
|
+
// `nativeProps_DEPRECATED`. Notice that the `nativeProps_DEPRECATED`
|
|
138
|
+
// patch will not get more props from `rawProps`: if the key is not
|
|
139
|
+
// present in `nativeProps_DEPRECATED`, it will not be added.
|
|
140
|
+
//
|
|
141
|
+
// The result of this operation is the new `nativeProps_DEPRECATED`.
|
|
133
142
|
family.nativeProps_DEPRECATED =
|
|
134
143
|
std::make_unique<folly::dynamic>(mergeDynamicProps(
|
|
135
|
-
*family.nativeProps_DEPRECATED,
|
|
136
|
-
(folly::dynamic)rawProps,
|
|
144
|
+
*family.nativeProps_DEPRECATED, // source
|
|
145
|
+
(folly::dynamic)rawProps, // patch
|
|
137
146
|
NullValueStrategy::Ignore));
|
|
138
147
|
|
|
148
|
+
// 2. Compute the final set of props.
|
|
149
|
+
//
|
|
150
|
+
// This step takes the new props handled by `setNativeProps` and
|
|
151
|
+
// merges them in the `rawProps` managed by React.
|
|
152
|
+
// The new props handled by `nativeProps` now takes precedence
|
|
153
|
+
// on the props handled by React, as we want to make sure that
|
|
154
|
+
// all the props are applied to the component.
|
|
155
|
+
// We use these finalProps as source of truth for the component.
|
|
156
|
+
auto finalProps = mergeDynamicProps(
|
|
157
|
+
(folly::dynamic)rawProps, // source
|
|
158
|
+
*family.nativeProps_DEPRECATED, // patch
|
|
159
|
+
NullValueStrategy::Override);
|
|
160
|
+
|
|
161
|
+
// 3. Clone the props by using finalProps.
|
|
139
162
|
props = componentDescriptor.cloneProps(
|
|
140
|
-
propsParserContext,
|
|
141
|
-
shadowNode.getProps(),
|
|
142
|
-
RawProps(*family.nativeProps_DEPRECATED));
|
|
163
|
+
propsParserContext, shadowNode.getProps(), RawProps(finalProps));
|
|
143
164
|
} else {
|
|
144
165
|
props = componentDescriptor.cloneProps(
|
|
145
166
|
propsParserContext, shadowNode.getProps(), std::move(rawProps));
|
|
@@ -204,47 +204,51 @@ std::string simpleBasename(const std::string& path) {
|
|
|
204
204
|
*/
|
|
205
205
|
void ReactInstance::loadScript(
|
|
206
206
|
std::unique_ptr<const JSBigString> script,
|
|
207
|
-
const std::string& sourceURL
|
|
207
|
+
const std::string& sourceURL,
|
|
208
|
+
std::function<void(jsi::Runtime& runtime)>&& completion) {
|
|
208
209
|
auto buffer = std::make_shared<BigStringBuffer>(std::move(script));
|
|
209
210
|
std::string scriptName = simpleBasename(sourceURL);
|
|
210
211
|
|
|
211
|
-
runtimeScheduler_->scheduleWork(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
212
|
+
runtimeScheduler_->scheduleWork([this,
|
|
213
|
+
scriptName,
|
|
214
|
+
sourceURL,
|
|
215
|
+
buffer = std::move(buffer),
|
|
216
|
+
weakBufferedRuntimeExecuter =
|
|
217
|
+
std::weak_ptr<BufferedRuntimeExecutor>(
|
|
218
|
+
bufferedRuntimeExecutor_),
|
|
219
|
+
completion](jsi::Runtime& runtime) {
|
|
220
|
+
SystraceSection s("ReactInstance::loadScript");
|
|
221
|
+
bool hasLogger(ReactMarker::logTaggedMarkerBridgelessImpl);
|
|
222
|
+
if (hasLogger) {
|
|
223
|
+
ReactMarker::logTaggedMarkerBridgeless(
|
|
224
|
+
ReactMarker::RUN_JS_BUNDLE_START, scriptName.c_str());
|
|
225
|
+
}
|
|
224
226
|
|
|
225
|
-
|
|
227
|
+
runtime.evaluateJavaScript(buffer, sourceURL);
|
|
226
228
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
229
|
+
/**
|
|
230
|
+
* TODO(T183610671): We need a safe/reliable way to enable the js
|
|
231
|
+
* pipeline from javascript. Remove this after we figure that out, or
|
|
232
|
+
* after we just remove the js pipeline.
|
|
233
|
+
*/
|
|
234
|
+
if (!jsErrorHandler_->hasHandledFatalError()) {
|
|
235
|
+
jsErrorHandler_->setRuntimeReady();
|
|
236
|
+
}
|
|
235
237
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
238
|
+
if (hasLogger) {
|
|
239
|
+
ReactMarker::logTaggedMarkerBridgeless(
|
|
240
|
+
ReactMarker::RUN_JS_BUNDLE_STOP, scriptName.c_str());
|
|
241
|
+
ReactMarker::logMarkerBridgeless(ReactMarker::INIT_REACT_RUNTIME_STOP);
|
|
242
|
+
ReactMarker::logMarkerBridgeless(ReactMarker::APP_STARTUP_STOP);
|
|
243
|
+
}
|
|
244
|
+
if (auto strongBufferedRuntimeExecuter =
|
|
245
|
+
weakBufferedRuntimeExecuter.lock()) {
|
|
246
|
+
strongBufferedRuntimeExecuter->flush();
|
|
247
|
+
}
|
|
248
|
+
if (completion) {
|
|
249
|
+
completion(runtime);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
248
252
|
}
|
|
249
253
|
|
|
250
254
|
/*
|
|
@@ -48,7 +48,8 @@ class ReactInstance final : private jsinspector_modern::InstanceTargetDelegate {
|
|
|
48
48
|
|
|
49
49
|
void loadScript(
|
|
50
50
|
std::unique_ptr<const JSBigString> script,
|
|
51
|
-
const std::string& sourceURL
|
|
51
|
+
const std::string& sourceURL,
|
|
52
|
+
std::function<void(jsi::Runtime& runtime)>&& completion = nullptr);
|
|
52
53
|
|
|
53
54
|
void registerSegment(uint32_t segmentId, const std::string& segmentPath);
|
|
54
55
|
|
|
@@ -470,8 +470,9 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags)
|
|
|
470
470
|
|
|
471
471
|
auto script = std::make_unique<NSDataBigString>(source.data);
|
|
472
472
|
const auto *url = deriveSourceURL(source.url).UTF8String;
|
|
473
|
-
_reactInstance->loadScript(std::move(script), url)
|
|
474
|
-
|
|
473
|
+
_reactInstance->loadScript(std::move(script), url, [](jsi::Runtime &_) {
|
|
474
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:@"RCTInstanceDidLoadBundle" object:nil];
|
|
475
|
+
});
|
|
475
476
|
}
|
|
476
477
|
|
|
477
478
|
- (void)_handleJSError:(const JsErrorHandler::ParsedError &)error
|
package/jest/setup.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-tvos",
|
|
3
|
-
"version": "0.76.
|
|
3
|
+
"version": "0.76.5-0",
|
|
4
4
|
"description": "A framework for building native apps using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -110,13 +110,13 @@
|
|
|
110
110
|
},
|
|
111
111
|
"dependencies": {
|
|
112
112
|
"@jest/create-cache-key-function": "^29.6.3",
|
|
113
|
-
"@react-native/assets-registry": "0.76.
|
|
114
|
-
"@react-native/codegen": "0.76.
|
|
115
|
-
"@react-native/community-cli-plugin": "0.76.
|
|
116
|
-
"@react-native/gradle-plugin": "0.76.
|
|
117
|
-
"@react-native/js-polyfills": "0.76.
|
|
118
|
-
"@react-native/normalize-colors": "0.76.
|
|
119
|
-
"@react-native-tvos/virtualized-lists": "0.76.
|
|
113
|
+
"@react-native/assets-registry": "0.76.5",
|
|
114
|
+
"@react-native/codegen": "0.76.5",
|
|
115
|
+
"@react-native/community-cli-plugin": "0.76.5",
|
|
116
|
+
"@react-native/gradle-plugin": "0.76.5",
|
|
117
|
+
"@react-native/js-polyfills": "0.76.5",
|
|
118
|
+
"@react-native/normalize-colors": "0.76.5",
|
|
119
|
+
"@react-native-tvos/virtualized-lists": "0.76.5-0",
|
|
120
120
|
"abort-controller": "^3.0.0",
|
|
121
121
|
"anser": "^1.4.9",
|
|
122
122
|
"ansi-regex": "^5.0.0",
|
|
@@ -152,6 +152,7 @@ function extractLibrariesFromJSON(configFile, dependencyPath) {
|
|
|
152
152
|
const config = configFile.codegenConfig;
|
|
153
153
|
return [
|
|
154
154
|
{
|
|
155
|
+
libraryName: configFile.name,
|
|
155
156
|
config,
|
|
156
157
|
libraryPath: dependencyPath,
|
|
157
158
|
},
|
|
@@ -252,19 +253,23 @@ function findExternalLibraries(pkgJson, projectRoot) {
|
|
|
252
253
|
});
|
|
253
254
|
}
|
|
254
255
|
|
|
255
|
-
function
|
|
256
|
+
function readRNConfigJSFile(projectRoot) {
|
|
256
257
|
const rnConfigFileName = 'react-native.config.js';
|
|
257
258
|
|
|
258
|
-
console.log(
|
|
259
|
-
`\n\n[Codegen] >>>>> Searching for codegen-enabled libraries in ${rnConfigFileName}`,
|
|
260
|
-
);
|
|
261
|
-
|
|
262
259
|
const rnConfigFilePath = path.resolve(projectRoot, rnConfigFileName);
|
|
263
260
|
|
|
264
261
|
if (!fs.existsSync(rnConfigFilePath)) {
|
|
265
262
|
return [];
|
|
266
263
|
}
|
|
267
|
-
|
|
264
|
+
return require(rnConfigFilePath);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function findLibrariesFromReactNativeConfig(projectRoot) {
|
|
268
|
+
console.log(
|
|
269
|
+
`\n\n[Codegen] >>>>> Searching for codegen-enabled libraries in react-native.config.js`,
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
const rnConfig = readRNConfigJSFile(projectRoot);
|
|
268
273
|
|
|
269
274
|
if (rnConfig.dependencies == null) {
|
|
270
275
|
return [];
|
|
@@ -290,6 +295,48 @@ function findLibrariesFromReactNativeConfig(projectRoot) {
|
|
|
290
295
|
});
|
|
291
296
|
}
|
|
292
297
|
|
|
298
|
+
// Function to look for libraries explicitly unlinked from the app
|
|
299
|
+
// through the react-native.config.js file.
|
|
300
|
+
// If this happens, it might be that the app does not need
|
|
301
|
+
// to generate code for that library as it won't be used by that platform
|
|
302
|
+
// @return { [libraryName: string]: [platform: string] }
|
|
303
|
+
function findNotLinkedLibraries(projectRoot) {
|
|
304
|
+
const rnConfig = readRNConfigJSFile(projectRoot);
|
|
305
|
+
|
|
306
|
+
if (rnConfig.dependencies == null) {
|
|
307
|
+
return {};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
let notLinkedLibraries = {};
|
|
311
|
+
|
|
312
|
+
Object.keys(rnConfig.dependencies).forEach(name => {
|
|
313
|
+
const dependency = rnConfig.dependencies[name];
|
|
314
|
+
let notLinkedPlatforms = [];
|
|
315
|
+
|
|
316
|
+
// dependency.platforms might not be defined, as the format
|
|
317
|
+
// {
|
|
318
|
+
// "dependencies": {
|
|
319
|
+
// "dependency-name": {
|
|
320
|
+
// "root": "path/to/dependency",
|
|
321
|
+
// }
|
|
322
|
+
// }
|
|
323
|
+
// }
|
|
324
|
+
// is also supported.
|
|
325
|
+
// In this case, we assume that the library is linked to all platforms.
|
|
326
|
+
// We don't consider the case were `dependency-name.root` is equal to `null`, because that
|
|
327
|
+
// means that the library is not linked to the app at all, and in that case the dependency
|
|
328
|
+
// should be removed by the user.
|
|
329
|
+
dependency.platforms && Object.keys(dependency.platforms).forEach(platform => {
|
|
330
|
+
if (dependency.platforms[platform] == null) {
|
|
331
|
+
notLinkedPlatforms.push(platform);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
notLinkedLibraries[name] = notLinkedPlatforms;
|
|
335
|
+
|
|
336
|
+
});
|
|
337
|
+
return notLinkedLibraries;
|
|
338
|
+
}
|
|
339
|
+
|
|
293
340
|
function findProjectRootLibraries(pkgJson, projectRoot) {
|
|
294
341
|
console.log('[Codegen] Searching for codegen-enabled libraries in the app.');
|
|
295
342
|
|
|
@@ -695,6 +742,8 @@ function execute(projectRoot, targetPlatform, baseOutputPath) {
|
|
|
695
742
|
let platforms =
|
|
696
743
|
targetPlatform === 'all' ? supportedPlatforms : [targetPlatform];
|
|
697
744
|
|
|
745
|
+
const notLinkedLibraries = findNotLinkedLibraries(projectRoot);
|
|
746
|
+
|
|
698
747
|
for (const platform of platforms) {
|
|
699
748
|
const outputPath = computeOutputPath(
|
|
700
749
|
projectRoot,
|
|
@@ -703,7 +752,19 @@ function execute(projectRoot, targetPlatform, baseOutputPath) {
|
|
|
703
752
|
platform,
|
|
704
753
|
);
|
|
705
754
|
|
|
706
|
-
const schemaInfos = generateSchemaInfos(
|
|
755
|
+
const schemaInfos = generateSchemaInfos(
|
|
756
|
+
libraries.filter(library => {
|
|
757
|
+
const unlinkedPlatforms = notLinkedLibraries[library.libraryName];
|
|
758
|
+
if (unlinkedPlatforms && unlinkedPlatforms.includes(platform)) {
|
|
759
|
+
console.log(
|
|
760
|
+
`[Codegen - ${library.libraryName}] Skipping Codegen on ${platform}`,
|
|
761
|
+
);
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
return true;
|
|
765
|
+
}),
|
|
766
|
+
);
|
|
767
|
+
|
|
707
768
|
generateNativeCode(
|
|
708
769
|
outputPath,
|
|
709
770
|
schemaInfos.filter(schemaInfo =>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|