-
Notifications
You must be signed in to change notification settings - Fork 24.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[createReactClass] Remove createReactClass from CameraRollView #21619
Changes from 3 commits
275858c
bad2a02
c84b563
54ca1b9
18dcaa1
77acac9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,34 +79,36 @@ const getPhotosParamChecker = createStrictShapeTypeChecker({ | |
mimeTypes: PropTypes.arrayOf(PropTypes.string), | ||
}); | ||
|
||
type GetPhotosReturn = Promise<{ | ||
edges: Array<{ | ||
node: { | ||
type: string, | ||
group_name: string, | ||
image: { | ||
uri: string, | ||
height: number, | ||
width: number, | ||
isStored?: boolean, | ||
playableDuration: number, | ||
}, | ||
timestamp: number, | ||
location?: { | ||
latitude?: number, | ||
longitude?: number, | ||
altitude?: number, | ||
heading?: number, | ||
speed?: number, | ||
}, | ||
export type GetPhotosEdge = { | ||
node: { | ||
type: string, | ||
group_name: string, | ||
image: { | ||
uri: string, | ||
height: number, | ||
width: number, | ||
isStored?: boolean, | ||
playableDuration: number, | ||
}, | ||
}>, | ||
timestamp: number, | ||
location?: { | ||
latitude?: number, | ||
longitude?: number, | ||
altitude?: number, | ||
heading?: number, | ||
speed?: number, | ||
}, | ||
}, | ||
}; | ||
|
||
export type GetPhotosReturn = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think about renaming this to: export type PhotoIdentifierObjectsPage = { Or: export type PhotoIdentifiersPage = { |
||
edges: Array<GetPhotosEdge>, | ||
page_info: { | ||
has_next_page: boolean, | ||
start_cursor?: string, | ||
end_cursor?: string, | ||
}, | ||
}>; | ||
}; | ||
|
||
/** | ||
* Shape of the return value of the `getPhotos` function. | ||
|
@@ -204,7 +206,7 @@ class CameraRoll { | |
* | ||
* See https://facebook.github.io/react-native/docs/cameraroll.html#getphotos | ||
*/ | ||
static getPhotos(params: GetPhotosParams): GetPhotosReturn { | ||
static getPhotos(params: GetPhotosParams): Promise<GetPhotosReturn> { | ||
if (__DEV__) { | ||
checkPropTypes( | ||
{params: getPhotosParamChecker}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,11 +10,9 @@ | |
|
||
'use strict'; | ||
|
||
var React = require('react'); | ||
var createReactClass = require('create-react-class'); | ||
const PropTypes = require('prop-types'); | ||
var ReactNative = require('react-native'); | ||
var { | ||
const React = require('react'); | ||
const ReactNative = require('react-native'); | ||
const { | ||
ActivityIndicator, | ||
Alert, | ||
CameraRoll, | ||
|
@@ -25,105 +23,123 @@ var { | |
StyleSheet, | ||
View, | ||
} = ReactNative; | ||
const ListViewDataSource = require('ListViewDataSource'); | ||
|
||
var groupByEveryN = require('groupByEveryN'); | ||
var logError = require('logError'); | ||
const groupByEveryN = require('groupByEveryN'); | ||
const logError = require('logError'); | ||
|
||
var propTypes = { | ||
import type {GetPhotosEdge, GetPhotosReturn} from 'CameraRoll'; | ||
|
||
const rowHasChanged = function(r1: Array<Image>, r2: Array<Image>): boolean { | ||
exced marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (r1.length !== r2.length) { | ||
return true; | ||
} | ||
|
||
for (var i = 0; i < r1.length; i++) { | ||
if (r1[i] !== r2[i]) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
}; | ||
|
||
type Props = $ReadOnly<{| | ||
/** | ||
* The group where the photos will be fetched from. Possible | ||
* values are 'Album', 'All', 'Event', 'Faces', 'Library', 'PhotoStream' | ||
* and SavedPhotos. | ||
*/ | ||
groupTypes: PropTypes.oneOf([ | ||
'Album', | ||
'All', | ||
'Event', | ||
'Faces', | ||
'Library', | ||
'PhotoStream', | ||
'SavedPhotos', | ||
]), | ||
groupTypes: | ||
| 'Album' | ||
| 'All' | ||
| 'Event' | ||
| 'Faces' | ||
| 'Library' | ||
| 'PhotoStream' | ||
| 'SavedPhotos', | ||
|
||
/** | ||
* Number of images that will be fetched in one page. | ||
*/ | ||
batchSize: PropTypes.number, | ||
batchSize: number, | ||
|
||
/** | ||
* A function that takes a single image as a parameter and renders it. | ||
*/ | ||
renderImage: PropTypes.func, | ||
renderImage: GetPhotosEdge => React.Node, | ||
|
||
/** | ||
* imagesPerRow: Number of images to be shown in each row. | ||
*/ | ||
imagesPerRow: PropTypes.number, | ||
|
||
imagesPerRow: number, | ||
|
||
/** | ||
* The asset type, one of 'Photos', 'Videos' or 'All' | ||
*/ | ||
assetType: PropTypes.oneOf(['Photos', 'Videos', 'All']), | ||
}; | ||
|
||
var CameraRollView = createReactClass({ | ||
displayName: 'CameraRollView', | ||
propTypes: propTypes, | ||
|
||
getDefaultProps: function(): Object { | ||
assetType: 'Photos' | 'Videos' | 'All', | ||
|}>; | ||
|
||
type State = {| | ||
assets: Array<GetPhotosEdge>, | ||
lastCursor: ?string, | ||
noMore: boolean, | ||
loadingMore: boolean, | ||
dataSource: ListViewDataSource, | ||
|}; | ||
|
||
class CameraRollView extends React.Component<Props, State> { | ||
static defaultProps = { | ||
groupTypes: 'SavedPhotos', | ||
batchSize: 5, | ||
imagesPerRow: 1, | ||
assetType: 'Photos', | ||
renderImage: function(asset: GetPhotosEdge) { | ||
const imageSize = 150; | ||
const imageStyle = [styles.image, {width: imageSize, height: imageSize}]; | ||
return <Image source={asset.node.image} style={imageStyle} />; | ||
}, | ||
}; | ||
|
||
state = this.getInitialState(); | ||
|
||
getInitialState() { | ||
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, | ||
assets: [], | ||
lastCursor: null, | ||
noMore: false, | ||
loadingMore: false, | ||
dataSource: ds, | ||
dataSource: new ListView.DataSource({rowHasChanged: rowHasChanged}), | ||
}; | ||
}, | ||
} | ||
|
||
/** | ||
* 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}); | ||
rendererChanged() { | ||
const ds = new ListView.DataSource({rowHasChanged: rowHasChanged}); | ||
this.state.dataSource = ds.cloneWithRows( | ||
// $FlowFixMe(>=0.41.0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the general rule of thumb should be: If you see a Pretty sure this is suppressing some valid flow errors. For example, |
||
groupByEveryN(this.state.assets, this.props.imagesPerRow), | ||
); | ||
}, | ||
} | ||
|
||
componentDidMount: function() { | ||
componentDidMount() { | ||
this.fetch(); | ||
}, | ||
} | ||
|
||
/* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an error | ||
* found when Flow v0.68 was deployed. To see the error delete this comment | ||
* and run Flow. */ | ||
UNSAFE_componentWillReceiveProps: function(nextProps: {groupTypes?: string}) { | ||
UNSAFE_componentWillReceiveProps(nextProps: {groupTypes?: string}) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure how we can remove it properly though. This is the Flow error I get : |
||
if (this.props.groupTypes !== nextProps.groupTypes) { | ||
this.fetch(true); | ||
} | ||
}, | ||
} | ||
|
||
_fetch: async function(clear?: boolean) { | ||
async _fetch(clear?: boolean) { | ||
if (clear) { | ||
this.setState(this.getInitialState(), this.fetch); | ||
return; | ||
|
@@ -162,21 +178,21 @@ var CameraRollView = createReactClass({ | |
} catch (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) { | ||
fetch = (clear?: boolean) => { | ||
if (!this.state.loadingMore) { | ||
this.setState({loadingMore: true}, () => { | ||
this._fetch(clear); | ||
}); | ||
} | ||
}, | ||
}; | ||
|
||
render: function() { | ||
render() { | ||
return ( | ||
<ListView | ||
renderRow={this._renderRow} | ||
|
@@ -187,36 +203,22 @@ var CameraRollView = createReactClass({ | |
enableEmptySections | ||
/> | ||
); | ||
}, | ||
} | ||
|
||
_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() { | ||
_renderFooterSpinner = () => { | ||
if (!this.state.noMore) { | ||
return <ActivityIndicator />; | ||
} | ||
return null; | ||
}, | ||
}; | ||
|
||
// rowData is an array of images | ||
_renderRow: function( | ||
rowData: Array<Image>, | ||
_renderRow = ( | ||
rowData: Array<GetPhotosEdge>, | ||
sectionID: string, | ||
rowID: string, | ||
) { | ||
var images = rowData.map(image => { | ||
) => { | ||
const images = rowData.map(image => { | ||
if (image === null) { | ||
return null; | ||
} | ||
|
@@ -225,11 +227,11 @@ var CameraRollView = createReactClass({ | |
}); | ||
exced marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return <View style={styles.row}>{images}</View>; | ||
}, | ||
}; | ||
|
||
_appendAssets: function(data: Object) { | ||
var assets = data.edges; | ||
var newState: Object = {loadingMore: false}; | ||
_appendAssets(data: GetPhotosReturn) { | ||
const assets = data.edges; | ||
const newState: $Shape<State> = {loadingMore: false}; | ||
|
||
if (!data.page_info.has_next_page) { | ||
newState.noMore = true; | ||
|
@@ -245,16 +247,16 @@ var CameraRollView = createReactClass({ | |
} | ||
exced marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
this.setState(newState); | ||
}, | ||
} | ||
|
||
_onEndReached: function() { | ||
_onEndReached = () => { | ||
if (!this.state.noMore) { | ||
this.fetch(); | ||
} | ||
}, | ||
}); | ||
}; | ||
} | ||
|
||
var styles = StyleSheet.create({ | ||
const styles = StyleSheet.create({ | ||
row: { | ||
flexDirection: 'row', | ||
flex: 1, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about renaming this to:
Or: