mirror of
https://github.com/status-im/react-native-camera-roll.git
synced 2026-08-27 19:31:12 +00:00
feat(iOS): Add subTypes field (#495)
Allow to know PHAssetMediaSubtype on iOS. So for example if a node is a LivePhoto or a Panorama.
This commit is contained in:
@@ -113,6 +113,7 @@ export default class CameraRollExample extends React.Component<Props, State> {
|
||||
<Text>{asset.node.group_name}</Text>
|
||||
<Text>{new Date(asset.node.timestamp * 1000).toString()}</Text>
|
||||
<Text>{new Date(asset.node.modificationTimestamp * 1000).toString()}</Text>
|
||||
<Text>Subtypes: {asset.node.subTypes.join(' ')}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -248,6 +248,7 @@ 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}
|
||||
* `subTypes`: {Array<string>} : An array of subtype strings (see `SubTypes` type). Always [] on Android.
|
||||
* `group_name`: {string}
|
||||
* `image`: {object} : An object with the following shape:
|
||||
* `uri`: {string}
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeArray;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
@@ -615,6 +616,8 @@ public class CameraRollModule extends NativeCameraRollModuleSpec {
|
||||
int dateAddedIndex,
|
||||
int dateModifiedIndex) {
|
||||
node.putString("type", media.getString(mimeTypeIndex));
|
||||
WritableArray subTypes = Arguments.createArray();
|
||||
node.putArray("subTypes", subTypes);
|
||||
node.putString("group_name", media.getString(groupNameIndex));
|
||||
long dateTaken = media.getLong(dateTakenIndex);
|
||||
if (dateTaken == 0L) {
|
||||
|
||||
@@ -113,6 +113,7 @@ export default class CameraRollExample extends React.Component<Props, State> {
|
||||
<Text>{asset.node.group_name}</Text>
|
||||
<Text>{new Date(asset.node.timestamp * 1000).toString()}</Text>
|
||||
<Text>{new Date(asset.node.modificationTimestamp * 1000).toString()}</Text>
|
||||
<Text>Subtypes: {asset.node.subTypes.join(' ')}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -422,6 +422,8 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
|
||||
? @"audio"
|
||||
: @"unknown")));
|
||||
|
||||
NSArray<NSString*> *const assetMediaSubtypesLabel = [self mediaSubTypeLabelsForAsset:asset];
|
||||
|
||||
if (includeFileExtension) {
|
||||
NSString *name = [asset valueForKey:@"filename"];
|
||||
NSString *extension = [name pathExtension];
|
||||
@@ -433,6 +435,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
|
||||
[assets addObject:@{
|
||||
@"node": @{
|
||||
@"type": assetMediaTypeLabel, // TODO: switch to mimeType?
|
||||
@"subTypes":assetMediaSubtypesLabel,
|
||||
@"group_name": currentCollectionName,
|
||||
@"image": @{
|
||||
@"uri": uri,
|
||||
@@ -559,6 +562,8 @@ RCT_EXPORT_METHOD(getPhotoByInternalID:(NSString *)internalId
|
||||
|
||||
__block NSString *filePath = @"";
|
||||
|
||||
NSArray<NSString*> *const assetMediaSubtypesLabel = [self mediaSubTypeLabelsForAsset:asset];
|
||||
|
||||
// check if HEIC extension asset
|
||||
if (convertHeic && asset.mediaType == PHAssetMediaTypeImage && [uniformMimeType isEqual: @"public.heic"]) {
|
||||
// convert to JPEG
|
||||
@@ -589,6 +594,7 @@ RCT_EXPORT_METHOD(getPhotoByInternalID:(NSString *)internalId
|
||||
resolve(@{
|
||||
@"node": @{
|
||||
@"type": assetMediaTypeLabel,
|
||||
@"subTypes":assetMediaSubtypesLabel,
|
||||
@"image": @{
|
||||
@"filepath": fullPath,
|
||||
@"filename": originalFilename,
|
||||
@@ -631,6 +637,7 @@ RCT_EXPORT_METHOD(getPhotoByInternalID:(NSString *)internalId
|
||||
resolve(@{
|
||||
@"node": @{
|
||||
@"type": assetMediaTypeLabel,
|
||||
@"subTypes":assetMediaSubtypesLabel,
|
||||
@"image": @{
|
||||
@"filepath": filePath,
|
||||
@"filename": originalFilename,
|
||||
@@ -670,6 +677,38 @@ RCT_EXPORT_METHOD(getPhotoByInternalID:(NSString *)internalId
|
||||
}, false);
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *) mediaSubTypeLabelsForAsset:(PHAsset *)asset {
|
||||
PHAssetMediaSubtype subtype = asset.mediaSubtypes;
|
||||
NSMutableArray<NSString*> *mediaSubTypeLabels = [NSMutableArray array];
|
||||
|
||||
if (subtype & PHAssetMediaSubtypePhotoPanorama) {
|
||||
[mediaSubTypeLabels addObject:@"PhotoPanorama"];
|
||||
}
|
||||
if (subtype & PHAssetMediaSubtypePhotoHDR) {
|
||||
[mediaSubTypeLabels addObject:@"PhotoHDR"];
|
||||
}
|
||||
if (subtype & PHAssetMediaSubtypePhotoScreenshot) {
|
||||
[mediaSubTypeLabels addObject:@"PhotoScreenshot"];
|
||||
}
|
||||
if (subtype & PHAssetMediaSubtypePhotoLive) {
|
||||
[mediaSubTypeLabels addObject:@"PhotoLive"];
|
||||
}
|
||||
if (subtype & PHAssetMediaSubtypePhotoDepthEffect) {
|
||||
[mediaSubTypeLabels addObject:@"PhotoDepthEffect"];
|
||||
}
|
||||
if (subtype & PHAssetMediaSubtypeVideoStreamed) {
|
||||
[mediaSubTypeLabels addObject:@"VideoStreamed"];
|
||||
}
|
||||
if (subtype & PHAssetMediaSubtypeVideoHighFrameRate) {
|
||||
[mediaSubTypeLabels addObject:@"VideoHighFrameRate"];
|
||||
}
|
||||
if (subtype & PHAssetMediaSubtypeVideoTimelapse) {
|
||||
[mediaSubTypeLabels addObject:@"VideoTimelapse"];
|
||||
}
|
||||
|
||||
return mediaSubTypeLabels;
|
||||
}
|
||||
|
||||
static void checkPhotoLibraryConfig()
|
||||
{
|
||||
#if RCT_DEV
|
||||
|
||||
@@ -32,6 +32,16 @@ export type GroupTypes =
|
||||
| 'PhotoStream'
|
||||
| 'SavedPhotos';
|
||||
|
||||
export type SubTypes =
|
||||
| 'PhotoPanorama'
|
||||
| 'PhotoHDR'
|
||||
| 'PhotoScreenshot'
|
||||
| 'PhotoLive'
|
||||
| 'PhotoDepthEffect'
|
||||
| 'VideoStreamed'
|
||||
| 'VideoHighFrameRate'
|
||||
| 'VideoTimelapse';
|
||||
|
||||
export type Include =
|
||||
| 'filename'
|
||||
| 'fileSize'
|
||||
@@ -100,6 +110,7 @@ export type GetPhotosParams = {
|
||||
export type PhotoIdentifier = {
|
||||
node: {
|
||||
type: string;
|
||||
subTypes: SubTypes;
|
||||
group_name: string;
|
||||
image: {
|
||||
filename: string | null;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// and we want to stay compatible with those
|
||||
import {TurboModuleRegistry, TurboModule} from 'react-native';
|
||||
|
||||
import type {SubTypes} from './CameraRoll';
|
||||
|
||||
type Album = {
|
||||
title: string;
|
||||
count: number;
|
||||
@@ -11,6 +13,7 @@ type Album = {
|
||||
type PhotoIdentifier = {
|
||||
node: {
|
||||
type: string;
|
||||
subTypes: SubTypes;
|
||||
group_name: string;
|
||||
image: {
|
||||
filename: string | null;
|
||||
|
||||
Reference in New Issue
Block a user