@around25/react-native-gallery-media-picker
Version:
A react native component that will get all the media files (images and video) from device gallery and allow to select items
213 lines (181 loc) • 5.45 kB
JavaScript
import React, { Component } from 'react';
import { Platform, View } from 'react-native';
import CameraRoll from "@react-native-community/cameraroll";
import _ from 'lodash'
import AlbumsList from '../src/components/AlbumsList';
import MediaList from '../src/components/MediaList';
import styles from './styles';
class GalleryMediaPicker extends Component {
constructor( props ) {
super( props );
this.state = {
images: [],
selected: this.props.selected,
lastCursor: null,
fetching: true,
loadingMore: false,
noMoreFiles: false,
batchSize: 1,
dataSource: [],
groupTypes: 'SavedPhotos',
maximumSelectedFiles: 15,
itemsPerRow: 3,
imageMargin: 5,
activityIndicatorSize: 'small',
activityIndicatorColor: '#000000',
selectSingleItem: false,
assetType: 'Photos',
backgroundColor: 'white',
emptyGalleryText: 'There are no photos or videos',
albums: [],
albumSelected: ''
};
}
componentWillMount() {
this.getFiles();
}
componentWillReceiveProps( nextProps ) {
this.setState( { selected: nextProps.selected } );
}
/**
* @description Get files from camera roll
*/
getFiles () {
if (!this.state.loadingMore) {
this.setState({loadingMore: true}, () => {
this.getCameraRollFiles();
});
}
}
/**
* @description Fetch camera roll files
*/
getCameraRollFiles() {
let { groupTypes, assetType, firstLimit } = this.props;
let fetchParams = {
first: firstLimit !== undefined ? firstLimit : 1000,
groupTypes: groupTypes,
assetType: assetType,
};
if (Platform.OS === "android") {
delete fetchParams.groupTypes;
}
if (this.state.lastCursor) {
fetchParams.after = this.state.lastCursor;
}
CameraRoll.getPhotos(fetchParams)
.then((data) => this.appendFiles(data), (e) => console.error(e));
}
/**
* @description This function is sorting files and put them on the state
* @param data
*/
appendFiles(data) {
let assets = data.edges;
this.extract(assets);
let newState = {
loadingMore: false,
fetching: false,
};
if (!data.page_info.has_next_page) {
newState.noMoreFiles = true;
}
if (assets.length > 0) {
newState.lastCursor = data.page_info.end_cursor;
newState.images = this.state.images.concat(assets);
}
this.setState(newState);
}
/**
* @description Extracts images from array
*/
extract (items) {
let res = items.map(item => item.node);
this.sort(res);
}
/**
* @description Sorts images based on album
*/
sort (items) {
let albums = [];
grouped = Object.values(_.groupBy(items, (item) => item.group_name));
grouped.map(list => albums.push({albumName: list[0].group_name, images: list}));
this.setState({
albums
});
}
selectAlbum (albumName) {
this.setState({
albumSelected: albumName
});
}
deselectAlbum () {
this.setState({
albumSelected: ''
});
}
getAlbumImages (selectedAlbumName) {
const selectedAlbum = this.state.albums.filter((album) => album.albumName === selectedAlbumName).pop();
return selectedAlbum.images;
}
/**
* @description Render background color for the container
* @return {string}
*/
renderBackgroundColor(){
return this.props.backgroundColor !== undefined ? this.props.backgroundColor : this.state.backgroundColor;
}
/**
* @description Render default loader style
* @return {{color: string, size: string}}
*/
renderLoaderStyle(){
let props = this.props;
return {
color: props.activityIndicatorColor !== undefined ? props.activityIndicatorColor : this.state.activityIndicatorColor,
size: props.activityIndicatorSize !== undefined ? props.activityIndicatorSize : this.state.activityIndicatorSize
}
}
/**
* @description On list end reached , load more files if there are any
*/
onEndReached() {
if (!this.state.noMoreFiles) {
this.getFiles();
}
}
renderMedia () {
if (!this.state.albumSelected) {
return (
<AlbumsList
albums={this.state.albums}
onAlbumPress={this.selectAlbum.bind(this)}/>
);
} else {
return (
<MediaList
images={this.getAlbumImages(this.state.albumSelected)}
itemsPerRow={this.props.itemsPerRow}
selected={this.props.selected}
onBackPress={this.deselectAlbum.bind(this)}
callback={this.props.callback}
batchSize={this.props.batchSize}
selectMediaFile={this.selectMediaFile}
imageMargin={this.props.imageMargin}
markIcon={this.props.markIcon}
customSelectMarker={this.props.customSelectMarker}
activityIndicatorColor={this.state.activityIndicatorColor}
maximumSelectedFiles={this.props.maximumSelectedFiles || this.state.maximumSelectedFiles}
/>
);
}
}
render () {
return (
<View style={styles.base}>
{this.renderMedia()}
</View>
);
}
}
export default GalleryMediaPicker;