Skip to content

Commit 09739b5

Browse files
committed
Merge branch 'master' into flow-def
2 parents faf7640 + a0eddff commit 09739b5

File tree

343 files changed

+15819
-7676
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

343 files changed

+15819
-7676
lines changed

.buckconfig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,3 @@
44

55
[maven_repositories]
66
central = https://repo1.maven.org/maven2
7-
8-

.buckjavaargs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-Xmx512m -XX:+HeapDumpOnOutOfMemoryError

.eslintrc

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,19 @@
1919
"__DEV__": true,
2020
"__dirname": false,
2121
"__fbBatchedBridgeConfig": false,
22+
"alert": false,
2223
"cancelAnimationFrame": false,
2324
"clearImmediate": true,
2425
"clearInterval": false,
2526
"clearTimeout": false,
2627
"console": false,
2728
"document": false,
2829
"escape": false,
30+
"Event": false,
31+
"EventTarget": false,
2932
"exports": false,
3033
"fetch": false,
34+
"FormData": false,
3135
"global": false,
3236
"jest": false,
3337
"Map": true,
@@ -43,7 +47,29 @@
4347
"setTimeout": false,
4448
"window": false,
4549
"XMLHttpRequest": false,
46-
"pit": false
50+
"pit": false,
51+
52+
// Flow global types.
53+
"ReactComponent": false,
54+
"ReactClass": false,
55+
"ReactElement": false,
56+
"ReactPropsCheckType": false,
57+
"ReactPropsChainableTypeChecker": false,
58+
"ReactPropTypes": false,
59+
"SyntheticEvent": false,
60+
"$Either": false,
61+
"$All": false,
62+
"$Tuple": false,
63+
"$Supertype": false,
64+
"$Subtype": false,
65+
"$Shape": false,
66+
"$Diff": false,
67+
"$Keys": false,
68+
"$Enum": false,
69+
"$Exports": false,
70+
"$FlowIssue": false,
71+
"$FlowFixMe": false,
72+
"$FixMe": false
4773
},
4874

4975
"rules": {

.flowconfig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@ module.system=haste
5151
munge_underscores=true
5252

5353
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
54-
module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub'
54+
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\)$' -> 'RelativeImageStub'
5555

5656
suppress_type=$FlowIssue
5757
suppress_type=$FlowFixMe
5858
suppress_type=$FixMe
5959

60-
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-0]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
61-
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-0]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
60+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
61+
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
6262
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
6363

6464
[version]
65-
0.20.1
65+
0.21.0

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ project.xcworkspace
2626
/Examples/**/android/app/build/
2727
/ReactAndroid/build/
2828

29+
# Buck
30+
.buckd
31+
buck-out
32+
2933
# Android
3034
.idea
3135
.gradle

