Compare commits

...
Author SHA1 Message Date
Martin Konicek a769f91ccf [0.19.0] Bump version numbers 2016-01-29 16:03:18 +01:00
Martin Konicek b68bae447d Set fixed width for picker 2016-01-29 15:44:13 +01:00
Martin Konicek 52d2dbe8da Give Android Picker a width so it gets rendered 2016-01-29 15:37:05 +01:00
Martin Konicek 8ed96be6b0 Fix comment in build.gradle 2016-01-29 15:23:12 +01:00
Martin Konicek c4fbfa66c1 Add a cross-platform Picker
Summary:
The basic API is consistent with iOS; there are several platform-specific props.

Also fixed the flickering when a value is selected.

public

Reviewed By: bestander

Differential Revision: D2871092

fb-gh-sync-id: f5cdf6858cb7344b28ee46954cb6b0a3b144b646

Conflicts:
	Examples/UIExplorer/PickerAndroidExample.js
2016-01-29 14:55:45 +01:00
Alex Kotliarskyi 12d96eec91 Skip bundling for Simulator
Summary:
Following up on the conversation in https://www.prod.facebook.com/groups/reactnativeoss/permalink/1516993445263951/ I currently don't see any good reason to create an offline bundle for simulator builds.
Closes https://github.com/facebook/react-native/pull/5519

Reviewed By: svcscm

Differential Revision: D2859751

Pulled By: mkonicek

fb-gh-sync-id: f70481e447e258f5531de773729fc31d9ebec6f7
2016-01-29 14:38:01 +01:00
Alex Kotliarskyi d403c24493 Improve react-native-xcode.sh integration
Summary:
Inspired by conversation in https://github.com/facebook/react-native/pull/5374, this PR improves `react-native-xcode.sh`:

* No longer depends on global `react-native` binary
* Gracefully handles missing `node` dependency and adds a new way to configure the path to `node` in non-standard installation environments

