react-native-cameraroll/CameraRoll.js

245 lines
8.3 KiB
JavaScript
Raw Normal View History

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule CameraRoll
* @flow
*/
'use strict';
var ReactPropTypes = require('React').PropTypes
var RCTCameraRollManager = require('NativeModules').CameraRollManager;
var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
var deepFreezeAndThrowOnMutationInDev =
require('deepFreezeAndThrowOnMutationInDev');
var invariant = require('fbjs/lib/invariant');
var GROUP_TYPES_OPTIONS = [
'Album',
'All',
'Event',
'Faces',
'Library',
'PhotoStream',
'SavedPhotos', // default
];
var ASSET_TYPE_OPTIONS = [
'All',
'Videos',
'Photos', // default
];
// Flow treats Object and Array as disjoint types, currently.
deepFreezeAndThrowOnMutationInDev((GROUP_TYPES_OPTIONS: any));
deepFreezeAndThrowOnMutationInDev((ASSET_TYPE_OPTIONS: any));
/**
* Shape of the param arg for the `getPhotos` function.
*/
var getPhotosParamChecker = createStrictShapeTypeChecker({
/**
* The number of photos wanted in reverse order of the photo application
* (i.e. most recent first for SavedPhotos).
*/
first: ReactPropTypes.number.isRequired,
/**
* A cursor that matches `page_info { end_cursor }` returned from a previous
* call to `getPhotos`
*/
after: ReactPropTypes.string,
/**
* Specifies which group types to filter the results to.
*/
groupTypes: ReactPropTypes.oneOf(GROUP_TYPES_OPTIONS),
/**
* Specifies filter on group names, like 'Recent Photos' or custom album
* titles.
*/
groupName: ReactPropTypes.string,
/**
* Specifies filter on asset type
*/
assetType: ReactPropTypes.oneOf(ASSET_TYPE_OPTIONS),
/**
* Filter by mimetype (e.g. image/jpeg).
*/
mimeTypes: ReactPropTypes.arrayOf(ReactPropTypes.string),
});
/**
* Shape of the return value of the `getPhotos` function.
*/
var getPhotosReturnChecker = createStrictShapeTypeChecker({
// $FlowFixMe(>=0.41.0)
edges: ReactPropTypes.arrayOf(createStrictShapeTypeChecker({
node: createStrictShapeTypeChecker({
type: ReactPropTypes.string.isRequired,
group_name: ReactPropTypes.string.isRequired,
image: createStrictShapeTypeChecker({
uri: ReactPropTypes.string.isRequired,
height: ReactPropTypes.number.isRequired,
width: ReactPropTypes.number.isRequired,
isStored: ReactPropTypes.bool,
}).isRequired,
timestamp: ReactPropTypes.number.isRequired,
location: createStrictShapeTypeChecker({
latitude: ReactPropTypes.number,
longitude: ReactPropTypes.number,
altitude: ReactPropTypes.number,
heading: ReactPropTypes.number,
speed: ReactPropTypes.number,
}),
}).isRequired,
})).isRequired,
page_info: createStrictShapeTypeChecker({
has_next_page: ReactPropTypes.bool.isRequired,
start_cursor: ReactPropTypes.string,
end_cursor: ReactPropTypes.string,
}).isRequired,
});
/**
* `CameraRoll` provides access to the local camera roll / gallery.
* Before using this you must link the `RCTCameraRoll` library.
* You can refer to [Linking](docs/linking-libraries-ios.html) for help.
*
* ### Permissions
* The user's permission is required in order to access the Camera Roll on devices running iOS 10 or later.
* Fill out the `NSCameraUsageDescription` key in your `Info.plist` with a string that describes how your
* app will use this data. This key will appear as `Privacy - Camera Usage Description` in Xcode.
*
*/
class CameraRoll {
static GroupTypesOptions: Array<string>;
static AssetTypeOptions: Array<string>;
static saveImageWithTag(tag: string): Promise<Object> {
console.warn('CameraRoll.saveImageWithTag is deprecated. Use CameraRoll.saveToCameraRoll instead');
return this.saveToCameraRoll(tag, 'photo');
}
/**
* Saves the photo or video to the camera roll / gallery.
*
* On Android, the tag must be a local image or video URI, such as `"file:///sdcard/img.png"`.
*
* On iOS, the tag can be any image URI (including local, remote asset-library and base64 data URIs)
* or a local video file URI (remote or data URIs are not supported for saving video at this time).
*
* If the tag has a file extension of .mov or .mp4, it will be inferred as a video. Otherwise
* it will be treated as a photo. To override the automatic choice, you can pass an optional
* `type` parameter that must be one of 'photo' or 'video'.
*
* Returns a Promise which will resolve with the new URI.
*/
static saveToCameraRoll(tag: string, type?: 'photo' | 'video'): Promise<Object> {
invariant(
typeof tag === 'string',
'CameraRoll.saveToCameraRoll must be a valid string.'
);
invariant(
type === 'photo' || type === 'video' || type === undefined,
// $FlowFixMe(>=0.28.0)
`The second argument to saveToCameraRoll must be 'photo' or 'video'. You passed ${type}`
);
let mediaType = 'photo';
if (type) {
mediaType = type;
} else if (['mov', 'mp4'].indexOf(tag.split('.').slice(-1)[0]) >= 0) {
mediaType = 'video';
}
return RCTCameraRollManager.saveToCameraRoll(tag, mediaType);
}
/**
* Returns a Promise with photo identifier objects from the local camera
* roll of the device matching shape defined by `getPhotosReturnChecker`.
*
* Expects a params object of the following shape:
*
* - `first` : {number} : The number of photos wanted in reverse order of the photo application (i.e. most recent first for SavedPhotos).
* - `after` : {string} : A cursor that matches `page_info { end_cursor }` returned from a previous call to `getPhotos`.
* - `groupTypes` : {string} : Specifies which group types to filter the results to. Valid values are:
* - `Album`
* - `All`
* - `Event`
* - `Faces`
* - `Library`
* - `PhotoStream`
* - `SavedPhotos` // default
* - `groupName` : {string} : Specifies filter on group names, like 'Recent Photos' or custom album titles.
* - `assetType` : {string} : Specifies filter on asset type. Valid values are:
* - `All`
* - `Videos`
* - `Photos` // default
* - `mimeTypes` : {string} : Filter by mimetype (e.g. image/jpeg).
*
* Returns a Promise which when resolved will be of the following shape:
*
* - `edges` : {Array<node>} An array of node objects
* - `node`: {object} An object with the following shape:
* - `type`: {string}
* - `group_name`: {string}
* - `image`: {object} : An object with the following shape:
* - `uri`: {string}
* - `height`: {number}
* - `width`: {number}
* - `isStored`: {boolean}
* - `timestamp`: {number}
* - `location`: {object} : An object with the following shape:
* - `latitude`: {number}
* - `longitude`: {number}
* - `altitude`: {number}
* - `heading`: {number}
* - `speed`: {number}
* - `page_info` : {object} : An object with the following shape:
* - `has_next_page`: {boolean}
* - `start_cursor`: {boolean}
* - `end_cursor`: {boolean}
*/
static getPhotos(params) {
if (__DEV__) {
getPhotosParamChecker({params}, 'params', 'CameraRoll.getPhotos');
}
if (arguments.length > 1) {
console.warn('CameraRoll.getPhotos(tag, success, error) is deprecated. Use the returned Promise instead');
let successCallback = arguments[1];
if (__DEV__) {
const callback = arguments[1];
successCallback = (response) => {
getPhotosReturnChecker(
{response},
'response',
'CameraRoll.getPhotos callback'
);
callback(response);
};
}
const errorCallback = arguments[2] || ( () => {} );
RCTCameraRollManager.getPhotos(params).then(successCallback, errorCallback);
}
// TODO: Add the __DEV__ check back in to verify the Promise result
return RCTCameraRollManager.getPhotos(params);
}
}
CameraRoll.GroupTypesOptions = GROUP_TYPES_OPTIONS;
CameraRoll.AssetTypeOptions = ASSET_TYPE_OPTIONS;
module.exports = CameraRoll;