Compare commits

...
Author SHA1 Message Date
Leland Richardson 44eedabf52 v0.41.100 2017-02-06 17:46:18 -08:00
Ben SchwabandLeland Richardson 4890d56eb1 Adds corner-radius support to ripples created in TouchableNativeFeedback. (#10)
This follows the same approach as b59f99b7e7f69b138860d12959eec9b46cd790a3
but fixes a bug in ReactViewGroup#refreshTranslucentBackgroundDrawable
where a view that has a borderRadius, but no nativeBackground would
not be rendered due to a missing condition case.
2017-02-06 17:07:55 -08:00
Andy ChenandLeland Richardson 619a576f47 Fix RCTImageLoader crash - Cancel network requests from the correct queue
Picked from here:
https://github.com/facebook/react-native/commit/26be005b0a8349afc7f00d8eb0bfe92be85021af
2017-02-06 16:57:30 -08:00
Leland Richardson e9883fd68c Fix Image Cache issues 2017-02-06 16:57:16 -08:00
Jimmy ZhuangandLeland Richardson 70bb4624f1 Support snapToInterval for horizontal scroll view on android 2017-02-06 16:56:57 -08:00
Leland Richardson 936d72a9c7 [Airbnb] Fix imports and private files to work with Swift/CocoaPods 2017-02-06 16:54:28 -08:00
James Ide 9347583d8a [0.41.2] Bump version numbers 2017-02-06 00:30:33 -08:00
James Ide 71785a06b3 [Release] Support the --remote option in bump-oss-version.js script
In my RN checkout, I use "upstream" as my remote instead of "origin" -> this lets me run `scripts/bump-oss-version.js --remote upstream 0.41.1` for example.

Also made the script executable so we don't need to put `node` in front of it, and updated the Releases.md doc.

Test Plan: Did a dry run, saw that without the `--remote` flag the default remote is still `origin` and that specifying the flag let me override the origin.
2017-02-06 00:29:42 -08:00
James Ide fa68531ba2 [React] Use ~15.4.0 (not RC) 2017-02-06 00:16:16 -08:00
Eric VicentiandJames Ide 516d97397b Eject CLI command to re-create native folders
Summary:
The iOS and Android native folders of a React Native app can be difficult to maintain. This introduces a new workflow for creating and maintaining the native code of your app.

Now it will be possible to:

1. Remove the native iOS or Android folders
2. Create an `app.json` for your app, with at least a `name` and `displayName`
3. Run `react-native eject`, and the native code for your app will be generated

Then, as usual, you can run `react-native run-ios` and `react-native run-android`, to build and launch your app

For apps that don't have any native code, it will be possible to ignore the `ios` and `android` folders from version control.

Eject step tested in RN app by deleting native folders.

mkonicek, what is the best way to test `react-native init`?

As follow-up items, we can enable the following:

- Configuring app icon and launch screen from the `app.json`
- Automatically run `react-native link` for native libraries
- A
Closes https://github.com/facebook/react-native/pull/12162

Differential Revision: D4509138

Pulled By: ericvicenti

fbshipit-source-id: 0ee213e68f0a3d44bfce337e3ec43e5024bacc66
2017-02-06 00:11:34 -08:00
Martin Konicek 8b1a34d0ee [0.41.1] Bump version numbers 2017-02-03 18:54:03 +00:00
Mike GrabowskiandMartin Konicek bc72cf1514 Remove build artifacts
Summary:
Ignores `bundle.js` that is a webpack bundle and got most likely accidentally released. Already cherry-picked to 0.42

Fixes #12183
Closes https://github.com/facebook/react-native/pull/12185

Differential Revision: D4507535

Pulled By: mkonicek

fbshipit-source-id: 2ab404534b345cf531f408b654c34a30abd01458
2017-02-03 18:52:35 +00:00
Mike Grabowski 5db36da8a1 [0.41.0] Bump version numbers 2017-02-02 18:51:58 +01:00
Emil SjolanderandMike Grabowski d32cf68ff8 Resolve conflicts 2017-02-02 18:50:41 +01:00
rh389andMike Grabowski 2b087c2c94 Fix template release build: Add -ObjC and -lc++ to tests target
Summary:
Fixes https://github.com/facebook/react-native/issues/11861 - the release config is currently broken for projects created by `react-native init` in `master`, 0.40 and 0.39.

I'm still investigating when and how this got broken but this seems to be a clean fix. I've added `-ObjC` as well to match the main target but I'm not sure yet whether that's necessary.

To test:
```
react-native init fooproject --version react-native@rh389/react-native#missinglinkerflags
```
Open in XCode, Edit scheme (⌘<), Change `Build Configuration` to `Release`, build.

Update: The `-lc++` flag became necessary when https://github.com/facebook/react-native/commit/33deaad196834e77a507cad7b13039161258c059 landed because of the libstdc++ dependencies of `RCTLog`. Still not sure about `-ObjC`. javache ?
Closes https://github.com/facebook/react-native/pull/11889

Differential Revision: D4421685

Pulled By: javache

fbshipit-source-id: 954edaef773f8cef7b7ad671fa4d1f2bfc2f20f2
2017-02-02 17:45:45 +01:00
Tomas RoosandMike Grabowski 7f98028e71 Fixes podspec for master #11640
Summary:
Currently the master Podspec is broken because tvOS files are being included, to avoid this compile error the file is being excluded.

https://github.com/facebook/react-native/commit/c92ad5f6ae74c1d398c7cd93d5c4c50da0ca0430

Thats the commit which introduced the breakage anything later that that will fail. Aka RN 0.41 will fail because of this.

**Test plan (required)**

Tested on new project against master

// cc ide
Closes https://github.com/facebook/react-native/pull/11667

Differential Revision: D4375453

Pulled By: ericvicenti

fbshipit-source-id: 035cdb8ef36054b40d1aaf59551cdc2e16f0cb19
2017-02-02 17:45:18 +01:00
Martin Konicek f1fdd8914a [0.41.0-rc.1] Bump version numbers 2017-01-30 18:44:24 +00:00
Martin Konicek 75f4033ca0 Support ScrollView.scrollToEnd on Android natively
Summary:
This is a followup for https://github.com/facebook/react-native/pull/12088 and implements the scrolling to end on Android natively rather than sending a large scroll offset from JS.

This turned out to be an OK amount of code, and some reduction in the amount of JavaScript. The only part I'm not particularly happy about is:

```
// ScrollView always has one child - the scrollable area
int bottom = scrollView.getChildAt(0).getHeight() + scrollView.getPaddingBottom();
```

According to multiple sources (e.g. [this SO answer](http://stackoverflow.com/questions/3609297/android-total-height-of-scrollview)) it is the way to get the total size of the scrollable area, similar to`scrollView.contentSize` on iOS but more ugly and relying on the fact the ScrollView always has a single child (hopefully this won't change in future versions of Android).

An alternative is:

```
View lastChild = scrollLayout.getChildAt(scrollLayout.getChildCount() - 1);
int bottom = lastChild.getBottom() + scrollLayout.getPadd
Closes https://github.com/facebook/react-native/pull/12101

Differential Revision: D4481523

Pulled By: mkonicek

fbshipit-source-id: 8c7967a0b9e06890c1e1ea70ad573c6eceb03daf
2017-01-30 18:42:46 +00:00
Martin Konicek 7f42a44751 Add scrollToEnd to ScrollView and ListView
Summary:
**Motivation**

A basic task of making a React Native ScrollView or ListView scroll to the bottom is currently very hard to accomplish:
- https://github.com/facebook/react-native/issues/8003
- https://github.com/facebook/react-native/issues/913
- http://stackoverflow.com/questions/29829375/how-to-scroll-to-bottom-in-react-native-listview

**NOTE:** If you're building something like a chat app where you want a ListView to keep scrolling to the bottom at all times, it's easiest to use the [react-native-invertible-scrollview](https://github.com/exponent/react-native-invertible-scroll-view) component rather calling `scrollToEnd` manually when layout changes. The invertible-scrollview uses a clever trick to invert the direction of the ScrollView.

This pull request adds a `scrollToEnd` method which scrolls to the bottom if the ScrollView is vertical, to the right if the ScrollView is horizontal.

The implementation is based on this SO answer:
http://stackoverflow.com/questions/952412/uiscrollview-scrol
Closes https://github.com/facebook/react-native/pull/12088

Differential Revision: D4474974

Pulled By: mkonicek

fbshipit-source-id: 6ecf8b3435f47dd3a31e2fd5be6859062711c233
2017-01-30 18:42:35 +00:00
Mike Grabowski b570c23cfe [0.41.0-rc.0] Bump version numbers 2017-01-04 13:48:22 +01:00
44 changed files with 493 additions and 22769 deletions
@@ -57,6 +57,11 @@ exports.examples = [
onPress={() => { _scrollView.scrollTo({y: 0}); }}>
<Text>Scroll to top</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => { _scrollView.scrollToEnd({animated: true}); }}>
<Text>Scroll to bottom</Text>
</TouchableOpacity>
</View>
);
}
@@ -79,6 +84,11 @@ exports.examples = [
onPress={() => { _scrollView.scrollTo({x: 0}); }}>
<Text>Scroll to start</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => { _scrollView.scrollToEnd({animated: true}); }}>
<Text>Scroll to end</Text>
</TouchableOpacity>
</View>
);
}
@@ -57,6 +57,20 @@ class ScrollViewSimpleExample extends React.Component {
{this.makeItems(NUM_ITEMS, [styles.itemWrapper, styles.horizontalItemWrapper])}
</ScrollView>
);
items.push(
<ScrollView
key={'scrollViewSnap'}
horizontal
snapToInterval={210}
pagingEnabled
>
{this.makeItems(NUM_ITEMS, [
styles.itemWrapper,
styles.horizontalItemWrapper,
styles.horizontalPagingItemWrapper,
])}
</ScrollView>
);
var verticalScrollView = (
<ScrollView style={styles.verticalScrollView}>
@@ -83,7 +97,10 @@ var styles = StyleSheet.create({
},
horizontalItemWrapper: {
padding: 50
}
},
horizontalPagingItemWrapper: {
width: 200,
},
});
module.exports = ScrollViewSimpleExample;
@@ -87,6 +87,7 @@ exports.examples = [
backgroundColor: 'rgb(180, 64, 119)',
width: 200,
height: 100,
borderRadius: 20,
transform: [{scale: mScale}]
};
return (
+23 -3
View File
@@ -377,11 +377,11 @@ var ScrollResponderMixin = {
},
/**
* A helper function to scroll to a specific point in the scrollview.
* This is currently used to help focus on child textviews, but can also
* A helper function to scroll to a specific point in the ScrollView.
* This is currently used to help focus child TextViews, but can also
* be used to quickly scroll to any element we want to focus. Syntax:
*
* scrollResponderScrollTo(options: {x: number = 0; y: number = 0; animated: boolean = true})
* `scrollResponderScrollTo(options: {x: number = 0; y: number = 0; animated: boolean = true})`
*
* Note: The weird argument signature is due to the fact that, for historical reasons,
* the function also accepts separate arguments as as alternative to the options object.
@@ -404,6 +404,26 @@ var ScrollResponderMixin = {
);
},
/**
* Scrolls to the end of the ScrollView, either immediately or with a smooth
* animation.
*
* Example:
*
* `scrollResponderScrollToEnd({animated: true})`
*/
scrollResponderScrollToEnd: function(
options?: { animated?: boolean },
) {
// Default to true
const animated = (options && options.animated) !== false;
UIManager.dispatchViewManagerCommand(
this.scrollResponderGetScrollableNode(),
UIManager.RCTScrollView.Commands.scrollToEnd,
[animated],
);
},
/**
* Deprecated, do not use.
*/
+24 -6
View File
@@ -294,8 +294,8 @@ const ScrollView = React.createClass({
* When set, causes the scroll view to stop at multiples of the value of
* `snapToInterval`. This can be used for paginating through children
* that have lengths smaller than the scroll view. Used in combination
* with `snapToAlignment`.
* @platform ios
* with `snapToAlignment` on ios.
* Supported for horizontal scrollview on android. Use in combination with `pagingEnabled`.
*/
snapToInterval: PropTypes.number,
/**
@@ -382,11 +382,11 @@ const ScrollView = React.createClass({
/**
* Scrolls to a given x, y offset, either immediately or with a smooth animation.
*
* Syntax:
* Example:
*
* `scrollTo(options: {x: number = 0; y: number = 0; animated: boolean = true})`
* `scrollTo({x: 0; y: 0; animated: true})`
*
* Note: The weird argument signature is due to the fact that, for historical reasons,
* Note: The weird function signature is due to the fact that, for historical reasons,
* the function also accepts separate arguments as as alternative to the options object.
* This is deprecated due to ambiguity (y before x), and SHOULD NOT BE USED.
*/
@@ -404,7 +404,25 @@ const ScrollView = React.createClass({
},
/**
* Deprecated, do not use.
* If this is a vertical ScrollView scrolls to the bottom.
* If this is a horizontal ScrollView scrolls to the right.
*
* Use `scrollToEnd({animated: true})` for smooth animated scrolling,
* `scrollToEnd({animated: false})` for immediate scrolling.
* If no options are passed, `animated` defaults to true.
*/
scrollToEnd: function(
options?: { animated?: boolean },
) {
// Default to true
const animated = (options && options.animated) !== false;
this.getScrollResponder().scrollResponderScrollToEnd({
animated: animated,
});
},
/**
* Deprecated, use `scrollTo` instead.
*/
scrollWithoutAnimationTo: function(y: number = 0, x: number = 0) {
console.warn('`scrollWithoutAnimationTo` is deprecated. Use `scrollTo` instead');
@@ -287,6 +287,29 @@ var ListView = React.createClass({
}
},
/**
* If this is a vertical ListView scrolls to the bottom.
* If this is a horizontal ListView scrolls to the right.
*
* Use `scrollToEnd({animated: true})` for smooth animated scrolling,
* `scrollToEnd({animated: false})` for immediate scrolling.
* If no options are passed, `animated` defaults to true.
*
* See `ScrollView#scrollToEnd`.
*/
scrollToEnd: function(options?: { animated?: boolean }) {
if (this._scrollComponent) {
if (this._scrollComponent.scrollToEnd) {
this._scrollComponent.scrollToEnd(options);
} else {
console.warn(
'The scroll component used by the ListView does not support ' +
'scrollToEnd. Check the renderScrollComponent prop of your ListView.'
);
}
}
},
setNativeProps: function(props: Object) {
if (this._scrollComponent) {
this._scrollComponent.setNativeProps(props);
+3 -4
View File
@@ -20,13 +20,12 @@
#import "RCTImageUtils.h"
static const NSUInteger RCTMaxCachableDecodedImageSizeInBytes = 1048576; // 1MB
static const NSUInteger RCTMaxCachableDecodedImageSizeInBytes = 1048576 * 4; // 4MB
static NSString *RCTCacheKeyForImage(NSString *imageTag, CGSize size, CGFloat scale,
RCTResizeMode resizeMode, NSString *responseDate)
{
return [NSString stringWithFormat:@"%@|%g|%g|%g|%zd|%@",
imageTag, size.width, size.height, scale, resizeMode, responseDate];
return [NSString stringWithFormat:@"%@", imageTag];
}
@implementation RCTImageCache
@@ -38,7 +37,7 @@ static NSString *RCTCacheKeyForImage(NSString *imageTag, CGSize size, CGFloat sc
- (instancetype)init
{
_decodedImageCache = [NSCache new];
_decodedImageCache.totalCostLimit = 5 * 1024 * 1024; // 5MB
_decodedImageCache.totalCostLimit = 32 * 1024 * 1024; // 32MB
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(clearCache)
+20 -3
View File
@@ -386,6 +386,9 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
} else {
// Use networking module to load image
cancelLoad = [strongSelf _loadURLRequest:request
size:size
scale:scale
resizeMode:resizeMode
progressBlock:progressHandler
completionBlock:completionHandler];
}
@@ -402,6 +405,9 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
}
- (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request
size:(CGSize)size
scale:(CGFloat)scale
resizeMode:(RCTResizeMode)resizeMode
progressBlock:(RCTImageLoaderProgressBlock)progressHandler
completionBlock:(void (^)(NSError *error, id imageOrData, NSString *fetchDate))completionHandler
{
@@ -413,6 +419,17 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
return NULL;
}
UIImage *image = [[self imageCache] imageForUrl:request.URL.absoluteString
size:size
scale:scale
resizeMode:resizeMode
responseDate:@""];
if (image) {
completionHandler(nil, image, @"");
return ^{ };
}
RCTNetworking *networking = [_bridge networking];
// Check if networking module can load image
@@ -457,9 +474,9 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
// Download image
__weak __typeof(self) weakSelf = self;
__block RCTNetworkTask *task =
[networking networkTaskWithRequest:request
completionBlock:^(NSURLResponse *response, NSData *data, NSError *error) {
__block RCTNetworkTask *task = [networking networkTaskWithRequest:request
completionBlock:^(NSURLResponse *response, NSData *data, NSError *error)
{
__typeof(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
+1 -1
View File
@@ -9,7 +9,7 @@
#import "RCTTextManager.h"
#import <yoga/Yoga.h>
#import <React/Yoga.h>
#import <React/RCTAccessibilityManager.h>
#import <React/RCTAssert.h>
#import <React/RCTConvert.h>
+9 -2
View File
@@ -4,7 +4,7 @@ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = "React"
s.version = package['version']
s.version = "0.41.100"
s.summary = package['description']
s.description = <<-DESC
React Native apps are built using the React JS
@@ -34,19 +34,26 @@ Pod::Spec.new do |s|
ss.dependency 'React/yoga'
ss.dependency 'React/cxxreact'
ss.source_files = "React/**/*.{c,h,m,mm,S}"
ss.exclude_files = "**/__tests__/*", "IntegrationTests/*", "ReactCommon/yoga/*"
ss.exclude_files = "**/__tests__/*", "IntegrationTests/*", "React/**/RCTTVView.*", "ReactCommon/yoga/*"
ss.frameworks = "JavaScriptCore"
ss.libraries = "stdc++"
end
s.subspec 'tvOS' do |ss|
ss.dependency 'React/Core'
ss.source_files = "React/**/RCTTVView.{h, m}"
end
s.subspec 'jschelpers' do |ss|
ss.source_files = 'ReactCommon/jschelpers/{JavaScriptCore,JSCWrapper}.{cpp,h}'
ss.private_header_files = "ReactCommon/jschelpers/{JavaScriptCore,JSCWrapper}.h"
ss.header_dir = 'jschelpers'
end
s.subspec 'cxxreact' do |ss|
ss.dependency 'React/jschelpers'
ss.source_files = 'ReactCommon/cxxreact/{JSBundleType,oss-compat-util}.{cpp,h}'
ss.private_header_files = "ReactCommon/cxxreact/{JSBundleType,oss-compat-util}.h"
ss.header_dir = 'cxxreact'
end
+1 -1
View File
@@ -10,7 +10,7 @@
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import <yoga/Yoga.h>
#import <React/Yoga.h>
#import <React/RCTAnimationType.h>
#import <React/RCTBorderStyle.h>
#import <React/RCTDefines.h>
+2 -2
View File
@@ -11,8 +11,8 @@
#import <sys/stat.h>
#import <cxxreact/JSBundleType.h>
#import <jschelpers/JavaScriptCore.h>
#import <React/JSBundleType.h>
#import <React/JavaScriptCore.h>
#import "RCTBridge.h"
#import "RCTConvert.h"
+4 -4
View File
@@ -480,10 +480,10 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
expectedCount -= 2;
}
RCTLogError(@"%@.%@ was called with %zd arguments, but expects %zd. \
If you haven\'t changed this method yourself, this usually means that \
your versions of the native code and JavaScript code are out of sync. \
Updating both should make this error go away.",
RCTLogError(@"%@.%@ was called with %zd arguments but expects %zd arguments. "
@"If you haven\'t changed this method yourself, this usually means that "
@"your versions of the native code and JavaScript code are out of sync. "
@"Updating both should make this error go away.",
RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName,
actualCount, expectedCount);
return nil;
+1 -1
View File
@@ -9,7 +9,7 @@
#include "RCTJSCErrorHandling.h"
#import <jschelpers/JavaScriptCore.h>
#import <React/JavaScriptCore.h>
#import "RCTAssert.h"
#import "RCTJSStackFrame.h"
+2 -2
View File
@@ -17,8 +17,8 @@
#import <UIKit/UIDevice.h>
#import <cxxreact/JSBundleType.h>
#import <jschelpers/JavaScriptCore.h>
#import <React/JSBundleType.h>
#import <React/JavaScriptCore.h>
#import "JSCSamplingProfiler.h"
#import "RCTAssert.h"
+1 -1
View File
@@ -11,7 +11,7 @@
#import <AVFoundation/AVFoundation.h>
#import <yoga/Yoga.h>
#import <React/Yoga.h>
#import "RCTAccessibilityManager.h"
#import "RCTAnimationType.h"
+26 -1
View File
@@ -588,6 +588,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
_scrollView.contentOffset = contentOffset;
}
- (BOOL)isHorizontal:(UIScrollView *)scrollView
{
return scrollView.contentSize.width > self.frame.size.width;
}
- (void)scrollToOffset:(CGPoint)offset
{
[self scrollToOffset:offset animated:YES];
@@ -602,6 +607,26 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
}
}
/**
* If this is a vertical scroll view, scrolls to the bottom.
* If this is a horizontal scroll view, scrolls to the right.
*/
- (void)scrollToEnd:(BOOL)animated
{
BOOL isHorizontal = [self isHorizontal:_scrollView];
CGPoint offset;
if (isHorizontal) {
offset = CGPointMake(_scrollView.contentSize.width - _scrollView.bounds.size.width, 0);
} else {
offset = CGPointMake(0, _scrollView.contentSize.height - _scrollView.bounds.size.height);
}
if (!CGPointEqualToPoint(_scrollView.contentOffset, offset)) {
// Ensure at least one scroll event will fire
_allowNextScrollNoMatterWhat = YES;
[_scrollView setContentOffset:offset animated:animated];
}
}
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated
{
[_scrollView zoomToRect:rect animated:animated];
@@ -727,7 +752,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
CGFloat snapToIntervalF = (CGFloat)self.snapToInterval;
// Find which axis to snap
BOOL isHorizontal = (scrollView.contentSize.width > self.frame.size.width);
BOOL isHorizontal = [self isHorizontal:scrollView];
// What is the current offset?
CGFloat targetContentOffsetAlongAxis = isHorizontal ? targetContentOffset->x : targetContentOffset->y;
+15
View File
@@ -147,6 +147,21 @@ RCT_EXPORT_METHOD(scrollTo:(nonnull NSNumber *)reactTag
}];
}
RCT_EXPORT_METHOD(scrollToEnd:(nonnull NSNumber *)reactTag
animated:(BOOL)animated)
{
[self.bridge.uiManager addUIBlock:
^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
[(id<RCTScrollableProtocol>)view scrollToEnd:animated];
} else {
RCTLogError(@"tried to scrollTo: on non-RCTScrollableProtocol view %@ "
"with tag #%@", view, reactTag);
}
}];
}
RCT_EXPORT_METHOD(zoomToRect:(nonnull NSNumber *)reactTag
withRect:(CGRect)rect
animated:(BOOL)animated)
+5
View File
@@ -19,6 +19,11 @@
- (void)scrollToOffset:(CGPoint)offset;
- (void)scrollToOffset:(CGPoint)offset animated:(BOOL)animated;
/**
* If this is a vertical scroll view, scrolls to the bottom.
* If this is a horizontal scroll view, scrolls to the right.
*/
- (void)scrollToEnd:(BOOL)animated;
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated;
- (void)addScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener;
+1 -1
View File
@@ -9,7 +9,7 @@
#import <UIKit/UIKit.h>
#import <yoga/Yoga.h>
#import <React/Yoga.h>
#import <React/RCTComponent.h>
#import <React/RCTRootView.h>
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0-master
VERSION_NAME=0.41.100
GROUP=com.facebook.react
POM_NAME=ReactNative
@@ -80,6 +80,15 @@ public class RecyclerViewBackedScrollViewManager extends
scrollView.scrollTo(data.mDestX, data.mDestY, data.mAnimated);
}
@Override
public void scrollToEnd(
RecyclerViewBackedScrollView scrollView,
ReactScrollViewCommandHelper.ScrollToEndCommandData data) {
// Not implemented.
// RecyclerViewBackedScrollView is deprecated and will be removed.
// People should use a standard ScrollView or ListView instead.
}
@Override
public @Nullable
Map getExportedCustomDirectEventTypeConstants() {
@@ -48,6 +48,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
private @Nullable String mScrollPerfTag;
private @Nullable Drawable mEndBackground;
private int mEndFillColor = Color.TRANSPARENT;
private int mSnapInterval = 0;
public ReactHorizontalScrollView(Context context) {
this(context, null);
@@ -88,6 +89,8 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
mPagingEnabled = pagingEnabled;
}
public void setSnapInterval(int snapInterval) { mSnapInterval = snapInterval; }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
MeasureSpecAssertions.assertExplicitMeasureSpec(widthMeasureSpec, heightMeasureSpec);
@@ -295,6 +298,13 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
postOnAnimationDelayed(mPostTouchRunnable, ReactScrollViewHelper.MOMENTUM_DELAY);
}
private int getSnapInterval() {
if (mSnapInterval != 0) {
return mSnapInterval;
}
return getWidth();
}
/**
* This will smooth scroll us to the nearest page boundary
* It currently just looks at where the content is relative to the page and slides to the nearest
@@ -302,7 +312,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
* scrolling.
*/
private void smoothScrollToPage(int velocity) {
int width = getWidth();
int width = getSnapInterval();
int currentX = getScrollX();
// TODO (t11123799) - Should we do anything beyond linear accounting of the velocity
int predictedX = currentX + velocity;
@@ -12,9 +12,11 @@ package com.facebook.react.views.scroll;
import javax.annotation.Nullable;
import android.graphics.Color;
import android.util.DisplayMetrics;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
@@ -58,6 +60,12 @@ public class ReactHorizontalScrollViewManager
view.setScrollEnabled(value);
}
@ReactProp(name = "snapToInterval")
public void setSnapToInterval(ReactHorizontalScrollView view, int snapToInterval) {
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
view.setSnapInterval((int)(snapToInterval * screenDisplayMetrics.density));
}
@ReactProp(name = "showsHorizontalScrollIndicator")
public void setShowsHorizontalScrollIndicator(ReactHorizontalScrollView view, boolean value) {
view.setHorizontalScrollBarEnabled(value);
@@ -117,6 +125,20 @@ public class ReactHorizontalScrollViewManager
}
}
@Override
public void scrollToEnd(
ReactHorizontalScrollView scrollView,
ReactScrollViewCommandHelper.ScrollToEndCommandData data) {
// ScrollView always has one child - the scrollable area
int right =
scrollView.getChildAt(0).getWidth() + scrollView.getPaddingRight();
if (data.mAnimated) {
scrollView.smoothScrollTo(right, scrollView.getScrollY());
} else {
scrollView.scrollTo(right, scrollView.getScrollY());
}
}
/**
* When set, fills the rest of the scrollview with a color to avoid setting a background and
* creating unnecessary overdraw.
@@ -25,9 +25,11 @@ import com.facebook.react.common.MapBuilder;
public class ReactScrollViewCommandHelper {
public static final int COMMAND_SCROLL_TO = 1;
public static final int COMMAND_SCROLL_TO_END = 2;
public interface ScrollCommandHandler<T> {
void scrollTo(T scrollView, ScrollToCommandData data);
void scrollToEnd(T scrollView, ScrollToEndCommandData data);
}
public static class ScrollToCommandData {
@@ -42,10 +44,21 @@ public class ReactScrollViewCommandHelper {
}
}
public static class ScrollToEndCommandData {
public final boolean mAnimated;
ScrollToEndCommandData(boolean animated) {
mAnimated = animated;
}
}
public static Map<String,Integer> getCommandsMap() {
return MapBuilder.of(
"scrollTo",
COMMAND_SCROLL_TO);
COMMAND_SCROLL_TO,
"scrollToEnd",
COMMAND_SCROLL_TO_END);
}
public static <T> void receiveCommand(
@@ -64,6 +77,11 @@ public class ReactScrollViewCommandHelper {
viewManager.scrollTo(scrollView, new ScrollToCommandData(destX, destY, animated));
return;
}
case COMMAND_SCROLL_TO_END: {
boolean animated = args.getBoolean(0);
viewManager.scrollToEnd(scrollView, new ScrollToEndCommandData(animated));
return;
}
default:
throw new IllegalArgumentException(String.format(
"Unsupported command %d received by %s.",
@@ -131,6 +131,20 @@ public class ReactScrollViewManager
}
}
@Override
public void scrollToEnd(
ReactScrollView scrollView,
ReactScrollViewCommandHelper.ScrollToEndCommandData data) {
// ScrollView always has one child - the scrollable area
int bottom =
scrollView.getChildAt(0).getHeight() + scrollView.getPaddingBottom();
if (data.mAnimated) {
scrollView.smoothScrollTo(scrollView.getScrollX(), bottom);
} else {
scrollView.scrollTo(scrollView.getScrollX(), bottom);
}
}
@Override
public @Nullable Map getExportedCustomDirectEventTypeConstants() {
return createExportedCustomDirectEventTypeConstants();
@@ -12,8 +12,8 @@ package com.facebook.react.views.view;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Build;
import android.util.TypedValue;
@@ -23,6 +23,8 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.SoftAssertions;
import com.facebook.react.uimanager.ViewProps;
import javax.annotation.Nullable;
/**
* Utility class that helps with converting android drawable description used in JS to an actual
* instance of {@link Drawable}.
@@ -31,9 +33,16 @@ public class ReactDrawableHelper {
private static final TypedValue sResolveOutValue = new TypedValue();
public static Drawable createDrawableFromJSDescription(
Context context,
ReadableMap drawableDescriptionDict) {
return createDrawableFromJSDescription(context, drawableDescriptionDict, null);
}
public static Drawable createDrawableFromJSDescription(
Context context,
ReadableMap drawableDescriptionDict) {
ReadableMap drawableDescriptionDict,
@Nullable float[] cornerRadii) {
String type = drawableDescriptionDict.getString("type");
if ("ThemeAttrAndroid".equals(type)) {
String attr = drawableDescriptionDict.getString("attribute");
@@ -75,11 +84,14 @@ public class ReactDrawableHelper {
"couldn't be resolved into a drawable");
}
}
Drawable mask = null;
PaintDrawable mask = null;
if (!drawableDescriptionDict.hasKey("borderless") ||
drawableDescriptionDict.isNull("borderless") ||
!drawableDescriptionDict.getBoolean("borderless")) {
mask = new ColorDrawable(Color.WHITE);
drawableDescriptionDict.isNull("borderless") ||
!drawableDescriptionDict.getBoolean("borderless")) {
mask = new PaintDrawable(Color.WHITE);
if (cornerRadii != null) {
mask.setCornerRadii(cornerRadii);
}
}
ColorStateList colorStateList = new ColorStateList(
new int[][] {new int[]{}},
@@ -255,6 +255,25 @@ public class ReactViewBackgroundDrawable extends Drawable {
}
}
/* package */ float[] getBorderRadii() {
float defaultBorderRadius = !YogaConstants.isUndefined(mBorderRadius) ? mBorderRadius : 0;
float topLeftRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[0]) ? mBorderCornerRadii[0] : defaultBorderRadius;
float topRightRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[1]) ? mBorderCornerRadii[1] : defaultBorderRadius;
float bottomRightRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[2]) ? mBorderCornerRadii[2] : defaultBorderRadius;
float bottomLeftRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[3]) ? mBorderCornerRadii[3] : defaultBorderRadius;
return new float[] {
topLeftRadius,
topLeftRadius,
topRightRadius,
topRightRadius,
bottomRightRadius,
bottomRightRadius,
bottomLeftRadius,
bottomLeftRadius
};
}
private void updatePath() {
if (!mNeedUpdatePathForBorderRadius) {
return;
@@ -277,25 +296,12 @@ public class ReactViewBackgroundDrawable extends Drawable {
mTempRectForBorderRadius.inset(fullBorderWidth * 0.5f, fullBorderWidth * 0.5f);
}
float defaultBorderRadius = !YogaConstants.isUndefined(mBorderRadius) ? mBorderRadius : 0;
float topLeftRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[0]) ? mBorderCornerRadii[0] : defaultBorderRadius;
float topRightRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[1]) ? mBorderCornerRadii[1] : defaultBorderRadius;
float bottomRightRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[2]) ? mBorderCornerRadii[2] : defaultBorderRadius;
float bottomLeftRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[3]) ? mBorderCornerRadii[3] : defaultBorderRadius;
float[] borderRadii = getBorderRadii();
mPathForBorderRadius.addRoundRect(
mTempRectForBorderRadius,
new float[] {
topLeftRadius,
topLeftRadius,
topRightRadius,
topRightRadius,
bottomRightRadius,
bottomRightRadius,
bottomLeftRadius,
bottomLeftRadius
},
Path.Direction.CW);
mTempRectForBorderRadius,
borderRadii,
Path.Direction.CW);
float extraRadiusForOutline = 0;
@@ -306,14 +312,14 @@ public class ReactViewBackgroundDrawable extends Drawable {
mPathForBorderRadiusOutline.addRoundRect(
mTempRectForBorderRadiusOutline,
new float[] {
topLeftRadius + extraRadiusForOutline,
topLeftRadius + extraRadiusForOutline,
topRightRadius + extraRadiusForOutline,
topRightRadius + extraRadiusForOutline,
bottomRightRadius + extraRadiusForOutline,
bottomRightRadius + extraRadiusForOutline,
bottomLeftRadius + extraRadiusForOutline,
bottomLeftRadius + extraRadiusForOutline
borderRadii[0] + extraRadiusForOutline,
borderRadii[1] + extraRadiusForOutline,
borderRadii[2] + extraRadiusForOutline,
borderRadii[3] + extraRadiusForOutline,
borderRadii[4] + extraRadiusForOutline,
borderRadii[5] + extraRadiusForOutline,
borderRadii[6] + extraRadiusForOutline,
borderRadii[7] + extraRadiusForOutline
},
Path.Direction.CW);
}
@@ -9,8 +9,6 @@
package com.facebook.react.views.view;
import javax.annotation.Nullable;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
@@ -22,6 +20,7 @@ import android.view.View;
import android.view.ViewGroup;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.touch.ReactHitSlopView;
import com.facebook.react.touch.ReactInterceptingViewGroup;
@@ -32,6 +31,8 @@ import com.facebook.react.uimanager.ReactClippingViewGroup;
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
import com.facebook.react.uimanager.ReactPointerEventsView;
import javax.annotation.Nullable;
/**
* Backing for a React View. Has support for borders, but since borders aren't common, lazy
* initializes most of the storage needed for them.
@@ -96,6 +97,7 @@ public class ReactViewGroup extends ViewGroup implements
private @Nullable ReactViewBackgroundDrawable mReactBackgroundDrawable;
private @Nullable OnInterceptTouchEventListener mOnInterceptTouchEventListener;
private boolean mNeedsOffscreenAlphaCompositing = false;
private @Nullable ReadableMap mNativeBackground;
public ReactViewGroup(Context context) {
super(context);
@@ -136,16 +138,33 @@ public class ReactViewGroup extends ViewGroup implements
"This method is not supported for ReactViewGroup instances");
}
public void setTranslucentBackgroundDrawable(@Nullable Drawable background) {
public void setNativeBackground(@Nullable ReadableMap nativeBackground) {
mNativeBackground = nativeBackground;
refreshTranslucentBackgroundDrawable();
}
public void refreshTranslucentBackgroundDrawable() {
// it's required to call setBackground to null, as in some of the cases we may set new
// background to be a layer drawable that contains a drawable that has been previously setup
// as a background previously. This will not work correctly as the drawable callback logic is
// messed up in AOSP
Drawable background = null;
if (mNativeBackground != null) {
float[] cornerRadii = null;
if (mReactBackgroundDrawable != null) {
cornerRadii = mReactBackgroundDrawable.getBorderRadii();
}
background = ReactDrawableHelper.createDrawableFromJSDescription(getContext(), mNativeBackground, cornerRadii);
}
super.setBackground(null);
if (mReactBackgroundDrawable != null && background != null) {
LayerDrawable layerDrawable =
new LayerDrawable(new Drawable[] {mReactBackgroundDrawable, background});
super.setBackground(layerDrawable);
} else if (mReactBackgroundDrawable != null && background == null) {
super.setBackground(mReactBackgroundDrawable);
} else if (background != null) {
super.setBackground(background);
}
@@ -209,10 +228,12 @@ public class ReactViewGroup extends ViewGroup implements
public void setBorderRadius(float borderRadius) {
getOrCreateReactViewBackground().setRadius(borderRadius);
refreshTranslucentBackgroundDrawable();
}
public void setBorderRadius(float borderRadius, int position) {
getOrCreateReactViewBackground().setRadius(borderRadius, position);
refreshTranslucentBackgroundDrawable();
}
public void setBorderStyle(@Nullable String style) {
@@ -104,8 +104,7 @@ public class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
@ReactProp(name = "nativeBackgroundAndroid")
public void setNativeBackground(ReactViewGroup view, @Nullable ReadableMap bg) {
view.setTranslucentBackgroundDrawable(bg == null ?
null : ReactDrawableHelper.createDrawableFromJSDescription(view.getContext(), bg));
view.setNativeBackground(bg);
}
@TargetApi(Build.VERSION_CODES.M)
+1 -1
View File
@@ -9,7 +9,7 @@
#pragma once
#include <jschelpers/JSCWrapper.h>
#include <React/JSCWrapper.h>
#if defined(__APPLE__)
+8 -4
View File
@@ -2520,19 +2520,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// If the user didn't specify a width or height for the node, set the
// dimensions based on the children.
if (measureModeMainDim == YGMeasureModeUndefined) {
if (measureModeMainDim == YGMeasureModeUndefined ||
(node->style.overflow != YGOverflowScroll && measureModeMainDim == YGMeasureModeAtMost)) {
// Clamp the size to the min/max size, if specified, and make sure it
// doesn't go below the padding and border amount.
node->layout.measuredDimensions[dim[mainAxis]] =
YGNodeBoundAxis(node, mainAxis, maxLineMainDim, mainAxisParentSize, parentWidth);
} else if (measureModeMainDim == YGMeasureModeAtMost) {
} else if (measureModeMainDim == YGMeasureModeAtMost &&
node->style.overflow == YGOverflowScroll) {
node->layout.measuredDimensions[dim[mainAxis]] = fmaxf(
fminf(availableInnerMainDim + paddingAndBorderAxisMain,
YGNodeBoundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim, mainAxisParentSize)),
paddingAndBorderAxisMain);
}
if (measureModeCrossDim == YGMeasureModeUndefined) {
if (measureModeCrossDim == YGMeasureModeUndefined ||
(node->style.overflow != YGOverflowScroll && measureModeCrossDim == YGMeasureModeAtMost)) {
// Clamp the size to the min/max size, if specified, and make sure it
// doesn't go below the padding and border amount.
node->layout.measuredDimensions[dim[crossAxis]] =
@@ -2541,7 +2544,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
totalLineCrossDim + paddingAndBorderAxisCross,
crossAxisParentSize,
parentWidth);
} else if (measureModeCrossDim == YGMeasureModeAtMost) {
} else if (measureModeCrossDim == YGMeasureModeAtMost &&
node->style.overflow == YGOverflowScroll) {
node->layout.measuredDimensions[dim[crossAxis]] =
fmaxf(fminf(availableInnerCrossDim + paddingAndBorderAxisCross,
YGNodeBoundAxisWithinMinAndMax(node,
+7 -6
View File
@@ -44,8 +44,9 @@ Run:
git checkout -b <version_you_are_releasing>-stable
# e.g. git checkout -b 0.22-stable
node ./scripts/bump-oss-version.js <exact-version_you_are_releasing>
# e.g. node ./scripts/bump-oss-version.js 0.22.0-rc
./scripts/bump-oss-version.js <exact-version_you_are_releasing>
# e.g. ./scripts/bump-oss-version.js 0.22.0-rc
# You can use the --remote option to specify a Git remote other than the default "origin"
```
Circle CI will automatically run the tests and publish to npm with the version you have specified (e.g `0.22.0-rc`) and tag `next` meaning that this version will not be installed for users by default.
@@ -112,8 +113,8 @@ git cherry-pick commitHash1
If everything worked:
```bash
node ./scripts/bump-oss-version.js <exact_version_you_are_releasing>
# e.g. node ./scripts/bump-oss-version.js 0.28.0-rc.1
./scripts/bump-oss-version.js <exact_version_you_are_releasing>
# e.g. ./scripts/bump-oss-version.js 0.28.0-rc.1
````
-------------------
@@ -141,8 +142,8 @@ git cherry-pick commitHash1
If everything worked:
```bash
node ./scripts/bump-oss-version.js <exact_version_you_are_releasing>
# e.g. node ./scripts/bump-oss-version.js 0.22.0
./scripts/bump-oss-version.js <exact_version_you_are_releasing>
# e.g. ./scripts/bump-oss-version.js 0.22.0
```
#### Update the release notes
+1
View File
@@ -42,6 +42,7 @@ const documentedCommands = [
require('./library/library'),
require('./bundle/bundle'),
require('./bundle/unbundle'),
require('./eject/eject'),
require('./link/link'),
require('./link/unlink'),
require('./install/install'),
+96
View File
@@ -0,0 +1,96 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const copyProjectTemplateAndReplace = require('../generator/copyProjectTemplateAndReplace');
const path = require('path');
const fs = require('fs');
/**
* The eject command re-creates the `android` and `ios` native folders. Because native code can be
* difficult to maintain, this new script allows an `app.json` to be defined for the project, which
* is used to configure the native app.
*
* The `app.json` config may contain the following keys:
*
* - `name` - The short name used for the project, should be TitleCase
* - `displayName` - The app's name on the home screen
*/
function eject() {
const doesIOSExist = fs.existsSync(path.resolve('ios'));
const doesAndroidExist = fs.existsSync(path.resolve('android'));
if (doesIOSExist && doesAndroidExist) {
console.error(
'Both the iOS and Android folders already exist! Please delete `ios` and/or `android` ' +
'before ejecting.'
);
process.exit(1);
}
let appConfig = null;
try {
appConfig = require(path.resolve('app.json'));
} catch(e) {
console.error(
`Eject requires an \`app.json\` config file to be located at ` +
`${path.resolve('app.json')}, and it must at least specify a \`name\` for the project ` +
`name, and a \`displayName\` for the app's home screen label.`
);
process.exit(1);
}
const appName = appConfig.name;
if (!appName) {
console.error(
`App \`name\` must be defined in the \`app.json\` config file to define the project name. `+
`It must not contain any spaces or dashes.`
);
process.exit(1);
}
const displayName = appConfig.displayName;
if (!displayName) {
console.error(
`App \`displayName\` must be defined in the \`app.json\` config file, to define the label ` +
`of the app on the home screen.`
);
process.exit(1);
}
const templateOptions = { displayName };
if (!doesIOSExist) {
console.log('Generating the iOS folder.');
copyProjectTemplateAndReplace(
path.resolve('node_modules', 'react-native', 'local-cli', 'templates', 'HelloWorld', 'ios'),
path.resolve('ios'),
appName,
templateOptions
);
}
if (!doesAndroidExist) {
console.log('Generating the Android folder.');
copyProjectTemplateAndReplace(
path.resolve('node_modules', 'react-native', 'local-cli', 'templates', 'HelloWorld', 'android'),
path.resolve('android'),
appName,
templateOptions
);
}
}
module.exports = {
name: 'eject',
description: 'Re-create the iOS and Android folders and native code',
func: eject,
options: [],
};
@@ -27,10 +27,12 @@ function copyProjectTemplateAndReplace(srcPath, destPath, newProjectName, option
if (!destPath) { throw new Error('Need a path to copy to'); }
if (!newProjectName) { throw new Error('Need a project name'); }
options = options || {};
walk(srcPath).forEach(absoluteSrcFilePath => {
// 'react-native upgrade'
if (options && options.upgrade) {
if (options.upgrade) {
// Don't upgrade these files
const fileName = path.basename(absoluteSrcFilePath);
// This also includes __tests__/index.*.js
@@ -44,7 +46,7 @@ function copyProjectTemplateAndReplace(srcPath, destPath, newProjectName, option
.replace(/helloworld/g, newProjectName.toLowerCase());
let contentChangedCallback = null;
if (options && options.upgrade && (!options.force)) {
if (options.upgrade && (!options.force)) {
contentChangedCallback = (_, contentChanged) => {
return upgradeFileContentChangedCallback(
absoluteSrcFilePath,
@@ -57,6 +59,7 @@ function copyProjectTemplateAndReplace(srcPath, destPath, newProjectName, option
absoluteSrcFilePath,
path.resolve(destPath, relativeRenamedPath),
{
'Hello App Display Name': options.displayName || newProjectName,
'HelloWorld': newProjectName,
'helloworld': newProjectName.toLowerCase(),
},
@@ -1,2 +1,3 @@
/captures/*
preLoadedCapture.js
bundle.js
File diff suppressed because one or more lines are too long
@@ -1,3 +1,3 @@
<resources>
<string name="app_name">HelloWorld</string>
<string name="app_name">Hello App Display Name</string>
</resources>
+4
View File
@@ -0,0 +1,4 @@
{
"name": "HelloWorld",
"displayName": "HelloWorld"
}
@@ -966,6 +966,10 @@
INFOPLIST_FILE = HelloWorldTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_LDFLAGS = (
"-ObjC",
"-lc++",
);
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorld.app/HelloWorld";
};
@@ -979,6 +983,10 @@
INFOPLIST_FILE = HelloWorldTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_LDFLAGS = (
"-ObjC",
"-lc++",
);
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorld.app/HelloWorld";
};
@@ -4,6 +4,8 @@
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>Hello App Display Name</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "1000.0.0",
"version": "0.41.100",
"description": "A framework for building native apps using React",
"license": "BSD-3-Clause",
"repository": {
@@ -113,7 +113,7 @@
"react-native": "local-cli/wrong-react-native.js"
},
"peerDependencies": {
"react": "~15.4.0-rc.4"
"react": "~15.4.0"
},
"dependencies": {
"absolute-path": "^0.0.0",
@@ -203,9 +203,9 @@
"jest-repl": "18.0.0",
"jest-runtime": "18.0.0",
"mock-fs": "^3.11.0",
"react": "~15.4.0-rc.4",
"react-dom": "~15.4.0-rc.4",
"react-test-renderer": "~15.4.0-rc.4",
"react": "~15.4.0",
"react-dom": "~15.4.0",
"react-test-renderer": "~15.4.0",
"shelljs": "0.6.0",
"sinon": "^2.0.0-pre.2"
}
Regular → Executable
+14 -5
View File
@@ -1,3 +1,4 @@
#!/usr/bin/env node
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -17,6 +18,13 @@
/*eslint-disable no-undef */
require(`shelljs/global`);
const minimist = require('minimist');
let argv = minimist(process.argv.slice(2), {
alias: {remote: 'r'},
default: {remote: 'origin'},
});
// - check we are in release branch, e.g. 0.33-stable
let branch = exec(`git symbolic-ref --short HEAD`, {silent: true}).stdout.trim();
@@ -30,7 +38,7 @@ let versionMajor = branch.slice(0, branch.indexOf(`-stable`));
// - check that argument version matches branch
// e.g. 0.33.1 or 0.33.0-rc4
let version = process.argv[2];
let version = argv._[0];
if (!version || version.indexOf(versionMajor) !== 0) {
echo(`You must pass a tag like ${versionMajor}.[X]-rc[Y] to bump a version`);
exit(1);
@@ -77,17 +85,18 @@ if (exec(`git tag v${version}`).code) {
}
// Push newly created tag
exec(`git push origin v${version}`);
let remote = argv.remote;
exec(`git push ${remote} v${version}`);
// Tag latest if doing stable release
if (version.indexOf(`rc`) === -1) {
exec(`git tag -d latest`);
exec(`git push origin :latest`);
exec(`git push ${remote} :latest`);
exec(`git tag latest`);
exec(`git push origin latest`);
exec(`git push ${remote} latest`);
}
exec(`git push origin ${branch} --follow-tags`);
exec(`git push ${remote} ${branch} --follow-tags`);
exit(0);
/*eslint-enable no-undef */