This is how the error looks like:
![image](https://cloud.githubusercontent.com/assets/192222/12538882/3f9b5c3e-c29a-11e5-84fc-c7ccedf1c46a.png)
Closes https://github.com/facebook/react-native/pull/5518

Reviewed By: svcscm

Differential Revision: D2861116

Pulled By: frantic

fb-gh-sync-id: 9a80eda6c844d066e34369b1cda503955171485b
2016-01-29 14:37:27 +01:00
Henrik Kok Jørgensen 9f07e1f306 Dont call npm before node is available
Summary:
This fixes an error introduced in `0.18.0-rc`

`node` and `npm` isn't available if the developer is using `nvm` or `nodeenv`. XCode throws an error because of the call to `npm`. Simple move the line to after `node` and `npm` has been setup.
Closes https://github.com/facebook/react-native/pull/5156

Reviewed By: svcscm

Differential Revision: D2807589

Pulled By: androidtrunkagent

fb-gh-sync-id: 30c33145b2cb6f30ff67f6648153d5aa67fb74ed
2016-01-29 14:36:42 +01:00
Dave Miller ca47230955 Fix a crash in Image when passed an invalid uri
Summary:
public

Fix https://github.com/facebook/react-native/issues/5465

Instead of returning null when we fail to parse the Uri, just return an empty Uri which somewhat hides the problem but does prevent the crash

Reviewed By: mkonicek

Differential Revision: D2854902

fb-gh-sync-id: 71265d5e52302e174b898af5be25ac698abcf9ab
2016-01-29 14:34:03 +01:00
Huang Yu 0acba126f9 Fix StyleSheet 'textAlign' for AndroidTextInput. Closes #2702
Summary:
change `setTextAlign` and `setTextAlignVertical` to receive argument of type `String` (the same as in `StyleSheet`), so that native props and stylesheet props are calling the same ReactMethod

- add demo (may not be necessary)
Closes https://github.com/facebook/react-native/pull/4481

Reviewed By: svcscm

Differential Revision: D2823456

Pulled By: mkonicek

fb-gh-sync-id: 349d17549f419b5bdc001d70b583423ade06bfe8
2016-01-29 14:33:54 +01:00
Sokovikov 90dd33726c Android AppState
Summary: Closes https://github.com/facebook/react-native/pull/5152

Reviewed By: svcscm

Differential Revision: D2850250

Pulled By: mkonicek

fb-gh-sync-id: 0b5063fa7121d4e304a70da8573c9ba1d05a757c
2016-01-29 14:33:40 +01:00
Martin Konicek eb3df43818 When using split builds, don't generate universal APK
Summary:
Closes https://github.com/facebook/react-native/issues/5452

public

Reviewed By: foghina

Differential Revision: D2849769

fb-gh-sync-id: 93a53b05dc39560529a916fbeeb74efa761a7d7e
2016-01-29 14:33:24 +01:00
Martin Konicek f514409495 Disable menu option for HMR, it's not ready just yet 2016-01-29 14:33:10 +01:00
Martin Konicek 6f5acbd95a Revert "Dont call npm before node is available"
This reverts commit 7ecb6936bc.
2016-01-21 12:55:39 +00:00
Konstantin Raev 2f1ed20a6e [0.19.0-rc] Bump version numbers 2016-01-20 15:07:26 +00:00
29 changed files with 772 additions and 369 deletions
+80
View File
@@ -0,0 +1,80 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @providesModule AppStateExample
* @flow
*/
'use strict';
var React = require('react-native');
var {
AppState,
Text,
View
} = React;
var AppStateSubscription = React.createClass({
getInitialState() {
return {
appState: AppState.currentState,
previousAppStates: [],
};
},
componentDidMount: function() {
AppState.addEventListener('change', this._handleAppStateChange);
},
componentWillUnmount: function() {
AppState.removeEventListener('change', this._handleAppStateChange);
},
_handleAppStateChange: function(appState) {
var previousAppStates = this.state.previousAppStates.slice();
previousAppStates.push(this.state.appState);
this.setState({
appState,
previousAppStates,
});
},
render() {
if (this.props.showCurrentOnly) {
return (
<View>
<Text>{this.state.appState}</Text>
</View>
);
}
return (
<View>
<Text>{JSON.stringify(this.state.previousAppStates)}</Text>
</View>
);
}
});
exports.title = 'AppState';
exports.description = 'app background status';
exports.examples = [
{
title: 'AppState.currentState',
description: 'Can be null on app initialization',
render() { return <Text>{AppState.currentState}</Text>; }
},
{
title: 'Subscribed AppState:',
description: 'This changes according to the current state, so you can only ever see it rendered as "active"',
render(): ReactElement { return <AppStateSubscription showCurrentOnly={true} />; }
},
{
title: 'Previous states:',
render(): ReactElement { return <AppStateSubscription showCurrentOnly={false} />; }
},
];
+68 -70
View File
@@ -16,25 +16,31 @@
'use strict';
const React = require('react-native');
const StyleSheet = require('StyleSheet');
const UIExplorerBlock = require('UIExplorerBlock');
const UIExplorerPage = require('UIExplorerPage');
const {
PickerAndroid,
Picker,
Text,
TouchableWithoutFeedback,
} = React;
const Item = PickerAndroid.Item;
const Item = Picker.Item;
const PickerExample = React.createClass({
statics: {
title: '<Picker>',
description: 'Provides multiple options to choose from, using either a dropdown menu or a dialog.',
},
const PickerAndroidExample = React.createClass({
getInitialState: function() {
return {
selected1: 'key1',
selected2: 'key1',
selected3: 'key1',
selected4: 'key1',
color: 'red',
mode: PickerAndroid.MODE_DIALOG,
mode: Picker.MODE_DIALOG,
};
},
@@ -42,101 +48,93 @@ const PickerAndroidExample = React.createClass({
render: function() {
return (
<UIExplorerPage title="<PickerAndroid>">
<UIExplorerPage title="<Picker>">
<UIExplorerBlock title="Basic Picker">
<PickerAndroid
style={{width: 100, height: 56}}
onSelect={this.onSelect.bind(this, 'selected1')}>
<Item text="hello" value="key0" selected={this.state.selected1 === 'key0'} />
<Item text="world" value="key1" selected={this.state.selected1 === 'key1'} />
</PickerAndroid>
<Picker
style={styles.picker}
selectedValue={this.state.selected1}
onValueChange={this.onValueChange.bind(this, 'selected1')}>
<Item label="hello" value="key0" />
<Item label="world" value="key1" />
</Picker>
</UIExplorerBlock>
<UIExplorerBlock title="Disabled picker">
<PickerAndroid style={{width: 100, height: 56}} enabled={false}>
<Item text="hello" value="key0" selected={this.state.selected1 === 'key0'} />
<Item text="world" value="key1" selected={this.state.selected1 === 'key1'} />
</PickerAndroid>
<Picker style={styles.picker} enabled={false} selectedValue={this.state.selected1}>
<Item label="hello" value="key0" />
<Item label="world" value="key1" />
</Picker>
</UIExplorerBlock>
<UIExplorerBlock title="Dropdown Picker">
<PickerAndroid
style={{width: 100, height: 56}}
onSelect={this.onSelect.bind(this, 'selected2')}
<Picker
style={styles.picker}
selectedValue={this.state.selected2}
onValueChange={this.onValueChange.bind(this, 'selected2')}
mode="dropdown">
<Item text="hello" value="key0" selected={this.state.selected2 === 'key0'} />
<Item text="world" value="key1" selected={this.state.selected2 === 'key1'} />
</PickerAndroid>
</UIExplorerBlock>
<UIExplorerBlock title="Alternating Picker">
<PickerAndroid
style={{width: 100, height: 56}}
onSelect={this.onSelect.bind(this, 'selected3')}
mode={this.state.mode}>
<Item text="hello" value="key0" selected={this.state.selected3 === 'key0'} />
<Item text="world" value="key1" selected={this.state.selected3 === 'key1'} />
</PickerAndroid>
<TouchableWithoutFeedback onPress={this.changeMode}>
<Text>Tap here to switch between dialog/dropdown.</Text>
</TouchableWithoutFeedback>
<Item label="hello" value="key0" />
<Item label="world" value="key1" />
</Picker>
</UIExplorerBlock>
<UIExplorerBlock title="Picker with prompt message">
<PickerAndroid
style={{width: 100, height: 56}}
onSelect={this.onSelect.bind(this, 'selected4')}
<Picker
style={styles.picker}
selectedValue={this.state.selected3}
onValueChange={this.onValueChange.bind(this, 'selected3')}
prompt="Pick one, just one">
<Item text="hello" value="key0" selected={this.state.selected4 === 'key0'} />
<Item text="world" value="key1" selected={this.state.selected4 === 'key1'} />
</PickerAndroid>
<Item label="hello" value="key0" />
<Item label="world" value="key1" />
</Picker>
</UIExplorerBlock>
<UIExplorerBlock title="Picker with no listener">
<PickerAndroid style={{width: 100, height: 56}}>
<Item text="hello" value="key0" />
<Item text="world" value="key1" />
</PickerAndroid>
<Picker style={styles.picker}>
<Item label="hello" value="key0" />
<Item label="world" value="key1" />
</Picker>
<Text>
You can not change the value of this picker because it doesn't set a selected prop on
its items.
Cannot change the value of this picker because it doesn't update selectedValue.
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Colorful pickers">
<PickerAndroid style={{width: 100, height: 56, color: 'black'}}
onSelect={this.onSelect.bind(this, 'color')}
<Picker
style={[styles.picker, {color: 'white', backgroundColor: '#333'}]}
selectedValue={this.state.color}
onValueChange={this.onValueChange.bind(this, 'color')}
mode="dropdown">
<Item text="red" color="red" value="red" selected={this.state.color === 'red'}/>
<Item text="green" color="green" value="green" selected={this.state.color === 'green'}/>
<Item text="blue" color="blue" value="blue" selected={this.state.color === 'blue'}/>
</PickerAndroid>
<PickerAndroid style={{width: 100, height: 56}}
onSelect={this.onSelect.bind(this, 'color')}
<Item label="red" color="red" value="red" />
<Item label="green" color="green" value="green" />
<Item label="blue" color="blue" value="blue" />
</Picker>
<Picker
style={styles.picker}
selectedValue={this.state.color}
onValueChange={this.onValueChange.bind(this, 'color')}
mode="dialog">
<Item text="red" color="red" value="red" selected={this.state.color === 'red'}/>
<Item text="green" color="green" value="green" selected={this.state.color === 'green'}/>
<Item text="blue" color="blue" value="blue" selected={this.state.color === 'blue'} />
</PickerAndroid>
<Item label="red" color="red" value="red" />
<Item label="green" color="green" value="green" />
<Item label="blue" color="blue" value="blue" />
</Picker>
</UIExplorerBlock>
</UIExplorerPage>
);
},
changeMode: function() {
const newMode = this.state.mode === PickerAndroid.MODE_DIALOG
? PickerAndroid.MODE_DROPDOWN
: PickerAndroid.MODE_DIALOG;
const newMode = this.state.mode === Picker.MODE_DIALOG
? Picker.MODE_DROPDOWN
: Picker.MODE_DIALOG;
this.setState({mode: newMode});
},
onSelect: function(key, value) {
onValueChange: function(key: string, value: string) {
const newState = {};
newState[key] = value;
this.setState(newState);
},
});
exports.title = '<PickerAndroid>';
exports.displayName = 'PickerAndroidExample';
exports.description = 'The Android Picker component provides multiple options to choose from';
exports.examples = [
{
title: 'PickerAndroidExample',
render(): ReactElement { return <PickerAndroidExample />; }
var styles = StyleSheet.create({
picker: {
width: 100,
},
];
});
module.exports = PickerExample;
@@ -348,25 +348,19 @@ exports.examples = [
placeholder="multiline, aligned top-left"
placeholderTextColor="red"
multiline={true}
textAlign="start"
textAlignVertical="top"
style={styles.multiline}
style={[styles.multiline, {textAlign: "left", textAlignVertical: "top"}]}
/>
<TextInput
autoCorrect={true}
placeholder="multiline, aligned center"
placeholderTextColor="green"
multiline={true}
textAlign="center"
textAlignVertical="center"
style={[styles.multiline]}
style={[styles.multiline, {textAlign: "center", textAlignVertical: "center"}]}
/>
<TextInput
autoCorrect={true}
multiline={true}
textAlign="end"
textAlignVertical="bottom"
style={[styles.multiline, {color: 'blue'}]}>
style={[styles.multiline, {color: 'blue'}, {textAlign: "right", textAlignVertical: "bottom"}]}>
<Text style={styles.multiline}>multiline with children, aligned bottom-right</Text>
</TextInput>
</View>
@@ -43,6 +43,7 @@ var COMPONENTS = [
var APIS = [
require('./AccessibilityAndroidExample.android'),
require('./AlertExample').AlertExample,
require('./AppStateExample'),
require('./BorderExample'),
require('./CameraRollExample'),
require('./ClipboardExample'),
@@ -64,6 +64,7 @@ var APIS = [
require('./AnimatedExample'),
require('./AnimatedGratuitousApp/AnExApp'),
require('./AppStateIOSExample'),
require('./AppStateExample'),
require('./AsyncStorageExample'),
require('./BorderExample'),
require('./BoxShadowExample'),
+147
View File
@@ -0,0 +1,147 @@
/**
* 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.
*
* @providesModule AppState
* @flow
*/
'use strict';
var Map = require('Map');
var NativeModules = require('NativeModules');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var RCTAppState = NativeModules.AppState;
var logError = require('logError');
var invariant = require('invariant');
var _eventHandlers = {
change: new Map(),
memoryWarning: new Map(),
};
/**
* `AppState` can tell you if the app is in the foreground or background,
* and notify you when the state changes.
*
* AppState is frequently used to determine the intent and proper behavior when
* handling push notifications.
*
* ### App States
*
* - `active` - The app is running in the foreground
* - `background` - The app is running in the background. The user is either
* in another app or on the home screen
* - `inactive` - This is a transition state that currently never happens for
* typical React Native apps.
*
* For more information, see
* [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html)
*
* ### Basic Usage
*
* To see the current state, you can check `AppState.currentState`, which
* will be kept up-to-date. However, `currentState` will be null at launch
* while `AppState` retrieves it over the bridge.
*
* ```
* getInitialState: function() {
* return {
* currentAppState: AppState.currentState,
* };
* },
* componentDidMount: function() {
* AppState.addEventListener('change', this._handleAppStateChange);
* },
* componentWillUnmount: function() {
* AppState.removeEventListener('change', this._handleAppStateChange);
* },
* _handleAppStateChange: function(currentAppState) {
* this.setState({ currentAppState, });
* },
* render: function() {
* return (
* <Text>Current state is: {this.state.currentAppState}</Text>
* );
* },
* ```
*
* This example will only ever appear to say "Current state is: active" because
* the app is only visible to the user when in the `active` state, and the null
* state will happen only momentarily.
*/
var AppState = {
/**
* Add a handler to AppState changes by listening to the `change` event type
* and providing the handler
*/
addEventListener: function(
type: string,
handler: Function
) {
invariant(
['change', 'memoryWarning'].indexOf(type) !== -1,
'Trying to subscribe to unknown event: "%s"', type
);
if (type === 'change') {
_eventHandlers[type].set(handler, RCTDeviceEventEmitter.addListener(
'appStateDidChange',
(appStateData) => {
handler(appStateData.app_state);
}
));
} else if (type === 'memoryWarning') {
_eventHandlers[type].set(handler, RCTDeviceEventEmitter.addListener(
'memoryWarning',
handler
));
}
},
/**
* Remove a handler by passing the `change` event type and the handler
*/
removeEventListener: function(
type: string,
handler: Function
) {
invariant(
['change', 'memoryWarning'].indexOf(type) !== -1,
'Trying to remove listener for unknown event: "%s"', type
);
if (!_eventHandlers[type].has(handler)) {
return;
}
_eventHandlers[type].get(handler).remove();
_eventHandlers[type].delete(handler);
},
// TODO: getCurrentAppState callback seems to be called at a really late stage
// after app launch. Trying to get currentState when mounting App component
// will likely to have the initial value here.
// Initialize to 'active' instead of null.
currentState: ('active' : ?string),
};
RCTDeviceEventEmitter.addListener(
'appStateDidChange',
(appStateData) => {
AppState.currentState = appStateData.app_state;
}
);
RCTAppState.getCurrentAppState(
(appStateData) => {
AppState.currentState = appStateData.app_state;
},
logError
);
module.exports = AppState;
+156
View File
@@ -0,0 +1,156 @@
/**
* 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.
*
* @providesModule Picker
* @flow
*/
'use strict';
var ColorPropType = require('ColorPropType');
var PickerIOS = require('PickerIOS');
var PickerAndroid = require('PickerAndroid');
var Platform = require('Platform');
var React = require('React');
var StyleSheet = require('StyleSheet');
var StyleSheetPropType = require('StyleSheetPropType');
var TextStylePropTypes = require('TextStylePropTypes');
var UnimplementedView = require('UnimplementedView');
var View = require('View');
var ViewStylePropTypes = require('ViewStylePropTypes');
var itemStylePropType = StyleSheetPropType(TextStylePropTypes);
var pickerStyleType = StyleSheetPropType({
...ViewStylePropTypes,
color: ColorPropType,
});
var MODE_DIALOG = 'dialog';
var MODE_DROPDOWN = 'dropdown';
/**
* Renders the native picker component on iOS and Android. Example:
*
* <Picker
* selectedValue={this.state.language}
* onValueChange={(lang) => this.setState({language: lang})}>
* <Picker.Item label="Java" value="java" />
* <Picker.Item label="JavaScript" value="js" />
* </Picker>
*
* Note: The picker has a default fixed height which you can modify
* using `style` if needed. To set the width, you can use `style`
* as well, e.g. to set a fixed width or stretch the picker horizontally.
*/
var Picker = React.createClass({
statics: {
/**
* On Android, display the options in a dialog.
*/
MODE_DIALOG: MODE_DIALOG,
/**
* On Android, display the options in a dropdown (this is the default).
*/
MODE_DROPDOWN: MODE_DROPDOWN,
},
getDefaultProps: function() {
return {
mode: MODE_DIALOG,
};
},
propTypes: {
...View.propTypes,
style: pickerStyleType,
/**
* Value matching value of one of the items. Can be a string or an integer.
*/
selectedValue: React.PropTypes.any,
/**
* Callback for when an item is selected. This is called with the following parameters:
* - `itemValue`: the `value` prop of the item that was selected
* - `itemPosition`: the index of the selected item in this picker
*/
onValueChange: React.PropTypes.func,
/**
* If set to false, the picker will be disabled, i.e. the user will not be able to make a
* selection.
* @platform android
*/
enabled: React.PropTypes.bool,
/**
* On Android, specifies how to display the selection items when the user taps on the picker:
* - 'dialog': Show a modal dialog. This is the default.
* - 'dropdown': Shows a dropdown anchored to the picker view
*
* @platform android
*/
mode: React.PropTypes.oneOf([MODE_DIALOG, MODE_DROPDOWN]),
/**
* Style to apply to each of the item labels.
* @platform ios
*/
itemStyle: itemStylePropType,
/**
* Prompt string for this picker, used on Android in dialog mode as the title of the dialog.
* @platform android
*/
prompt: React.PropTypes.string,
/**
* Used to locate this view in end-to-end tests.
*/
testID: React.PropTypes.string,
},
render: function() {
if (Platform.OS === 'ios') {
return <PickerIOS {...this.props}>{this.props.children}</PickerIOS>;
} else if (Platform.OS === 'android') {
return <PickerAndroid {...this.props}>{this.props.children}</PickerAndroid>;
} else {
return <UnimplementedView />;
}
},
});
/**
* Individual selectable item in a Picker.
*/
Picker.Item = React.createClass({
propTypes: {
/**
* Text to display for this item.
*/
label: React.PropTypes.string.isRequired,
/**
* The value to be passed to picker's `onValueChange` callback when
* this item is selected. Can be a string or an integer.
*/
value: React.PropTypes.any,
/**
* Color of this item's text.
* @platform android
*/
color: ColorPropType,
/**
* Used to locate the item in end-to-end tests.
*/
testID: React.PropTypes.string,
},
render: function() {
// The items are not rendered directly
throw null;
},
});
module.exports = Picker;
@@ -0,0 +1,141 @@
/**
* 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.
*
* @providesModule PickerAndroid
* @flow
*/
'use strict';
var ColorPropType = require('ColorPropType');
var React = require('React');
var ReactChildren = require('ReactChildren');
var ReactPropTypes = require('ReactPropTypes');
var StyleSheet = require('StyleSheet');
var StyleSheetPropType = require('StyleSheetPropType');
var View = require('View');
var ViewStylePropTypes = require('ViewStylePropTypes');
var processColor = require('processColor');
var requireNativeComponent = require('requireNativeComponent');
var REF_PICKER = 'picker';
var MODE_DIALOG = 'dialog';
var MODE_DROPDOWN = 'dropdown';
var pickerStyleType = StyleSheetPropType({
...ViewStylePropTypes,
color: ColorPropType,
});
type Event = Object;
/**
* Not exposed as a public API - use <Picker> instead.
*/
var PickerAndroid = React.createClass({
propTypes: {
...View.propTypes,
style: pickerStyleType,
selectedValue: React.PropTypes.any,
enabled: ReactPropTypes.bool,
mode: ReactPropTypes.oneOf(['dialog', 'dropdown']),
onValueChange: ReactPropTypes.func,
prompt: ReactPropTypes.string,
testID: ReactPropTypes.string,
},
getInitialState: function() {
return this._stateFromProps(this.props);
},
componentWillReceiveProps: function(nextProps) {
this.setState(this._stateFromProps(nextProps));
},
// Translate prop and children into stuff that the native picker understands.
_stateFromProps: function(props) {
var selectedIndex = 0;
let items = ReactChildren.map(props.children, (child, index) => {
if (child.props.value === props.selectedValue) {
selectedIndex = index;
}
let childProps = {
value: child.props.value,
label: child.props.label,
};
if (child.props.color) {
childProps.color = processColor(child.props.color);
}
return childProps;
});
return {selectedIndex, items};
},
render: function() {
var Picker = this.props.mode === MODE_DROPDOWN ? DropdownPicker : DialogPicker;
var nativeProps = {
enabled: this.props.enabled,
items: this.state.items,
mode: this.props.mode,
onSelect: this._onChange,
prompt: this.props.prompt,
selected: this.state.selectedIndex,
testID: this.props.testID,
style: [styles.pickerAndroid, this.props.style],
};
return <Picker ref={REF_PICKER} {...nativeProps} />;
},
_onChange: function(event: Event) {
if (this.props.onValueChange) {
var position = event.nativeEvent.position;
if (position >= 0) {
var value = this.props.children[position].props.value;
this.props.onValueChange(value);
} else {
this.props.onValueChange(null);
}
}
// The picker is a controlled component. This means we expect the
// on*Change handlers to be in charge of updating our
// `selectedValue` prop. That way they can also
// disallow/undo/mutate the selection of certain values. In other
// words, the embedder of this component should be the source of
// truth, not the native component.
if (this.refs[REF_PICKER] && this.state.selectedIndex !== event.nativeEvent.position) {
this.refs[REF_PICKER].setNativeProps({selected: this.state.selectedIndex});
}
},
});
var styles = StyleSheet.create({
pickerAndroid: {
// We have to set the picker's dimensions explicitly to ensure
// it gets rendered.
// TODO would be better to export a native constant for this,
// like in iOS the RCTDatePickerManager.m
width: 80,
height: 50,
},
});
var cfg = {
nativeOnly: {
items: true,
selected: true,
}
}
var DropdownPicker = requireNativeComponent('AndroidDropdownPicker', PickerAndroid, cfg);
var DialogPicker = requireNativeComponent('AndroidDialogPicker', PickerAndroid, cfg);
module.exports = PickerAndroid;
@@ -0,0 +1,13 @@
/**
* 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.
*
* @providesModule PickerAndroid
*/
'use strict';
module.exports = require('UnimplementedView');
@@ -1,213 +0,0 @@
/**
* 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.
*
* @providesModule PickerAndroid
* @flow
*/
'use strict';
var ColorPropType = require('ColorPropType');
var React = require('React');
var ReactChildren = require('ReactChildren');
var ReactPropTypes = require('ReactPropTypes');
var StyleSheetPropType = require('StyleSheetPropType');
var View = require('View');
var ViewStylePropTypes = require('ViewStylePropTypes');
var processColor = require('processColor');
var requireNativeComponent = require('requireNativeComponent');
var MODE_DIALOG = 'dialog';
var MODE_DROPDOWN = 'dropdown';
var REF_PICKER = 'picker';
var pickerStyleType = StyleSheetPropType({
...ViewStylePropTypes,
color: ColorPropType,
});
type Items = {
selected: number;
items: any[];
};
type Event = Object;
/**
* Individual selectable item in a Picker.
*/
var Item = React.createClass({
propTypes: {
/**
* Color of this item's text.
*/
color: ColorPropType,
/**
* Text to display for this item.
*/
text: ReactPropTypes.string.isRequired,
/**
* The value to be passed to picker's `onSelect` callback when this item is selected.
*/
value: ReactPropTypes.string,
/**
* If `true`, this item is selected and shown in the picker.
* Usually this is set based on state.
*/
selected: ReactPropTypes.bool,
/**
* Used to locate this view in end-to-end tests.
*/
testID: ReactPropTypes.string,
},
render: function() {
throw new Error('Picker items should never be rendered');
},
});
/**
* <PickerAndroid> - A React component that renders the native Picker widget on Android. The items
* that can be selected are specified as children views of type Item. Example usage:
*
* <PickerAndroid>
* <PickerAndroid.Item text="Java" value="js" />
* <PickerAndroid.Item text="JavaScript" value="java" selected={true} />
* </PickerAndroid>
*/
var PickerAndroid = React.createClass({
propTypes: {
...View.propTypes,
style: pickerStyleType,
/**
* If set to false, the picker will be disabled, i.e. the user will not be able to make a
* selection.
*/
enabled: ReactPropTypes.bool,
/**
* Specifies how to display the selection items when the user taps on the picker:
*
* - dialog: Show a modal dialog
* - dropdown: Shows a dropdown anchored to the picker view
*/
mode: ReactPropTypes.oneOf([MODE_DIALOG, MODE_DROPDOWN]),
/**
* Callback for when an item is selected. This is called with the following parameters:
*
* - `itemValue`: the `value` prop of the item that was selected
* - `itemPosition`: the index of the selected item in this picker
*/
onSelect: ReactPropTypes.func,
/**
* Prompt string for this picker, currently only used in `dialog` mode as the title of the
* dialog.
*/
prompt: ReactPropTypes.string,
/**
* Used to locate this view in end-to-end tests.
*/
testID: ReactPropTypes.string,
},
statics: {
Item: Item,
MODE_DIALOG: MODE_DIALOG,
MODE_DROPDOWN: MODE_DROPDOWN,
},
getDefaultProps: function() {
return {
mode: MODE_DIALOG,
};
},
render: function() {
var Picker = this.props.mode === MODE_DROPDOWN ? DropdownPicker : DialogPicker;
var { selected, items } = this._getItems();
var nativeProps = {
enabled: this.props.enabled,
items: items,
mode: this.props.mode,
onSelect: this._onSelect,
prompt: this.props.prompt,
selected: selected,
style: this.props.style,
testID: this.props.testID,
};
return <Picker ref={REF_PICKER} {...nativeProps} />;
},
/**
* Transform this view's children into an array of items to be passed to the native component.
* Since we're traversing the children, also determine the selected position.
*
* @returns an object with two keys:
*
* - `selected` (number) - the index of the selected item
* - `items` (array) - the items of this picker, as an array of strings
*/
_getItems: function(): Items {
var items = [];
var selected = 0;
ReactChildren.forEach(this.props.children, function(child, index) {
var childProps = Object.assign({}, child.props);
if (childProps.color) {
childProps.color = processColor(childProps.color);
}
items.push(childProps);
if (childProps.selected) {
selected = index;
}
});
return {
selected: selected,
items: items,
};
},
_onSelect: function(event: Event) {
if (this.props.onSelect) {
var position = event.nativeEvent.position;
if (position >= 0) {
var value = this.props.children[position].props.value;
this.props.onSelect(value, position);
} else {
this.props.onSelect(null, position);
}
}
// The native Picker has changed, but the props haven't (yet). If
// the handler decides to not accept the new value or do something
// else with it we might end up in a bad state, so we reset the
// selection on the native component.
// tl;dr: PickerAndroid is a controlled component.
var { selected } = this._getItems();
if (this.refs[REF_PICKER]) {
this.refs[REF_PICKER].setNativeProps({selected: selected});
}
},
});
var cfg = {
nativeOnly: {
items: true,
selected: true,
}
}
var DropdownPicker = requireNativeComponent('AndroidDropdownPicker', PickerAndroid, cfg);
var DialogPicker = requireNativeComponent('AndroidDialogPicker', PickerAndroid, cfg);
module.exports = PickerAndroid;
@@ -101,24 +101,6 @@ var TextInput = React.createClass({
* The default value is false.
*/
autoFocus: PropTypes.bool,
/**
* Set the position of the cursor from where editing will begin.
* @platform android
*/
textAlign: PropTypes.oneOf([
'start',
'center',
'end',
]),
/**
* Aligns text vertically within the TextInput.
* @platform android
*/
textAlignVertical: PropTypes.oneOf([
'top',
'center',
'bottom',
]),
/**
* If false, text is not editable. The default value is true.
*/
@@ -491,10 +473,6 @@ var TextInput = React.createClass({
var autoCapitalize =
UIManager.AndroidTextInput.Constants.AutoCapitalizationType[this.props.autoCapitalize];
var textAlign = UIManager.AndroidTextInput.Constants.TextAlign[this.props.textAlign];
var textAlignVertical =
UIManager.AndroidTextInput.Constants.TextAlignVertical[this.props.textAlignVertical];
var children = this.props.children;
var childCount = 0;
ReactChildren.forEach(children, () => ++childCount);
@@ -512,8 +490,6 @@ var TextInput = React.createClass({
style={[this.props.style]}
autoCapitalize={autoCapitalize}
autoCorrect={this.props.autoCorrect}
textAlign={textAlign}
textAlignVertical={textAlignVertical}
keyboardType={this.props.keyboardType}
mostRecentEventCount={0}
multiline={this.props.multiline}
+6
View File
@@ -46,6 +46,12 @@ var TextStylePropTypes = Object.assign(Object.create(ViewStylePropTypes), {
textAlign: ReactPropTypes.oneOf(
['auto' /*default*/, 'left', 'right', 'center', 'justify']
),
/**
* @platform android
*/
textAlignVertical: ReactPropTypes.oneOf(
['auto' /*default*/, 'top', 'bottom', 'center']
),
/**
* @platform ios
*/
+2 -1
View File
@@ -25,7 +25,7 @@ var ReactNative = {
get Modal() { return require('Modal'); },
get Navigator() { return require('Navigator'); },
get NavigatorIOS() { return require('NavigatorIOS'); },
get PickerAndroid() { return require('PickerAndroid'); },
get Picker() { return require('Picker'); },
get PickerIOS() { return require('PickerIOS'); },
get ProgressBarAndroid() { return require('ProgressBarAndroid'); },
get ProgressViewIOS() { return require('ProgressViewIOS'); },
@@ -60,6 +60,7 @@ var ReactNative = {
get AlertIOS() { return require('AlertIOS'); },
get Animated() { return require('Animated'); },
get AppRegistry() { return require('AppRegistry'); },
get AppState() { return require('AppState'); },
get AppStateIOS() { return require('AppStateIOS'); },
get AsyncStorage() { return require('AsyncStorage'); },
get BackAndroid() { return require('BackAndroid'); },
+2 -1
View File
@@ -37,7 +37,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
Modal: require('Modal'),
Navigator: require('Navigator'),
NavigatorIOS: require('NavigatorIOS'),
PickerAndroid: require('PickerAndroid'),
Picker: require('Picker'),
PickerIOS: require('PickerIOS'),
ProgressBarAndroid: require('ProgressBarAndroid'),
ProgressViewIOS: require('ProgressViewIOS'),
@@ -72,6 +72,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
AlertIOS: require('AlertIOS'),
Animated: require('Animated'),
AppRegistry: require('AppRegistry'),
AppState: require('AppState'),
AppStateIOS: require('AppStateIOS'),
AsyncStorage: require('AsyncStorage'),
BackAndroid: require('BackAndroid'),
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "React"
s.version = "0.0.0-master"
s.version = "0.19.0"
s.summary = "Build high quality mobile apps using React."
s.description = <<-DESC
React Native apps are built using the React JS
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=0.12.0-SNAPSHOT
VERSION_NAME=0.19.1
GROUP=com.facebook.react
POM_NAME=ReactNative
@@ -265,17 +265,6 @@ public class DevSupportManagerImpl implements DevSupportManager {
handleReloadJS();
}
});
options.put(
mDevSettings.isHotModuleReplacementEnabled()
? mApplicationContext.getString(R.string.catalyst_hot_module_replacement_off)
: mApplicationContext.getString(R.string.catalyst_hot_module_replacement),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
mDevSettings.setHotModuleReplacementEnabled(!mDevSettings.isHotModuleReplacementEnabled());
handleReloadJS();
}
});
options.put(
mDevSettings.isReloadOnJSChangeEnabled()
? mApplicationContext.getString(R.string.catalyst_live_reload_off)
@@ -0,0 +1,76 @@
/**
* 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.
*/
package com.facebook.react.modules.appstate;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
public class AppStateModule extends ReactContextBaseJavaModule
implements LifecycleEventListener {
public static final String APP_STATE_ACTIVE = "active";
public static final String APP_STATE_BACKGROUND = "background";
private String mAppState = "uninitialized";
public AppStateModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "AppState";
}
@Override
public void initialize() {
getReactApplicationContext().addLifecycleEventListener(this);
}
@ReactMethod
public void getCurrentAppState(Callback success, Callback error) {
success.invoke(createAppStateEventMap());
}
@Override
public void onHostResume() {
mAppState = APP_STATE_ACTIVE;
sendAppStateChangeEvent();
}
@Override
public void onHostPause() {
mAppState = APP_STATE_BACKGROUND;
sendAppStateChangeEvent();
}
@Override
public void onHostDestroy() {
// do not set state to destroyed, do not send an event. By the current implementation, the
// catalyst instance is going to be immediately dropped, and all JS calls with it.
}
private WritableMap createAppStateEventMap() {
WritableMap appState = Arguments.createMap();
appState.putString("app_state", mAppState);
return appState;
}
private void sendAppStateChangeEvent() {
getReactApplicationContext().getJSModule(RCTDeviceEventEmitter.class)
.emit("appStateDidChange", createAppStateEventMap());
}
}
@@ -26,6 +26,7 @@ import com.facebook.react.modules.netinfo.NetInfoModule;
import com.facebook.react.modules.network.NetworkingModule;
import com.facebook.react.modules.storage.AsyncStorageModule;
import com.facebook.react.modules.toast.ToastModule;
import com.facebook.react.modules.appstate.AppStateModule;
import com.facebook.react.modules.websocket.WebSocketModule;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.views.art.ARTRenderableViewManager;
@@ -59,6 +60,7 @@ public class MainReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new AppStateModule(reactContext),
new AsyncStorageModule(reactContext),
new CameraRollManager(reactContext),
new ClipboardModule(reactContext),
@@ -68,8 +70,8 @@ public class MainReactPackage implements ReactPackage {
new LocationModule(reactContext),
new NetworkingModule(reactContext),
new NetInfoModule(reactContext),
new WebSocketModule(reactContext),
new ToastModule(reactContext));
new ToastModule(reactContext),
new WebSocketModule(reactContext));
}
@Override
@@ -91,17 +93,17 @@ public class MainReactPackage implements ReactPackage {
new ReactImageManager(),
new ReactProgressBarViewManager(),
new ReactRawTextManager(),
new RecyclerViewBackedScrollViewManager(),
new ReactScrollViewManager(),
new ReactSwitchManager(),
new ReactTextInlineImageViewManager(),
new ReactTextInputManager(),
new ReactTextViewManager(),
new ReactToolbarManager(),
new ReactViewManager(),
new ReactViewPagerManager(),
new ReactTextInlineImageViewManager(),
new ReactVirtualTextViewManager(),
new SwipeRefreshLayoutManager(),
new ReactWebViewManager());
new ReactWebViewManager(),
new RecyclerViewBackedScrollViewManager(),
new SwipeRefreshLayoutManager());
}
}
@@ -70,6 +70,7 @@ public class ViewProps {
public static final String ON = "on";
public static final String RESIZE_MODE = "resizeMode";
public static final String TEXT_ALIGN = "textAlign";
public static final String TEXT_ALIGN_VERTICAL = "textAlignVertical";
public static final String BORDER_WIDTH = "borderWidth";
public static final String BORDER_LEFT_WIDTH = "borderLeftWidth";
@@ -352,11 +352,11 @@ public class ReactImageView extends GenericDraweeView {
return resId > 0 ? context.getResources().getDrawable(resId) : null;
}
private static @Nullable Uri getResourceDrawableUri(Context context, @Nullable String name) {
private static Uri getResourceDrawableUri(Context context, @Nullable String name) {
int resId = getResourceDrawableId(context, name);
return resId > 0 ? new Uri.Builder()
.scheme(UriUtil.LOCAL_RESOURCE_SCHEME)
.path(String.valueOf(resId))
.build() : null;
.build() : Uri.EMPTY;
}
}
@@ -128,7 +128,7 @@ public abstract class ReactPickerManager extends SimpleViewManager<ReactPicker>
}
TextView textView = (TextView) convertView;
textView.setText(item.getString("text"));
textView.setText(item.getString("label"));
if (!isDropdown && mPrimaryTextColor != null) {
textView.setTextColor(mPrimaryTextColor);
} else if (item.hasKey("color") && !item.isNull("color")) {
@@ -28,6 +28,8 @@ import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.JSApplicationCausedNativeException;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
@@ -202,14 +204,34 @@ public class ReactTextInputManager extends
}
}
@ReactProp(name = "textAlign")
public void setTextAlign(ReactEditText view, int gravity) {
view.setGravityHorizontal(gravity);
@ReactProp(name = ViewProps.TEXT_ALIGN)
public void setTextAlign(ReactEditText view, @Nullable String textAlign) {
if (textAlign == null || "auto".equals(textAlign)) {
view.setGravityHorizontal(Gravity.NO_GRAVITY);
} else if ("left".equals(textAlign)) {
view.setGravityHorizontal(Gravity.LEFT);
} else if ("right".equals(textAlign)) {
view.setGravityHorizontal(Gravity.RIGHT);
} else if ("center".equals(textAlign)) {
view.setGravityHorizontal(Gravity.CENTER_HORIZONTAL);
} else {
throw new JSApplicationIllegalArgumentException("Invalid textAlign: " + textAlign);
}
}
@ReactProp(name = "textAlignVertical")
public void setTextAlignVertical(ReactEditText view, int gravity) {
view.setGravityVertical(gravity);
@ReactProp(name = ViewProps.TEXT_ALIGN_VERTICAL)
public void setTextAlignVertical(ReactEditText view, @Nullable String textAlignVertical) {
if (textAlignVertical == null || "auto".equals(textAlignVertical)) {
view.setGravityVertical(Gravity.NO_GRAVITY);
} else if ("top".equals(textAlignVertical)) {
view.setGravityVertical(Gravity.TOP);
} else if ("bottom".equals(textAlignVertical)) {
view.setGravityVertical(Gravity.BOTTOM);
} else if ("center".equals(textAlignVertical)) {
view.setGravityVertical(Gravity.CENTER_VERTICAL);
} else {
throw new JSApplicationIllegalArgumentException("Invalid textAlignVertical: " + textAlignVertical);
}
}
@ReactProp(name = "editable", defaultBoolean = true)
@@ -474,16 +496,6 @@ public class ReactTextInputManager extends
@Override
public @Nullable Map getExportedViewConstants() {
return MapBuilder.of(
"TextAlign",
MapBuilder.of(
"start", Gravity.START,
"center", Gravity.CENTER_HORIZONTAL,
"end", Gravity.END),
"TextAlignVertical",
MapBuilder.of(
"top", Gravity.TOP,
"center", Gravity.CENTER_VERTICAL,
"bottom", Gravity.BOTTOM),
"AutoCapitalizationType",
MapBuilder.of(
"none",
@@ -60,8 +60,7 @@ import com.android.build.OutputFile
apply from: "react.gradle"
/**
* Set this to true to create three separate APKs instead of one:
* - A universal APK that works on all devices
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
* - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB.
@@ -92,7 +91,7 @@ android {
splits {
abi {
enable enableSeparateBuildPerCPUArchitecture
universalApk true
universalApk false // Also generate an universal APK
reset()
include "armeabi-v7a", "x86"
}
@@ -121,5 +120,5 @@ android {
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:0.13.0"
compile "com.facebook.react:react-native:0.19.+"
}
@@ -525,7 +525,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "../node_modules/react-native/packager/react-native-xcode.sh";
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
showEnvVarsInLog = 1;
};
/* End PBXShellScriptBuildPhase section */
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "0.0.0-master",
"version": "0.19.0",
"description": "A framework for building native apps using React",
"license": "BSD-3-Clause",
"repository": {
+28 -6
View File
@@ -10,6 +10,13 @@
# This script is supposed to be invoked as part of Xcode build process
# and relies on envoronment variables (including PWD) set by Xcode
# There is no point in creating an offline package for simulator builds
# because the packager is supposed to be running during development anyways
if [[ "$PLATFORM_NAME" = "iphonesimulator" ]]; then
echo "Skipping bundling for Simulator platform"
exit 0;
fi
case "$CONFIGURATION" in
Debug)
DEV=true
@@ -23,12 +30,12 @@ case "$CONFIGURATION" in
;;
esac
# Path to react-native folder inside node_modules
REACT_NATIVE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# Xcode project file for React Native apps is located in ios/ subfolder
cd ..
set -x
DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH
# Define NVM_DIR and source the nvm.sh setup script
[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.nvm"
@@ -43,10 +50,25 @@ if [[ -x "$HOME/.nodenv/bin/nodenv" ]]; then
eval "$($HOME/.nodenv/bin/nodenv init -)"
fi
# npm global install path may be a non-standard location
PATH="$(npm prefix -g)/bin:$PATH"
[ -z "$NODE_BINARY" ] && export NODE_BINARY="node"
react-native bundle \
nodejs_not_found()
{
echo "error: Can't find '$NODE_BINARY' binary to build React Native bundle" >&2
echo "If you have non-standard nodejs installation, select your project in Xcode," >&2
echo "find 'Build Phases' - 'Bundle React Native code and images'" >&2
echo "and change NODE_BINARY to absolute path to your node executable" >&2
echo "(you can find it by invoking 'which node' in the terminal)" >&2
exit 2
}
type $NODE_BINARY >/dev/null 2>&1 || nodejs_not_found
# Print commands before executing them (useful for troubleshooting)
set -x
DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH
$NODE_BINARY $REACT_NATIVE_DIR/local-cli/cli.js bundle \
--entry-file index.ios.js \
--platform ios \
--dev $DEV \
-1
View File
@@ -47,7 +47,6 @@ for i in "${artifacts_list[@]}"; do
artifact_file="${artifacts_dir}/react-native-${RELEASE}.0${i}"
[ -e "${artifact_file}" ] || error "Couldn't find file: ${artifact_file}"
[ -e "${artifact_file}.asc" ] || error "Couldn't find file: ${artifact_file}.asc"
done
success "Generated artifacts for Maven"
+1
View File
@@ -225,6 +225,7 @@ var apis = [
'../Libraries/Animated/src/AnimatedImplementation.js',
'../Libraries/AppRegistry/AppRegistry.js',
'../Libraries/AppStateIOS/AppStateIOS.ios.js',
'../Libraries/AppState/AppState.js',
'../Libraries/Storage/AsyncStorage.js',
'../Libraries/Utilities/BackAndroid.android.js',
'../Libraries/CameraRoll/CameraRoll.js',