From 3907e6b2e99fb5fd089871434fe4ea4fe9da28e7 Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Tue, 16 Apr 2024 12:55:45 +0200 Subject: [PATCH] swap camera roll fork with patch --- package.json | 2 +- patches/CameraRoll.ts.patch | 188 ++++++++++++++++++++++++ patches/NativeCameraRollModule.ts.patch | 74 ++++++++++ patches/RNCCameraRoll.mm.patch | 140 ++++++++++++++++++ yarn.lock | 5 +- 5 files changed, 406 insertions(+), 3 deletions(-) create mode 100644 patches/CameraRoll.ts.patch create mode 100644 patches/NativeCameraRollModule.ts.patch create mode 100644 patches/RNCCameraRoll.mm.patch diff --git a/package.json b/package.json index 69c89e9a90bb..d9335df60527 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@react-native-async-storage/async-storage": "1.19.3", - "@react-native-camera-roll/camera-roll": "git+https://github.com/status-im/react-native-camera-roll.git#refs/tags/v5.1.1.1", + "@react-native-camera-roll/camera-roll": "5.10.0", "@react-native-clipboard/clipboard": "1.13.2", "@react-native-community/audio-toolkit": "git+https://github.com/tbenr/react-native-audio-toolkit.git#refs/tags/v2.0.3-status-v6", "@react-native-community/blur": "git+https://github.com/status-im/react-native-blur.git#refs/tags/v4.3.3-status", diff --git a/patches/CameraRoll.ts.patch b/patches/CameraRoll.ts.patch new file mode 100644 index 000000000000..75fb80d96086 --- /dev/null +++ b/patches/CameraRoll.ts.patch @@ -0,0 +1,188 @@ +--- /tmp/tmp-status-mobile-8a12ad351/tmp.SnIPZikasU/CameraRoll.ts 2024-04-16 12:22:28.722553000 +0200 ++++ ./node_modules/@react-native-camera-roll/camera-roll/src/CameraRoll.ts 2024-04-16 12:22:40.347610946 +0200 +@@ -24,32 +24,32 @@ + }; + + export type GroupTypes = +- | 'Album' +- | 'All' +- | 'Event' +- | 'Faces' +- | 'Library' +- | 'PhotoStream' +- | 'SavedPhotos'; ++ | 'Album' ++ | 'All' ++ | 'Event' ++ | 'Faces' ++ | 'Library' ++ | 'PhotoStream' ++ | 'SavedPhotos'; + + export type SubTypes = +- | 'PhotoPanorama' +- | 'PhotoHDR' +- | 'PhotoScreenshot' +- | 'PhotoLive' +- | 'PhotoDepthEffect' +- | 'VideoStreamed' +- | 'VideoHighFrameRate' +- | 'VideoTimelapse'; ++ | 'PhotoPanorama' ++ | 'PhotoHDR' ++ | 'PhotoScreenshot' ++ | 'PhotoLive' ++ | 'PhotoDepthEffect' ++ | 'VideoStreamed' ++ | 'VideoHighFrameRate' ++ | 'VideoTimelapse'; + + export type Include = +- | 'filename' +- | 'fileSize' +- | 'fileExtension' +- | 'location' +- | 'imageSize' +- | 'playableDuration' +- | 'orientation'; ++ | 'filename' ++ | 'fileSize' ++ | 'fileExtension' ++ | 'location' ++ | 'imageSize' ++ | 'playableDuration' ++ | 'orientation'; + + export type AssetType = 'All' | 'Videos' | 'Photos'; + +@@ -164,14 +164,14 @@ + }; + + export type AlbumSubType = +- | 'AlbumRegular' +- | 'AlbumSyncedEvent' +- | 'AlbumSyncedFaces' +- | 'AlbumSyncedAlbum' +- | 'AlbumImported' +- | 'AlbumMyPhotoStream' +- | 'AlbumCloudShared' +- | 'Unknown'; ++ | 'AlbumRegular' ++ | 'AlbumSyncedEvent' ++ | 'AlbumSyncedFaces' ++ | 'AlbumSyncedAlbum' ++ | 'AlbumImported' ++ | 'AlbumMyPhotoStream' ++ | 'AlbumCloudShared' ++ | 'Unknown'; + + export type Album = { + title: string; +@@ -180,18 +180,18 @@ + }; + + export type ThumbnailSize = { +- height: number, +- width: number ++ height: number; ++ width: number; + }; + + export type PhotoThumbnailOptions = { +- allowNetworkAccess: boolean, //iOS only +- targetSize: ThumbnailSize, +- quality: number ++ allowNetworkAccess: boolean; //iOS only ++ targetSize: ThumbnailSize; ++ quality: number; + }; + + export type PhotoThumbnail = { +- thumbnailBase64: string, ++ thumbnailBase64: string; + }; + + /** +@@ -213,12 +213,25 @@ + } + + /** ++ * Returns total iOS image count ++ */ ++ static getPhotosCountiOS(): Promise { ++ return RNCCameraRoll.getPhotosCountiOS(''); ++ } ++ /** ++ * Returns favorites and their count iOS ++ */ ++ static getFavoritesiOS(): Promise { ++ return RNCCameraRoll.getFavoritesiOS(''); ++ } ++ ++ /** + * Saves the photo or video to the camera roll or photo library. + * + */ + static save( +- tag: string, +- options: SaveToCameraRollOptions = {}, ++ tag: string, ++ options: SaveToCameraRollOptions = {}, + ): Promise { + let {type = 'auto'} = options; + const {album = ''} = options; +@@ -234,17 +247,17 @@ + } + + static saveToCameraRoll( +- tag: string, +- type?: 'photo' | 'video' | 'auto', ++ tag: string, ++ type?: 'photo' | 'video' | 'auto', + ): Promise { + console.warn( +- 'CameraRoll.saveToCameraRoll(tag, type) is deprecated. Use the save function instead', ++ 'CameraRoll.saveToCameraRoll(tag, type) is deprecated. Use the save function instead', + ); + return CameraRoll.save(tag, {type}); + } + + static getAlbums( +- params: GetAlbumsParams = {assetType: 'All'}, ++ params: GetAlbumsParams = {assetType: 'All'}, + ): Promise { + return RNCCameraRoll.getAlbums(params); + } +@@ -279,8 +292,8 @@ + * @returns Promise + */ + static iosGetImageDataById( +- internalID: string, +- convertHeicImages = false, ++ internalID: string, ++ convertHeicImages = false, + ): Promise { + const conversionOption: PhotoConvertionOptions = { + convertHeicImages: convertHeicImages, +@@ -288,14 +301,17 @@ + return RNCCameraRoll.getPhotoByInternalID(internalID, conversionOption); + } + +- /** ++ /** + * Returns a Promise with thumbnail photo. + * + * @param internalID - PH photo internal ID. + * @param options - thumbnail photo options. + * @returns Promise + */ +- static getPhotoThumbnail(internalID: string, options: PhotoThumbnailOptions): Promise { +- return RNCCameraRoll.getPhotoThumbnail(internalID, options); +- } ++ static getPhotoThumbnail( ++ internalID: string, ++ options: PhotoThumbnailOptions, ++ ): Promise { ++ return RNCCameraRoll.getPhotoThumbnail(internalID, options); ++ } + } diff --git a/patches/NativeCameraRollModule.ts.patch b/patches/NativeCameraRollModule.ts.patch new file mode 100644 index 000000000000..51c574206cc7 --- /dev/null +++ b/patches/NativeCameraRollModule.ts.patch @@ -0,0 +1,74 @@ +--- /tmp/tmp-status-mobile-8a12ad351/tmp.v1Aju1hKVG/NativeCameraRollModule.ts 2024-04-16 12:14:39.262541000 +0200 ++++ ./node_modules/@react-native-camera-roll/camera-roll/src/NativeCameraRollModule.ts 2024-04-16 12:21:34.905876910 +0200 +@@ -2,17 +2,17 @@ + // we use Object type because methods on the native side use NSDictionary and ReadableMap + // and we want to stay compatible with those + import {TurboModuleRegistry, TurboModule} from 'react-native'; +-import type { PhotoThumbnail } from './CameraRoll'; ++import type {PhotoThumbnail} from './CameraRoll'; + + export type AlbumSubType = +- | 'AlbumRegular' +- | 'AlbumSyncedEvent' +- | 'AlbumSyncedFaces' +- | 'AlbumSyncedAlbum' +- | 'AlbumImported' +- | 'AlbumMyPhotoStream' +- | 'AlbumCloudShared' +- | 'Unknown'; ++ | 'AlbumRegular' ++ | 'AlbumSyncedEvent' ++ | 'AlbumSyncedFaces' ++ | 'AlbumSyncedAlbum' ++ | 'AlbumImported' ++ | 'AlbumMyPhotoStream' ++ | 'AlbumCloudShared' ++ | 'Unknown'; + + type Album = { + title: string; +@@ -21,14 +21,14 @@ + }; + + type SubTypes = +- | 'PhotoPanorama' +- | 'PhotoHDR' +- | 'PhotoScreenshot' +- | 'PhotoLive' +- | 'PhotoDepthEffect' +- | 'VideoStreamed' +- | 'VideoHighFrameRate' +- | 'VideoTimelapse'; ++ | 'PhotoPanorama' ++ | 'PhotoHDR' ++ | 'PhotoScreenshot' ++ | 'PhotoLive' ++ | 'PhotoDepthEffect' ++ | 'VideoStreamed' ++ | 'VideoHighFrameRate' ++ | 'VideoTimelapse'; + + type PhotoIdentifier = { + node: { +@@ -73,14 +73,16 @@ + getPhotos(params: Object): Promise; + getAlbums(params: Object): Promise; + deletePhotos(photoUris: Array): Promise; ++ getPhotosCountiOS(arg: string): Promise; ++ getFavoritesiOS(arg: string): Promise; + getPhotoByInternalID( +- internalID: string, +- options: Object, ++ internalID: string, ++ options: Object, + ): Promise; + getPhotoThumbnail( +- internalID: string, +- options: Object +- ): Promise ++ internalID: string, ++ options: Object, ++ ): Promise; + } + + export default TurboModuleRegistry.getEnforcing('RNCCameraRoll'); diff --git a/patches/RNCCameraRoll.mm.patch b/patches/RNCCameraRoll.mm.patch new file mode 100644 index 000000000000..f4dccc0b9537 --- /dev/null +++ b/patches/RNCCameraRoll.mm.patch @@ -0,0 +1,140 @@ +--- /tmp/tmp-status-mobile-8a12ad351/tmp.1GxFrJZyJK/RNCCameraRoll.mm 2024-04-16 12:08:50.684272000 +0200 ++++ ./node_modules/@react-native-camera-roll/camera-roll/ios/RNCCameraRoll.mm 2024-04-16 12:09:28.792265816 +0200 +@@ -178,14 +178,14 @@ + if ([[inputURI.pathExtension lowercaseString] isEqualToString:@"webp"]) { + UIImage *webpImage; + +- #ifdef SD_WEB_IMAGE_WEBP_CODER_AVAILABLE ++ #ifdef SD_WEB_IMAGE_WEBP_CODER_AVAILABLE + webpImage = [[SDImageWebPCoder sharedCoder] decodedImageWithData:data options:nil]; + #else + if (@available(iOS 14, *)) { + webpImage = [UIImage imageWithData:data]; + } + #endif +- ++ + if (webpImage) { + data = UIImageJPEGRepresentation(webpImage, 1.0); + } +@@ -701,15 +701,15 @@ + checkPhotoLibraryConfig(); + + BOOL const allowNetworkAccess = options[@"allowNetworkAccess"] == nil ? NO : [RCTConvert BOOL:options[@"allowNetworkAccess"]]; +- ++ + NSDictionary *const targetSize = [RCTConvert NSDictionary:options[@"targetSize"]]; + CGFloat const targetHeight = targetSize[@"height"] == nil ? 400 : [RCTConvert CGFloat:targetSize[@"height"]]; + CGFloat const targetWidth = targetSize[@"width"] == nil ? 400 : [RCTConvert CGFloat:targetSize[@"width"]]; +- ++ + CGFloat quality = options[@"quality"] == nil ? 1.0 : [RCTConvert CGFloat:options[@"quality"]]; + + requestPhotoLibraryAccess(reject, ^(bool isLimited){ +- ++ + PHFetchResult *fetchResult; + PHAsset *asset; + NSString *mediaIdentifier = internalId; +@@ -729,7 +729,7 @@ + requestOptions.networkAccessAllowed = allowNetworkAccess; + requestOptions.version = PHImageRequestOptionsVersionUnadjusted; + requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; +- ++ + CGSize const thumbnailSize = CGSizeMake(targetWidth, targetHeight); + [[PHImageManager defaultManager] requestImageForAsset:asset + targetSize:thumbnailSize +@@ -741,9 +741,9 @@ + if (error) { + reject(@"Error while getting thumbnail image",@"Error while getting thumbnail image",error); + } +- ++ + NSString *thumbnailBase64 = [UIImageJPEGRepresentation(image, quality) base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; +- ++ + resolve(@{ + @"thumbnailBase64": thumbnailBase64 + }); +@@ -759,7 +759,7 @@ + + NSString *subTypeLabelForCollection(PHAssetCollection *assetCollection) { + PHAssetCollectionSubtype subtype = assetCollection.assetCollectionSubtype; +- ++ + switch (subtype) { + case PHAssetCollectionSubtypeAlbumRegular: + return @"AlbumRegular"; +@@ -774,7 +774,7 @@ + case PHAssetCollectionSubtypeAlbumMyPhotoStream: + return @"AlbumMyPhotoStream"; + case PHAssetCollectionSubtypeAlbumCloudShared: +- return @"AlbumCloudShared"; ++ return @"AlbumCloudShared"; + default: + return @"Unknown"; + } +@@ -783,7 +783,7 @@ + - (NSArray *) mediaSubTypeLabelsForAsset:(PHAsset *)asset { + PHAssetMediaSubtype subtype = asset.mediaSubtypes; + NSMutableArray *mediaSubTypeLabels = [NSMutableArray array]; +- ++ + if (subtype & PHAssetMediaSubtypePhotoPanorama) { + [mediaSubTypeLabels addObject:@"PhotoPanorama"]; + } +@@ -812,6 +812,53 @@ + return mediaSubTypeLabels; + } + ++RCT_EXPORT_METHOD(getPhotosCountiOS:(NSString *)blank ++ resolve:(RCTPromiseResolveBlock)resolve ++ reject:(RCTPromiseRejectBlock)reject) ++{ ++ __block NSInteger intTotalCount=0; ++ PHFetchOptions *allPhotosOptions = [PHFetchOptions new]; ++ allPhotosOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d ",PHAssetMediaTypeImage]; ++ PHFetchResult *allPhotosResult = [PHAsset fetchAssetsWithOptions:allPhotosOptions]; ++ intTotalCount+=allPhotosResult.count; ++ ++ resolve(@(intTotalCount)); ++} ++ ++RCT_EXPORT_METHOD(getFavoritesiOS:(NSString *)blank ++ resolve:(RCTPromiseResolveBlock)resolve ++ reject:(RCTPromiseRejectBlock)reject) ++{ ++ __block NSInteger intTotalCount=0; ++ PHFetchOptions *fetchOptions = [PHFetchOptions new]; ++ NSString *format = @"(favorite == true)"; ++ fetchOptions.predicate = [NSPredicate predicateWithFormat:format]; ++ PHFetchResult *const assetsFetchResult = [PHAsset fetchAssetsWithOptions:fetchOptions]; ++ PHAsset *imageAsset = [assetsFetchResult firstObject]; ++ NSMutableArray * result = [NSMutableArray new]; ++ ++ for (PHAsset* asset in assetsFetchResult) { ++ NSArray *resources = [PHAssetResource assetResourcesForAsset:asset ]; ++ if ([resources count] < 1) continue; ++ NSString *orgFilename = ((PHAssetResource*)resources[0]).originalFilename; ++ NSString *uit = ((PHAssetResource*)resources[0]).uniformTypeIdentifier; ++ NSString *mimeType = (NSString *)CFBridgingRelease(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef _Nonnull)(uit), kUTTagClassMIMEType)); ++ CFStringRef extension = UTTypeCopyPreferredTagWithClass((__bridge CFStringRef _Nonnull)(uit), kUTTagClassFilenameExtension); ++ [result addObject:@{ ++ @"width": @([asset pixelWidth]), ++ @"height": @([asset pixelHeight]), ++ @"filename": orgFilename ?: @"", ++ @"mimeType": mimeType ?: @"", ++ @"id": [asset localIdentifier], ++ @"creationDate": [asset creationDate], ++ @"uri": [NSString stringWithFormat:@"ph://%@", [asset localIdentifier]], ++ @"duration": @([asset duration]) ++ }]; ++ } ++ [result addObject:@{@"count": @(assetsFetchResult.count)}]; ++ resolve(result); ++} ++ + static void checkPhotoLibraryConfig() + { + #if RCT_DEV diff --git a/yarn.lock b/yarn.lock index 1f2358dee69e..cca958952d7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2576,9 +2576,10 @@ dependencies: merge-options "^3.0.4" -"@react-native-camera-roll/camera-roll@git+https://github.com/status-im/react-native-camera-roll.git#refs/tags/v5.1.1.1": +"@react-native-camera-roll/camera-roll@5.10.0": version "5.10.0" - resolved "git+https://github.com/status-im/react-native-camera-roll.git#174f8c6ad88e5bad9d9bd207f42173e567ec3138" + resolved "https://registry.yarnpkg.com/@react-native-camera-roll/camera-roll/-/camera-roll-5.10.0.tgz#98cf5489be6805ac926b1c4d29ac956cf4df45dc" + integrity sha512-NZb/zU4S+k1Hx2Y3BdNufrfn8whNsiRjHNxeiGMak8OwDDJikqP5Ej7HXFv8sJSfTGfi1ddH0wdd541MHV/Nbw== "@react-native-clipboard/clipboard@1.13.2": version "1.13.2"