Examples/.eslintrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"rules": {
3+
"no-alert": 0
4+
}
5+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* The examples provided by Facebook are for non-commercial testing and
3+
* evaluation purposes only.
4+
*
5+
* Facebook reserves all rights not expressly granted.
6+
*
7+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9+
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
10+
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
11+
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
12+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13+
*/
14+
'use strict';
15+
16+
var React = require('react-native');
17+
var {
18+
DatePickerAndroid,
19+
StyleSheet,
20+
Text,
21+
TouchableWithoutFeedback,
22+
} = React;
23+
24+
var UIExplorerBlock = require('./UIExplorerBlock');
25+
var UIExplorerPage = require('./UIExplorerPage');
26+
27+
var DatePickerAndroidExample = React.createClass({
28+
29+
statics: {
30+
title: 'DatePickerAndroid',
31+
description: 'Standard Android date picker dialog',
32+
},
33+
34+
getInitialState() {
35+
return {
36+
presetDate: new Date(2020, 4, 5),
37+
allDate: new Date(2020, 4, 5),
38+
simpleText: 'pick a date',
39+
minText: 'pick a date, no earlier than today',
40+
maxText: 'pick a date, no later than today',
41+
presetText: 'pick a date, preset to 2020/5/5',
42+
allText: 'pick a date between 2020/5/1 and 2020/5/10',
43+
};
44+
},
45+
46+
async showPicker(stateKey, options) {
47+
try {
48+
var newState = {};
49+
const {action, year, month, day} = await DatePickerAndroid.open(options);
50+
if (action === DatePickerAndroid.dismissedAction) {
51+
newState[stateKey + 'Text'] = 'dismissed';
52+
} else {
53+
var date = new Date(year, month, day);
54+
newState[stateKey + 'Text'] = date.toLocaleDateString();
55+
newState[stateKey + 'Date'] = date;
56+
}
57+
this.setState(newState);
58+
} catch ({code, message}) {
59+
console.warn(`Error in example '${stateKey}': `, message);
60+
}
61+
},
62+
63+
render() {
64+
return (
65+
<UIExplorerPage title="DatePickerAndroid">
66+
<UIExplorerBlock title="Simple date picker">
67+
<TouchableWithoutFeedback
68+
onPress={this.showPicker.bind(this, 'simple', {date: this.state.simpleDate})}>
69+
<Text style={styles.text}>{this.state.simpleText}</Text>
70+
</TouchableWithoutFeedback>
71+
</UIExplorerBlock>
72+
<UIExplorerBlock title="Date picker with pre-set date">
73+
<TouchableWithoutFeedback
74+
onPress={this.showPicker.bind(this, 'preset', {date: this.state.presetDate})}>
75+
<Text style={styles.text}>{this.state.presetText}</Text>
76+
</TouchableWithoutFeedback>
77+
</UIExplorerBlock>
78+
<UIExplorerBlock title="Date picker with minDate">
79+
<TouchableWithoutFeedback
80+
onPress={this.showPicker.bind(this, 'min', {
81+
date: this.state.minDate,
82+
minDate: new Date(),
83+
})}>
84+
<Text style={styles.text}>{this.state.minText}</Text>
85+
</TouchableWithoutFeedback>
86+
</UIExplorerBlock>
87+
<UIExplorerBlock title="Date picker with maxDate">
88+
<TouchableWithoutFeedback
89+
onPress={this.showPicker.bind(this, 'max', {
90+
date: this.state.maxDate,
91+
maxDate: new Date(),
92+
})}>
93+
<Text style={styles.text}>{this.state.maxText}</Text>
94+
</TouchableWithoutFeedback>
95+
</UIExplorerBlock>
96+
<UIExplorerBlock title="Date picker with all options">
97+
<TouchableWithoutFeedback
98+
onPress={this.showPicker.bind(this, 'all', {
99+
date: this.state.allDate,
100+
minDate: new Date(2020, 4, 1),
101+
maxDate: new Date(2020, 4, 10),
102+
})}>
103+
<Text style={styles.text}>{this.state.allText}</Text>
104+
</TouchableWithoutFeedback>
105+
</UIExplorerBlock>
106+
</UIExplorerPage>
107+
);
108+
},
109+
});
110+
111+
var styles = StyleSheet.create({
112+
text: {
113+
color: 'black',
114+
},
115+
});
116+
117+
module.exports = DatePickerAndroidExample;

