Files
react-native-camera-roll/example/js/GetPhotosPerformanceExample.tsx
T
Bartol KaruzaandHarry Yu 4da8310892 feat: Added include parameter to getPhotos to let users tradeoff performance by omitting metadata (#178) (#200)
BREAKING CHANGE: meta data is no longer added as default. This applies to `fileName`, `fileSize` and `location`. If you need this metadata use the new `include` parameter. Adding this metadata will slow down the `getPhotos` function, so consider only retrieving this meta data for smaller sets of images as needed, instead of for all images.

* Created getPhotosFast function, fixed inconsistent getPhotos toDate logic

* Fixed wrong param name, added better typechecking

* Added example, renamed allowEmptyFilenames to skipGettingFilenames

* Removed `after` from getPhotosFast docs

* Redid implementation based on a new `include` param

* Updated API to use include parameter

* Fixed flow checking by converting index.ts to Typescript

* Unformatted README.md

* Unformatted README.md

* Unformatted README.md

* Added .prettierignore and ignored README.md for now

* Made example/index.js not checked by Flow

* Updated README.md to include notes in the outputs too

* Made inclusion of fields consistent, addressed other feedback

* Renamed GetPhotosFastParams back to GetPhotosParams

* Updated documentation to reflect nullable types

* Updated typings and documentation for fromTime, toTime

* Updated to fix `hasNextPage` being incorrectly false in some cases

Co-authored-by: Harry Yu <hy.harry.yu@gmail.com>
2020-06-16 13:20:51 +03:00

176 lines
4.2 KiB
TypeScript

import * as React from 'react';
import {
StyleSheet,
View,
Button,
Text,
Switch,
TextInput,
Keyboard,
} from 'react-native';
// @ts-ignore: CameraRollExample has no typings in same folder
import CameraRoll from '../../js/CameraRoll';
interface State {
fetchingPhotos: boolean;
timeTakenMillis: number | null;
output: CameraRoll.PhotoIdentifiersPage | null;
include: CameraRoll.Include[];
/**
* `first` argument passed into `getPhotos`, but as a string. Validate it
* with `this.first()` before using.
*/
firstStr: string;
/** `after` passed into `getPhotos`. Not passed if empty */
after: string;
}
const includeValues: CameraRoll.Include[] = [
'filename',
'fileSize',
'location',
];
/**
* Example for testing performance differences between `getPhotos` and
* `getPhotosFast`
*/
export default class GetPhotosPerformanceExample extends React.PureComponent<
{},
State
> {
state: State = {
fetchingPhotos: false,
timeTakenMillis: null,
output: null,
include: [],
firstStr: '1000',
after: '',
};
first = () => {
const first = parseInt(this.state.firstStr, 10);
if (first < 0 || !Number.isInteger(first)) {
return null;
}
return first;
};
startFetchingPhotos = async () => {
const {include} = this.state;
const first = this.first();
if (first === null) {
return;
}
this.setState({fetchingPhotos: true});
Keyboard.dismiss();
const params: CameraRoll.GetPhotosParams = {first, include};
const startTime = Date.now();
const output: CameraRoll.PhotoIdentifiersPage = await CameraRoll.getPhotos(
params,
);
const endTime = Date.now();
this.setState({
output,
timeTakenMillis: endTime - startTime,
fetchingPhotos: false,
});
};
handleIncludeChange = (
includeValue: CameraRoll.Include,
changedTo: boolean,
) => {
if (changedTo === false) {
const include = this.state.include.filter(
value => value !== includeValue,
);
this.setState({include});
} else {
const include = [...this.state.include, includeValue];
this.setState({include});
}
};
render() {
const {
fetchingPhotos,
timeTakenMillis,
output,
include,
firstStr,
} = this.state;
const first = this.first();
return (
<View style={styles.container}>
{includeValues.map(includeValue => (
<View key={includeValue} style={styles.inputRow}>
<Text>{includeValue}</Text>
<Switch
value={include.includes(includeValue)}
onValueChange={(changedTo: boolean) =>
this.handleIncludeChange(includeValue, changedTo)
}
/>
</View>
))}
<View style={styles.inputRow}>
<Text>
first
{first === null && (
<Text style={styles.error}> (enter a positive number)</Text>
)}
</Text>
<TextInput
value={firstStr}
onChangeText={(text: string) => this.setState({firstStr: text})}
style={[styles.textInput, first === null && styles.textInputError]}
/>
</View>
<Button
disabled={fetchingPhotos}
title={`Run getPhotos on ${first} photos`}
onPress={this.startFetchingPhotos}
/>
{timeTakenMillis !== null && (
<Text>Time taken: {timeTakenMillis} ms</Text>
)}
<View>
<Text>Output</Text>
</View>
<TextInput
value={JSON.stringify(output, null, 2)}
multiline
style={styles.outputBox}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {flex: 1, padding: 8},
inputRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: 2,
},
textInput: {
borderColor: '#ccc',
borderWidth: 1,
paddingVertical: 4,
paddingHorizontal: 8,
width: 150,
},
error: {color: '#f00'},
textInputError: {borderColor: '#f00'},
outputBox: {
flex: 1,
borderColor: '#ccc',
borderWidth: 1,
padding: 8,
},
});