mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 09:35:48 +00:00
4c245160bd
Summary: This replaces ActivityIndicatorIOS and indeterminate ProgressBar that were deprecated recently with ActivityIndicator across the codebase and examples and a few other cleanups. This also make a small tweak to ActivityIndicator so it uses the Android theme color instead of gray when no color is specified. Use Slider instead of SliderIOS in CameraRoll example. Remove the line about unifying ActivityIndicator and ProgressBar. **Test plan** Tested the affected components in UIExplorer on iOS and Android, tested the changes made in Movies example on iOS and Android. Closes https://github.com/facebook/react-native/pull/8082 Differential Revision: D3429770 fbshipit-source-id: 3b2e1196a8b9fe00d47a7aa1bbc079b094796421
262 lines
6.0 KiB
JavaScript
262 lines
6.0 KiB
JavaScript
/**
|
|
* 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 CameraRollView
|
|
* @flow
|
|
*/
|
|
'use strict';
|
|
|
|
var React = require('react');
|
|
var ReactNative = require('react-native');
|
|
var {
|
|
ActivityIndicator,
|
|
CameraRoll,
|
|
Image,
|
|
ListView,
|
|
Platform,
|
|
StyleSheet,
|
|
View,
|
|
} = ReactNative;
|
|
|
|
var groupByEveryN = require('groupByEveryN');
|
|
var logError = require('logError');
|
|
|
|
var propTypes = {
|
|
/**
|
|
* The group where the photos will be fetched from. Possible
|
|
* values are 'Album', 'All', 'Event', 'Faces', 'Library', 'PhotoStream'
|
|
* and SavedPhotos.
|
|
*/
|
|
groupTypes: React.PropTypes.oneOf([
|
|
'Album',
|
|
'All',
|
|
'Event',
|
|
'Faces',
|
|
'Library',
|
|
'PhotoStream',
|
|
'SavedPhotos',
|
|
]),
|
|
|
|
/**
|
|
* Number of images that will be fetched in one page.
|
|
*/
|
|
batchSize: React.PropTypes.number,
|
|
|
|
/**
|
|
* A function that takes a single image as a parameter and renders it.
|
|
*/
|
|
renderImage: React.PropTypes.func,
|
|
|
|
/**
|
|
* imagesPerRow: Number of images to be shown in each row.
|
|
*/
|
|
imagesPerRow: React.PropTypes.number,
|
|
|
|
/**
|
|
* The asset type, one of 'Photos', 'Videos' or 'All'
|
|
*/
|
|
assetType: React.PropTypes.oneOf([
|
|
'Photos',
|
|
'Videos',
|
|
'All',
|
|
]),
|
|
|
|
};
|
|
|
|
var CameraRollView = React.createClass({
|
|
propTypes: propTypes,
|
|
|
|
getDefaultProps: function(): Object {
|
|
return {
|
|
groupTypes: 'SavedPhotos',
|
|
batchSize: 5,
|
|
imagesPerRow: 1,
|
|
assetType: 'Photos',
|
|
renderImage: function(asset) {
|
|
var imageSize = 150;
|
|
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
|
|
return (
|
|
<Image
|
|
source={asset.node.image}
|
|
style={imageStyle}
|
|
/>
|
|
);
|
|
},
|
|
};
|
|
},
|
|
|
|
getInitialState: function() {
|
|
var ds = new ListView.DataSource({rowHasChanged: this._rowHasChanged});
|
|
|
|
return {
|
|
assets: ([]: Array<Image>),
|
|
groupTypes: this.props.groupTypes,
|
|
lastCursor: (null : ?string),
|
|
assetType: this.props.assetType,
|
|
noMore: false,
|
|
loadingMore: false,
|
|
dataSource: ds,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* This should be called when the image renderer is changed to tell the
|
|
* component to re-render its assets.
|
|
*/
|
|
rendererChanged: function() {
|
|
var ds = new ListView.DataSource({rowHasChanged: this._rowHasChanged});
|
|
this.state.dataSource = ds.cloneWithRows(
|
|
groupByEveryN(this.state.assets, this.props.imagesPerRow)
|
|
);
|
|
},
|
|
|
|
componentDidMount: function() {
|
|
this.fetch();
|
|
},
|
|
|
|
componentWillReceiveProps: function(nextProps: {groupTypes?: string}) {
|
|
if (this.props.groupTypes !== nextProps.groupTypes) {
|
|
this.fetch(true);
|
|
}
|
|
},
|
|
|
|
_fetch: function(clear?: boolean) {
|
|
if (clear) {
|
|
this.setState(this.getInitialState(), this.fetch);
|
|
return;
|
|
}
|
|
|
|
var fetchParams: Object = {
|
|
first: this.props.batchSize,
|
|
groupTypes: this.props.groupTypes,
|
|
assetType: this.props.assetType,
|
|
};
|
|
if (Platform.OS === 'android') {
|
|
// not supported in android
|
|
delete fetchParams.groupTypes;
|
|
}
|
|
if (this.state.lastCursor) {
|
|
fetchParams.after = this.state.lastCursor;
|
|
}
|
|
|
|
CameraRoll.getPhotos(fetchParams)
|
|
.then((data) => this._appendAssets(data), (e) => logError(e));
|
|
},
|
|
|
|
/**
|
|
* Fetches more images from the camera roll. If clear is set to true, it will
|
|
* set the component to its initial state and re-fetch the images.
|
|
*/
|
|
fetch: function(clear?: boolean) {
|
|
if (!this.state.loadingMore) {
|
|
this.setState({loadingMore: true}, () => { this._fetch(clear); });
|
|
}
|
|
},
|
|
|
|
render: function() {
|
|
return (
|
|
<ListView
|
|
renderRow={this._renderRow}
|
|
renderFooter={this._renderFooterSpinner}
|
|
onEndReached={this._onEndReached}
|
|
style={styles.container}
|
|
dataSource={this.state.dataSource}
|
|
/>
|
|
);
|
|
},
|
|
|
|
_rowHasChanged: function(r1: Array<Image>, r2: Array<Image>): boolean {
|
|
if (r1.length !== r2.length) {
|
|
return true;
|
|
}
|
|
|
|
for (var i = 0; i < r1.length; i++) {
|
|
if (r1[i] !== r2[i]) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
_renderFooterSpinner: function() {
|
|
if (!this.state.noMore) {
|
|
return <ActivityIndicator style={styles.spinner} />;
|
|
}
|
|
return null;
|
|
},
|
|
|
|
// rowData is an array of images
|
|
_renderRow: function(rowData: Array<Image>, sectionID: string, rowID: string) {
|
|
var images = rowData.map((image) => {
|
|
if (image === null) {
|
|
return null;
|
|
}
|
|
return this.props.renderImage(image);
|
|
});
|
|
|
|
return (
|
|
<View style={styles.row}>
|
|
{images}
|
|
</View>
|
|
);
|
|
},
|
|
|
|
_appendAssets: function(data: Object) {
|
|
var assets = data.edges;
|
|
var newState: Object = { loadingMore: false };
|
|
|
|
if (!data.page_info.has_next_page) {
|
|
newState.noMore = true;
|
|
}
|
|
|
|
if (assets.length > 0) {
|
|
newState.lastCursor = data.page_info.end_cursor;
|
|
newState.assets = this.state.assets.concat(assets);
|
|
newState.dataSource = this.state.dataSource.cloneWithRows(
|
|
groupByEveryN(newState.assets, this.props.imagesPerRow)
|
|
);
|
|
}
|
|
|
|
this.setState(newState);
|
|
},
|
|
|
|
_onEndReached: function() {
|
|
if (!this.state.noMore) {
|
|
this.fetch();
|
|
}
|
|
},
|
|
});
|
|
|
|
var styles = StyleSheet.create({
|
|
row: {
|
|
flexDirection: 'row',
|
|
flex: 1,
|
|
},
|
|
url: {
|
|
fontSize: 9,
|
|
marginBottom: 14,
|
|
},
|
|
image: {
|
|
margin: 4,
|
|
},
|
|
info: {
|
|
flex: 1,
|
|
},
|
|
container: {
|
|
flex: 1,
|
|
},
|
|
});
|
|
|
|
module.exports = CameraRollView;
|