Examples/UIExplorer/ExampleTypes.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
export type Example = {
2020
title: string,
21-
/* $FlowFixMe(>=0.16.0) */
2221
render: () => ?ReactElement<any, any, any>,
2322
description?: string,
2423
platform?: string;

Examples/UIExplorer/ImageEditingExample.js

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ var {
2222
Image,
2323
ImageEditor,
2424
NativeModules,
25+
Platform,
2526
ScrollView,
2627
StyleSheet,
2728
Text,
@@ -30,8 +31,6 @@ var {
3031
View,
3132
} = React;
3233

33-
var RCTScrollViewConsts = UIManager.RCTScrollView.Constants;
34-
3534
var PAGE_SIZE = 20;
3635

3736
type ImageOffset = {
@@ -67,22 +66,21 @@ class SquareImageCropper extends React.Component {
6766
this._fetchRandomPhoto();
6867
}
6968

70-
_fetchRandomPhoto() {
71-
CameraRoll.getPhotos(
72-
{first: PAGE_SIZE},
73-
(data) => {
74-
if (!this._isMounted) {
75-
return;
76-
}
77-
var edges = data.edges;
78-
var edge = edges[Math.floor(Math.random() * edges.length)];
79-
var randomPhoto = edge && edge.node && edge.node.image;
80-
if (randomPhoto) {
81-
this.setState({randomPhoto});
82-
}
83-
},
84-
(error) => undefined
85-
);
69+
async _fetchRandomPhoto() {
70+
try {
71+
const data = await CameraRoll.getPhotos({first: PAGE_SIZE});
72+
if (!this._isMounted) {
73+
return;
74+
}
75+
var edges = data.edges;
76+
var edge = edges[Math.floor(Math.random() * edges.length)];
77+
var randomPhoto = edge && edge.node && edge.node.image;
78+
if (randomPhoto) {
79+
this.setState({randomPhoto});
80+
}
81+
} catch (error) {
82+
console.warn("Can't get a photo from camera roll", error);
83+
}
8684
}
8785

8886
componentWillUnmount() {
@@ -190,29 +188,49 @@ class SquareImageCropper extends React.Component {
190188
}
191189

192190
class ImageCropper extends React.Component {
193-
_scaledImageSize: ImageSize;
194191
_contentOffset: ImageOffset;
192+
_maximumZoomScale: number;
193+
_minimumZoomScale: number;
194+
_scaledImageSize: ImageSize;
195+
_horizontal: boolean;
195196

196197
componentWillMount() {
197198
// Scale an image to the minimum size that is large enough to completely
198199
// fill the crop box.
199200
var widthRatio = this.props.image.width / this.props.size.width;
200201
var heightRatio = this.props.image.height / this.props.size.height;
201-
if (widthRatio < heightRatio) {
202+
this._horizontal = widthRatio > heightRatio;
203+
if (this._horizontal) {
202204
this._scaledImageSize = {
203-
width: this.props.size.width,
204-
height: this.props.image.height / widthRatio,
205+
width: this.props.image.width / heightRatio,
206+
height: this.props.size.height,
205207
};
206208
} else {
207209
this._scaledImageSize = {
208-
width: this.props.image.width / heightRatio,
209-
height: this.props.size.height,
210+
width: this.props.size.width,
211+
height: this.props.image.height / widthRatio,
210212
};
213+
if (Platform.OS === 'android') {
214+
// hack to work around Android ScrollView a) not supporting zoom, and
215+
// b) not supporting vertical scrolling when nested inside another
216+
// vertical ScrollView (which it is, when displayed inside UIExplorer)
217+
this._scaledImageSize.width *= 2;
218+
this._scaledImageSize.height *= 2;
219+
this._horizontal = true;
220+
}
211221
}
212222
this._contentOffset = {
213223
x: (this._scaledImageSize.width - this.props.size.width) / 2,
214224
y: (this._scaledImageSize.height - this.props.size.height) / 2,
215225
};
226+
this._maximumZoomScale = Math.min(
227+
this.props.image.width / this._scaledImageSize.width,
228+
this.props.image.height / this._scaledImageSize.height
229+
);
230+
this._minimumZoomScale = Math.max(
231+
this.props.size.width / this._scaledImageSize.width,
232+
this.props.size.height / this._scaledImageSize.height
233+
);
216234
this._updateTransformData(
217235
this._contentOffset,
218236
this._scaledImageSize,
@@ -248,19 +266,15 @@ class ImageCropper extends React.Component {
248266
}
249267

250268
render() {
251-
var decelerationRate =
252-
RCTScrollViewConsts && RCTScrollViewConsts.DecelerationRate ?
253-
RCTScrollViewConsts.DecelerationRate.Fast :
254-
0;
255-
256269
return (
257270
<ScrollView
258271
alwaysBounceVertical={true}
259272
automaticallyAdjustContentInsets={false}
260273
contentOffset={this._contentOffset}
261-
decelerationRate={decelerationRate}
262-
horizontal={true}
263-
maximumZoomScale={3.0}
274+
decelerationRate="fast"
275+
horizontal={this._horizontal}
276+
maximumZoomScale={this._maximumZoomScale}
277+
minimumZoomScale={this._minimumZoomScale}
264278
onMomentumScrollEnd={this._onScroll.bind(this)}
265279
onScrollEndDrag={this._onScroll.bind(this)}
266280
showsHorizontalScrollIndicator={false}

0 commit comments

Comments
 (0)