Skip to content

Commit

Permalink
feat: Support filter media items between dates (#140)
Browse files Browse the repository at this point in the history
* Update RNCCameraRollManager.m

* Update CameraRollModule.java

* Update README.md

* Update RNCCameraRollManager.m

* Update CameraRoll.d.ts

* Update RNCCameraRollManager.h

* Update CameraRollModule.java

* Update RNCCameraRollManager.m

* update code
  • Loading branch information
r0b0t3d committed Feb 5, 2020
1 parent 24f141c commit 75b4208
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 11 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ Returns a Promise with photo identifier objects from the local camera roll of th
* `Videos`
* `Photos` // default
* `mimeTypes` : {Array} : Filter by mimetype (e.g. image/jpeg).
* `fromTime` : {timestamp} : Filter from date added.
* `toTime` : {timestamp} : Filter to date added.

Returns a Promise which when resolved will be of the following shape:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ public void getPhotos(final ReadableMap params, final Promise promise) {
String after = params.hasKey("after") ? params.getString("after") : null;
String groupName = params.hasKey("groupName") ? params.getString("groupName") : null;
String assetType = params.hasKey("assetType") ? params.getString("assetType") : ASSET_TYPE_PHOTOS;
long fromTime = params.hasKey("fromTime") ? (long) params.getDouble("fromTime") : 0;
long toTime = params.hasKey("toTime") ? (long) params.getDouble("toTime") : 0;
ReadableArray mimeTypes = params.hasKey("mimeTypes")
? params.getArray("mimeTypes")
: null;
Expand All @@ -245,6 +247,8 @@ public void getPhotos(final ReadableMap params, final Promise promise) {
groupName,
mimeTypes,
assetType,
fromTime,
toTime,
promise)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
Expand All @@ -257,6 +261,8 @@ private static class GetMediaTask extends GuardedAsyncTask<Void, Void> {
private final @Nullable ReadableArray mMimeTypes;
private final Promise mPromise;
private final String mAssetType;
private final long mFromTime;
private final long mToTime;

private GetMediaTask(
ReactContext context,
Expand All @@ -265,6 +271,8 @@ private GetMediaTask(
@Nullable String groupName,
@Nullable ReadableArray mimeTypes,
String assetType,
long fromTime,
long toTime,
Promise promise) {
super(context);
mContext = context;
Expand All @@ -274,6 +282,8 @@ private GetMediaTask(
mMimeTypes = mimeTypes;
mPromise = promise;
mAssetType = assetType;
mFromTime = fromTime;
mToTime = toTime;
}

@Override
Expand Down Expand Up @@ -314,6 +324,15 @@ protected void doInBackgroundGuarded(Void... params) {
selection.replace(selection.length() - 1, selection.length(), ")");
}

if (mFromTime > 0) {
selection.append(" AND " + Images.Media.DATE_TAKEN + " > ?");
selectionArgs.add(mFromTime + "");
}
if (mToTime > 0) {
selection.append(" AND " + Images.Media.DATE_TAKEN + " <= ?");
selectionArgs.add(mToTime + "");
}

WritableMap response = new WritableNativeMap();
ContentResolver resolver = mContext.getContentResolver();

Expand Down
4 changes: 3 additions & 1 deletion ios/RNCCameraRollManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@

@interface RCTConvert (PHFetchOptions)

+ (PHFetchOptions *)PHFetchOptionsFromMediaType:(NSString *)mediaType;
+ (PHFetchOptions *)PHFetchOptionsFromMediaType:(NSString *)mediaType
fromTime:(NSUInteger)fromTime
toTime:(NSUInteger)toTime;

@end

Expand Down
39 changes: 29 additions & 10 deletions ios/RNCCameraRollManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,44 @@ @implementation RCTConvert (PHAssetCollectionSubtype)
@implementation RCTConvert (PHFetchOptions)

+ (PHFetchOptions *)PHFetchOptionsFromMediaType:(NSString *)mediaType
fromTime:(NSUInteger)fromTime
toTime:(NSUInteger)toTime
{
// This is not exhaustive in terms of supported media type predicates; more can be added in the future
NSString *const lowercase = [mediaType lowercaseString];
NSMutableArray *format = [NSMutableArray new];
NSMutableArray *arguments = [NSMutableArray new];

if ([lowercase isEqualToString:@"photos"]) {
PHFetchOptions *const options = [PHFetchOptions new];
options.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d", PHAssetMediaTypeImage];
return options;
[format addObject:@"mediaType = %d"];
[arguments addObject:@(PHAssetMediaTypeImage)];
} else if ([lowercase isEqualToString:@"videos"]) {
PHFetchOptions *const options = [PHFetchOptions new];
options.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d", PHAssetMediaTypeVideo];
return options;
[format addObject:@"mediaType = %d"];
[arguments addObject:@(PHAssetMediaTypeVideo)];
} else {
if (![lowercase isEqualToString:@"all"]) {
RCTLogError(@"Invalid filter option: '%@'. Expected one of 'photos',"
"'videos' or 'all'.", mediaType);
}
// This case includes the "all" mediatype
PHFetchOptions *const options = [PHFetchOptions new];
return options;
}

if (fromTime > 0) {
NSDate* fromDate = [NSDate dateWithTimeIntervalSince1970:fromTime/1000];
[format addObject:@"creationDate > %@"];
[arguments addObject:fromDate];
}
if (toTime > 0) {
NSDate* toDate = [NSDate dateWithTimeIntervalSince1970:toTime/1000];
[format addObject:@"creationDate < %@"];
[arguments addObject:toDate];
}

// This case includes the "all" mediatype
PHFetchOptions *const options = [PHFetchOptions new];
if ([format count] > 0) {
options.predicate = [NSPredicate predicateWithFormat:[format componentsJoinedByString:@" AND "] argumentArray:arguments];
}
return options;
}

@end
Expand Down Expand Up @@ -225,6 +242,8 @@ static void RCTResolvePromise(RCTPromiseResolveBlock resolve,
NSString *const groupName = [RCTConvert NSString:params[@"groupName"]];
NSString *const groupTypes = [[RCTConvert NSString:params[@"groupTypes"]] lowercaseString];
NSString *const mediaType = [RCTConvert NSString:params[@"assetType"]];
NSUInteger const fromTime = [RCTConvert NSInteger:params[@"fromTime"]];
NSUInteger const toTime = [RCTConvert NSInteger:params[@"toTime"]];
NSArray<NSString *> *const mimeTypes = [RCTConvert NSStringArray:params[@"mimeTypes"]];

// If groupTypes is "all", we want to fetch the SmartAlbum "all photos". Otherwise, all
Expand All @@ -235,7 +254,7 @@ static void RCTResolvePromise(RCTPromiseResolveBlock resolve,
PHAssetCollectionSubtype const collectionSubtype = [RCTConvert PHAssetCollectionSubtype:groupTypes];

// Predicate for fetching assets within a collection
PHFetchOptions *const assetFetchOptions = [RCTConvert PHFetchOptionsFromMediaType:mediaType];
PHFetchOptions *const assetFetchOptions = [RCTConvert PHFetchOptionsFromMediaType:mediaType fromTime:fromTime toTime:toTime];
assetFetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];

BOOL __block foundAfter = NO;
Expand Down
2 changes: 2 additions & 0 deletions typings/CameraRoll.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ declare namespace CameraRoll {
groupName?: string;
assetType?: AssetType;
mimeTypes?: Array<string>;
fromTime?: number;
toTime?: number;
}

interface PhotoIdentifier {
Expand Down

0 comments on commit 75b4208

Please sign in to comment.