stream-chat-react-native 5.44.2 → 6.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/android/build.gradle +103 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/streamchatreactnative/StreamChatReactNative.java +594 -0
- package/android/src/main/java/com/streamchatreactnative/StreamChatReactNativeModule.java +111 -0
- package/android/src/main/java/com/streamchatreactnative/StreamChatReactNativePackage.java +45 -0
- package/android/src/newarch/com/streamchatreactnative/StreamChatReactNative.java +9 -0
- package/android/src/oldarch/com/streamchatreactnative/StreamChatReactNative.java +16 -0
- package/ios/ImageHelpers.h +57 -0
- package/ios/ImageHelpers.m +179 -0
- package/ios/StreamChatReactNative.h +13 -0
- package/ios/StreamChatReactNative.mm +417 -0
- package/ios/StreamChatReactNative.xcodeproj/project.pbxproj +280 -0
- package/package.json +31 -21
- package/src/handlers/compressImage.ts +3 -4
- package/src/handlers/index.ts +0 -5
- package/src/index.js +6 -3
- package/src/native/NativeStreamChatReactNative.ts +24 -0
- package/src/native/index.tsx +48 -0
- package/src/native/types.ts +32 -0
- package/src/optionalDependencies/Audio.ts +10 -4
- package/src/optionalDependencies/FlatList.ts +21 -0
- package/src/{handlers → optionalDependencies}/Sound.tsx +1 -1
- package/src/{handlers → optionalDependencies}/Video.tsx +1 -1
- package/src/optionalDependencies/deleteFile.ts +19 -0
- package/src/optionalDependencies/getLocalAssetUri.ts +8 -3
- package/src/optionalDependencies/getPhotos.ts +20 -10
- package/src/optionalDependencies/iOS14RefreshGallerySelection.ts +1 -1
- package/src/optionalDependencies/index.ts +10 -6
- package/src/optionalDependencies/oniOS14GalleryLibrarySelectionChange.ts +1 -1
- package/src/optionalDependencies/saveFile.ts +24 -0
- package/src/optionalDependencies/shareImage.ts +10 -6
- package/src/optionalDependencies/takePhoto.ts +15 -11
- package/stream-chat-react-native.podspec +38 -0
- package/src/handlers/NetInfo.ts +0 -43
- package/src/handlers/deleteFile.ts +0 -11
- package/src/handlers/saveFile.ts +0 -11
- /package/src/optionalDependencies/{Video.ts → AudioVideo.ts} +0 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
#import "StreamChatReactNative.h"
|
|
2
|
+
#import <React/RCTLog.h>
|
|
3
|
+
#import <AssetsLibrary/AssetsLibrary.h>
|
|
4
|
+
#import <MobileCoreServices/MobileCoreServices.h>
|
|
5
|
+
|
|
6
|
+
#if __has_include(<React/RCTLog.h>)
|
|
7
|
+
#import <React/RCTLog.h>
|
|
8
|
+
#import <React/RCTImageLoader.h>
|
|
9
|
+
#else
|
|
10
|
+
#import "RCTLog.h"
|
|
11
|
+
#import "RCTImageLoader.h"
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
NSString *moduleName = @"StreamChatReactNative";
|
|
15
|
+
|
|
16
|
+
@implementation StreamChatReactNative
|
|
17
|
+
|
|
18
|
+
@synthesize bridge = _bridge;
|
|
19
|
+
|
|
20
|
+
RCT_EXPORT_MODULE()
|
|
21
|
+
|
|
22
|
+
RCT_REMAP_METHOD(createResizedImage, uri:(NSString *)uri width:(double)width height:(double)height format:(NSString *)format quality:(double)quality mode:(NSString *)mode onlyScaleDown:(BOOL)onlyScaleDown rotation:(nonnull NSNumber *)rotation outputPath:(NSString *)outputPath keepMeta:(nonnull NSNumber *)keepMeta resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
|
|
23
|
+
{
|
|
24
|
+
[self createResizedImage:uri width:width height:height format:format quality:quality mode:mode onlyScaleDown:onlyScaleDown rotation:rotation outputPath:outputPath keepMeta:keepMeta resolve:resolve reject:reject];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
- (void)createResizedImage:(NSString *)uri width:(double)width height:(double)height format:(NSString *)format quality:(double)quality mode:(NSString *)mode onlyScaleDown:(BOOL)onlyScaleDown rotation:(nonnull NSNumber *)rotation outputPath:(NSString *)outputPath keepMeta:(nonnull NSNumber *)keepMeta resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
28
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
29
|
+
@try {
|
|
30
|
+
CGSize newSize = CGSizeMake(width, height);
|
|
31
|
+
|
|
32
|
+
//Set image extension
|
|
33
|
+
NSString *extension = @"jpg";
|
|
34
|
+
if ([format isEqualToString:@"PNG"]) {
|
|
35
|
+
extension = @"png";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
NSString* fullPath;
|
|
39
|
+
@try {
|
|
40
|
+
fullPath = generateFilePath(extension, outputPath);
|
|
41
|
+
} @catch (NSException *exception) {
|
|
42
|
+
[NSException raise:moduleName format:@"Invalid output path."];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
RCTImageLoader *loader = [self.bridge moduleForName:@"ImageLoader" lazilyLoadIfNecessary:YES];
|
|
46
|
+
NSURLRequest *request = [RCTConvert NSURLRequest:uri];
|
|
47
|
+
[loader loadImageWithURLRequest:request
|
|
48
|
+
size:newSize
|
|
49
|
+
scale:1
|
|
50
|
+
clipped:NO
|
|
51
|
+
resizeMode:RCTResizeModeContain
|
|
52
|
+
progressBlock:nil
|
|
53
|
+
partialLoadBlock:nil
|
|
54
|
+
completionBlock:^(NSError *error, UIImage *image) {
|
|
55
|
+
if (error) {
|
|
56
|
+
RCTLogError(@"%@", [NSString stringWithFormat:@"Code : %@ / Message : %@", [NSString stringWithFormat: @"%ld", (long)error.code], error.description]);
|
|
57
|
+
reject([NSString stringWithFormat: @"%ld", (long)error.code], error.description, nil);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
NSDictionary * response = transformImage(image, uri, [rotation integerValue], newSize, fullPath, format, (int)quality, [keepMeta boolValue], @{@"mode": mode, @"onlyScaleDown": [NSNumber numberWithBool:onlyScaleDown]});
|
|
61
|
+
resolve(response);
|
|
62
|
+
}];
|
|
63
|
+
} @catch (NSException *exception) {
|
|
64
|
+
RCTLogError(@"%@", [NSString stringWithFormat:@"Code : %@ / Message : %@", exception.name, exception.reason]);
|
|
65
|
+
reject(exception.name, exception.reason, nil);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
bool saveImage(NSString * fullPath, UIImage * image, NSString * format, float quality, NSMutableDictionary *metadata)
|
|
73
|
+
{
|
|
74
|
+
if(metadata == nil){
|
|
75
|
+
NSData* data = nil;
|
|
76
|
+
if ([format isEqualToString:@"JPEG"]) {
|
|
77
|
+
data = UIImageJPEGRepresentation(image, quality / 100.0);
|
|
78
|
+
} else if ([format isEqualToString:@"PNG"]) {
|
|
79
|
+
data = UIImagePNGRepresentation(image);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (data == nil) {
|
|
83
|
+
return NO;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
NSFileManager* fileManager = [NSFileManager defaultManager];
|
|
87
|
+
return [fileManager createFileAtPath:fullPath contents:data attributes:nil];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// process / write metadata together with image data
|
|
91
|
+
else{
|
|
92
|
+
|
|
93
|
+
CFStringRef imgType = kUTTypeJPEG;
|
|
94
|
+
|
|
95
|
+
if ([format isEqualToString:@"JPEG"]) {
|
|
96
|
+
[metadata setObject:@(quality / 100.0) forKey:(__bridge NSString *)kCGImageDestinationLossyCompressionQuality];
|
|
97
|
+
}
|
|
98
|
+
else if([format isEqualToString:@"PNG"]){
|
|
99
|
+
imgType = kUTTypePNG;
|
|
100
|
+
}
|
|
101
|
+
else{
|
|
102
|
+
return NO;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
NSMutableData * destData = [NSMutableData data];
|
|
106
|
+
|
|
107
|
+
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)destData, imgType, 1, NULL);
|
|
108
|
+
|
|
109
|
+
@try{
|
|
110
|
+
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef) metadata);
|
|
111
|
+
|
|
112
|
+
// write final image data with metadata to our destination
|
|
113
|
+
if (CGImageDestinationFinalize(destination)){
|
|
114
|
+
|
|
115
|
+
NSFileManager* fileManager = [NSFileManager defaultManager];
|
|
116
|
+
return [fileManager createFileAtPath:fullPath contents:destData attributes:nil];
|
|
117
|
+
}
|
|
118
|
+
else{
|
|
119
|
+
return NO;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
@finally{
|
|
123
|
+
@try{
|
|
124
|
+
CFRelease(destination);
|
|
125
|
+
}
|
|
126
|
+
@catch(NSException *exception){
|
|
127
|
+
NSLog(@"Failed to release CGImageDestinationRef: %@", exception);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
NSString * generateFilePath(NSString * ext, NSString * outputPath)
|
|
134
|
+
{
|
|
135
|
+
NSString* directory;
|
|
136
|
+
|
|
137
|
+
if ([outputPath length] == 0) {
|
|
138
|
+
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
|
139
|
+
directory = [paths firstObject];
|
|
140
|
+
} else {
|
|
141
|
+
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
|
142
|
+
NSString *documentsDirectory = [paths objectAtIndex:0];
|
|
143
|
+
if ([outputPath hasPrefix:documentsDirectory]) {
|
|
144
|
+
directory = outputPath;
|
|
145
|
+
} else {
|
|
146
|
+
directory = [documentsDirectory stringByAppendingPathComponent:outputPath];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
NSError *error;
|
|
150
|
+
[[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error];
|
|
151
|
+
if (error) {
|
|
152
|
+
NSLog(@"Error creating documents subdirectory: %@", error);
|
|
153
|
+
@throw [NSException exceptionWithName:@"InvalidPathException" reason:[NSString stringWithFormat:@"Error creating documents subdirectory: %@", error] userInfo:nil];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
NSString* name = [[NSUUID UUID] UUIDString];
|
|
158
|
+
NSString* fullName = [NSString stringWithFormat:@"%@.%@", name, ext];
|
|
159
|
+
NSString* fullPath = [directory stringByAppendingPathComponent:fullName];
|
|
160
|
+
|
|
161
|
+
return fullPath;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
UIImage * rotateImage(UIImage *inputImage, float rotationDegrees)
|
|
165
|
+
{
|
|
166
|
+
|
|
167
|
+
// We want only fixed 0, 90, 180, 270 degree rotations.
|
|
168
|
+
const int rotDiv90 = (int)round(rotationDegrees / 90);
|
|
169
|
+
const int rotQuadrant = rotDiv90 % 4;
|
|
170
|
+
const int rotQuadrantAbs = (rotQuadrant < 0) ? rotQuadrant + 4 : rotQuadrant;
|
|
171
|
+
|
|
172
|
+
// Return the input image if no rotation specified.
|
|
173
|
+
if (0 == rotQuadrantAbs) {
|
|
174
|
+
return inputImage;
|
|
175
|
+
} else {
|
|
176
|
+
// Rotate the image by 80, 180, 270.
|
|
177
|
+
UIImageOrientation orientation = UIImageOrientationUp;
|
|
178
|
+
|
|
179
|
+
switch(rotQuadrantAbs) {
|
|
180
|
+
case 1:
|
|
181
|
+
orientation = UIImageOrientationRight; // 90 deg CW
|
|
182
|
+
break;
|
|
183
|
+
case 2:
|
|
184
|
+
orientation = UIImageOrientationDown; // 180 deg rotation
|
|
185
|
+
break;
|
|
186
|
+
default:
|
|
187
|
+
orientation = UIImageOrientationLeft; // 90 deg CCW
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return [[UIImage alloc] initWithCGImage: inputImage.CGImage
|
|
192
|
+
scale: 1.0
|
|
193
|
+
orientation: orientation];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
float getScaleForProportionalResize(CGSize theSize, CGSize intoSize, bool onlyScaleDown, bool maximize)
|
|
198
|
+
{
|
|
199
|
+
float sx = theSize.width;
|
|
200
|
+
float sy = theSize.height;
|
|
201
|
+
float dx = intoSize.width;
|
|
202
|
+
float dy = intoSize.height;
|
|
203
|
+
float scale = 1;
|
|
204
|
+
|
|
205
|
+
if( sx != 0 && sy != 0 )
|
|
206
|
+
{
|
|
207
|
+
dx = dx / sx;
|
|
208
|
+
dy = dy / sy;
|
|
209
|
+
|
|
210
|
+
// if maximize is true, take LARGER of the scales, else smaller
|
|
211
|
+
if (maximize) {
|
|
212
|
+
scale = MAX(dx, dy);
|
|
213
|
+
} else {
|
|
214
|
+
scale = MIN(dx, dy);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (onlyScaleDown) {
|
|
218
|
+
scale = MIN(scale, 1);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else
|
|
222
|
+
{
|
|
223
|
+
scale = 0;
|
|
224
|
+
}
|
|
225
|
+
return scale;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
// returns a resized image keeping aspect ratio and considering
|
|
230
|
+
// any :image scale factor.
|
|
231
|
+
// The returned image is an unscaled image (scale = 1.0)
|
|
232
|
+
// so no additional scaling math needs to be done to get its pixel dimensions
|
|
233
|
+
UIImage* scaleImage (UIImage* image, CGSize toSize, NSString* mode, bool onlyScaleDown)
|
|
234
|
+
{
|
|
235
|
+
|
|
236
|
+
// Need to do scaling corrections
|
|
237
|
+
// based on scale, since UIImage width/height gives us
|
|
238
|
+
// a possibly scaled image (dimensions in points)
|
|
239
|
+
// Idea taken from RNCamera resize code
|
|
240
|
+
CGSize imageSize = CGSizeMake(image.size.width * image.scale, image.size.height * image.scale);
|
|
241
|
+
|
|
242
|
+
// using this instead of ImageHelpers allows us to consider
|
|
243
|
+
// rotation variations
|
|
244
|
+
CGSize newSize;
|
|
245
|
+
|
|
246
|
+
if ([mode isEqualToString:@"stretch"]) {
|
|
247
|
+
// Distort aspect ratio
|
|
248
|
+
int width = toSize.width;
|
|
249
|
+
int height = toSize.height;
|
|
250
|
+
|
|
251
|
+
if (onlyScaleDown) {
|
|
252
|
+
width = MIN(width, imageSize.width);
|
|
253
|
+
height = MIN(height, imageSize.height);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
newSize = CGSizeMake(width, height);
|
|
257
|
+
} else {
|
|
258
|
+
// Either "contain" (default) or "cover": preserve aspect ratio
|
|
259
|
+
bool maximize = [mode isEqualToString:@"cover"];
|
|
260
|
+
float scale = getScaleForProportionalResize(imageSize, toSize, onlyScaleDown, maximize);
|
|
261
|
+
newSize = CGSizeMake(roundf(imageSize.width * scale), roundf(imageSize.height * scale));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
UIGraphicsBeginImageContextWithOptions(newSize, NO, 1.0);
|
|
265
|
+
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
|
|
266
|
+
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
267
|
+
UIGraphicsEndImageContext();
|
|
268
|
+
return newImage;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Returns the image's metadata, or nil if failed to retrieve it.
|
|
272
|
+
NSMutableDictionary * getImageMeta(NSString * path)
|
|
273
|
+
{
|
|
274
|
+
if([path hasPrefix:@"assets-library"]) {
|
|
275
|
+
|
|
276
|
+
__block NSMutableDictionary* res = nil;
|
|
277
|
+
|
|
278
|
+
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
|
|
279
|
+
{
|
|
280
|
+
|
|
281
|
+
NSDictionary *exif = [[myasset defaultRepresentation] metadata];
|
|
282
|
+
res = [exif mutableCopy];
|
|
283
|
+
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
|
|
287
|
+
NSURL *url = [NSURL URLWithString:[path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
|
|
288
|
+
|
|
289
|
+
[assetslibrary assetForURL:url resultBlock:resultblock failureBlock:^(NSError *error) { NSLog(@"error couldn't image from assets library"); }];
|
|
290
|
+
|
|
291
|
+
return res;
|
|
292
|
+
|
|
293
|
+
} else {
|
|
294
|
+
|
|
295
|
+
NSData* imageData = nil;
|
|
296
|
+
|
|
297
|
+
if ([path hasPrefix:@"data:"] || [path hasPrefix:@"file:"]) {
|
|
298
|
+
NSURL *imageUrl = [[NSURL alloc] initWithString:path];
|
|
299
|
+
imageData = [NSData dataWithContentsOfURL:imageUrl];
|
|
300
|
+
|
|
301
|
+
} else {
|
|
302
|
+
imageData = [NSData dataWithContentsOfFile:path];
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if(imageData == nil){
|
|
306
|
+
NSLog(@"Could not get image file data to extract metadata.");
|
|
307
|
+
return nil;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
if(source != nil){
|
|
314
|
+
|
|
315
|
+
CFDictionaryRef metaRef = CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
|
|
316
|
+
|
|
317
|
+
// release CF image
|
|
318
|
+
CFRelease(source);
|
|
319
|
+
|
|
320
|
+
CFMutableDictionaryRef metaRefMutable = CFDictionaryCreateMutableCopy(NULL, 0, metaRef);
|
|
321
|
+
|
|
322
|
+
// release the source meta ref now that we've copie it
|
|
323
|
+
CFRelease(metaRef);
|
|
324
|
+
|
|
325
|
+
// bridge CF object so it auto releases
|
|
326
|
+
NSMutableDictionary* res = (NSMutableDictionary *)CFBridgingRelease(metaRefMutable);
|
|
327
|
+
|
|
328
|
+
return res;
|
|
329
|
+
|
|
330
|
+
}
|
|
331
|
+
else{
|
|
332
|
+
return nil;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
NSDictionary * transformImage(UIImage *image,
|
|
339
|
+
NSString * originalPath,
|
|
340
|
+
int rotation,
|
|
341
|
+
CGSize newSize,
|
|
342
|
+
NSString* fullPath,
|
|
343
|
+
NSString* format,
|
|
344
|
+
int quality,
|
|
345
|
+
BOOL keepMeta,
|
|
346
|
+
NSDictionary* options)
|
|
347
|
+
{
|
|
348
|
+
if (image == nil) {
|
|
349
|
+
[NSException raise:moduleName format:@"Can't retrieve the file from the path."];
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Rotate image if rotation is specified.
|
|
353
|
+
if (0 != (int)rotation) {
|
|
354
|
+
image = rotateImage(image, rotation);
|
|
355
|
+
if (image == nil) {
|
|
356
|
+
[NSException raise:moduleName format:@"Can't rotate the image."];
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Do the resizing
|
|
361
|
+
UIImage * scaledImage = scaleImage(
|
|
362
|
+
image,
|
|
363
|
+
newSize,
|
|
364
|
+
options[@"mode"],
|
|
365
|
+
[[options objectForKey:@"onlyScaleDown"] boolValue]
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
if (scaledImage == nil) {
|
|
369
|
+
[NSException raise:moduleName format:@"Can't resize the image."];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
NSMutableDictionary *metadata = nil;
|
|
374
|
+
|
|
375
|
+
// to be consistent with Android, we will only allow JPEG
|
|
376
|
+
// to do this.
|
|
377
|
+
if(keepMeta && [format isEqualToString:@"JPEG"]){
|
|
378
|
+
|
|
379
|
+
metadata = getImageMeta(originalPath);
|
|
380
|
+
|
|
381
|
+
// remove orientation (since we fix it)
|
|
382
|
+
// width/height meta is adjusted automatically
|
|
383
|
+
// NOTE: This might still leave some stale values due to resize
|
|
384
|
+
metadata[(NSString*)kCGImagePropertyOrientation] = @(1);
|
|
385
|
+
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Compress and save the image
|
|
389
|
+
if (!saveImage(fullPath, scaledImage, format, quality, metadata)) {
|
|
390
|
+
[NSException raise:moduleName format:@"Can't save the image. Check your compression format and your output path"];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:fullPath];
|
|
394
|
+
NSString *fileName = fileUrl.lastPathComponent;
|
|
395
|
+
NSError *attributesError = nil;
|
|
396
|
+
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:&attributesError];
|
|
397
|
+
NSNumber *fileSize = fileAttributes == nil ? 0 : [fileAttributes objectForKey:NSFileSize];
|
|
398
|
+
NSDictionary *response = @{@"path": fullPath,
|
|
399
|
+
@"uri": fileUrl.absoluteString,
|
|
400
|
+
@"name": fileName,
|
|
401
|
+
@"size": fileSize == nil ? @(0) : fileSize,
|
|
402
|
+
@"width": @(scaledImage.size.width),
|
|
403
|
+
@"height": @(scaledImage.size.height),
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
return response;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Don't compile this code when we build for the old architecture.
|
|
410
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
411
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
412
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
413
|
+
{
|
|
414
|
+
return std::make_shared<facebook::react::NativeStreamChatReactNativeSpecJSI>(params);
|
|
415
|
+
}
|
|
416
|
+
#endif
|
|
417
|
+
@end
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// !$*UTF8*$!
|
|
2
|
+
{
|
|
3
|
+
archiveVersion = 1;
|
|
4
|
+
classes = {
|
|
5
|
+
};
|
|
6
|
+
objectVersion = 54;
|
|
7
|
+
objects = {
|
|
8
|
+
|
|
9
|
+
/* Begin PBXCopyFilesBuildPhase section */
|
|
10
|
+
58B511D91A9E6C8500147676 /* CopyFiles */ = {
|
|
11
|
+
isa = PBXCopyFilesBuildPhase;
|
|
12
|
+
buildActionMask = 2147483647;
|
|
13
|
+
dstPath = "include/$(PRODUCT_NAME)";
|
|
14
|
+
dstSubfolderSpec = 16;
|
|
15
|
+
files = (
|
|
16
|
+
);
|
|
17
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
18
|
+
};
|
|
19
|
+
/* End PBXCopyFilesBuildPhase section */
|
|
20
|
+
|
|
21
|
+
/* Begin PBXFileReference section */
|
|
22
|
+
134814201AA4EA6300B7C361 /* libStreamChatReactNative.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libStreamChatReactNative.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
23
|
+
B3E7B5881CC2AC0600A0062D /* StreamChatReactNative.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamChatReactNative.h; sourceTree = "<group>"; };
|
|
24
|
+
B3E7B5891CC2AC0600A0062D /* StreamChatReactNative.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamChatReactNative.mm; sourceTree = "<group>"; };
|
|
25
|
+
/* End PBXFileReference section */
|
|
26
|
+
|
|
27
|
+
/* Begin PBXFrameworksBuildPhase section */
|
|
28
|
+
58B511D81A9E6C8500147676 /* Frameworks */ = {
|
|
29
|
+
isa = PBXFrameworksBuildPhase;
|
|
30
|
+
buildActionMask = 2147483647;
|
|
31
|
+
files = (
|
|
32
|
+
);
|
|
33
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
34
|
+
};
|
|
35
|
+
/* End PBXFrameworksBuildPhase section */
|
|
36
|
+
|
|
37
|
+
/* Begin PBXGroup section */
|
|
38
|
+
134814211AA4EA7D00B7C361 /* Products */ = {
|
|
39
|
+
isa = PBXGroup;
|
|
40
|
+
children = (
|
|
41
|
+
134814201AA4EA6300B7C361 /* libStreamChatReactNative.a */,
|
|
42
|
+
);
|
|
43
|
+
name = Products;
|
|
44
|
+
sourceTree = "<group>";
|
|
45
|
+
};
|
|
46
|
+
58B511D21A9E6C8500147676 = {
|
|
47
|
+
isa = PBXGroup;
|
|
48
|
+
children = (
|
|
49
|
+
B3E7B5881CC2AC0600A0062D /* StreamChatReactNative.h */,
|
|
50
|
+
B3E7B5891CC2AC0600A0062D /* StreamChatReactNative.mm */,
|
|
51
|
+
134814211AA4EA7D00B7C361 /* Products */,
|
|
52
|
+
);
|
|
53
|
+
sourceTree = "<group>";
|
|
54
|
+
};
|
|
55
|
+
/* End PBXGroup section */
|
|
56
|
+
|
|
57
|
+
/* Begin PBXNativeTarget section */
|
|
58
|
+
58B511DA1A9E6C8500147676 /* StreamChatReactNative */ = {
|
|
59
|
+
isa = PBXNativeTarget;
|
|
60
|
+
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "StreamChatReactNative" */;
|
|
61
|
+
buildPhases = (
|
|
62
|
+
58B511D71A9E6C8500147676 /* Sources */,
|
|
63
|
+
58B511D81A9E6C8500147676 /* Frameworks */,
|
|
64
|
+
58B511D91A9E6C8500147676 /* CopyFiles */,
|
|
65
|
+
);
|
|
66
|
+
buildRules = (
|
|
67
|
+
);
|
|
68
|
+
dependencies = (
|
|
69
|
+
);
|
|
70
|
+
name = StreamChatReactNative;
|
|
71
|
+
productName = RCTDataManager;
|
|
72
|
+
productReference = 134814201AA4EA6300B7C361 /* libStreamChatReactNative.a */;
|
|
73
|
+
productType = "com.apple.product-type.library.static";
|
|
74
|
+
};
|
|
75
|
+
/* End PBXNativeTarget section */
|
|
76
|
+
|
|
77
|
+
/* Begin PBXProject section */
|
|
78
|
+
58B511D31A9E6C8500147676 /* Project object */ = {
|
|
79
|
+
isa = PBXProject;
|
|
80
|
+
attributes = {
|
|
81
|
+
BuildIndependentTargetsInParallel = YES;
|
|
82
|
+
LastUpgradeCheck = 1540;
|
|
83
|
+
ORGANIZATIONNAME = Facebook;
|
|
84
|
+
TargetAttributes = {
|
|
85
|
+
58B511DA1A9E6C8500147676 = {
|
|
86
|
+
CreatedOnToolsVersion = 6.1.1;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "StreamChatReactNative" */;
|
|
91
|
+
compatibilityVersion = "Xcode 3.2";
|
|
92
|
+
developmentRegion = English;
|
|
93
|
+
hasScannedForEncodings = 0;
|
|
94
|
+
knownRegions = (
|
|
95
|
+
English,
|
|
96
|
+
en,
|
|
97
|
+
);
|
|
98
|
+
mainGroup = 58B511D21A9E6C8500147676;
|
|
99
|
+
productRefGroup = 58B511D21A9E6C8500147676;
|
|
100
|
+
projectDirPath = "";
|
|
101
|
+
projectRoot = "";
|
|
102
|
+
targets = (
|
|
103
|
+
58B511DA1A9E6C8500147676 /* StreamChatReactNative */,
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
/* End PBXProject section */
|
|
107
|
+
|
|
108
|
+
/* Begin PBXSourcesBuildPhase section */
|
|
109
|
+
58B511D71A9E6C8500147676 /* Sources */ = {
|
|
110
|
+
isa = PBXSourcesBuildPhase;
|
|
111
|
+
buildActionMask = 2147483647;
|
|
112
|
+
files = (
|
|
113
|
+
);
|
|
114
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
115
|
+
};
|
|
116
|
+
/* End PBXSourcesBuildPhase section */
|
|
117
|
+
|
|
118
|
+
/* Begin XCBuildConfiguration section */
|
|
119
|
+
58B511ED1A9E6C8500147676 /* Debug */ = {
|
|
120
|
+
isa = XCBuildConfiguration;
|
|
121
|
+
buildSettings = {
|
|
122
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
123
|
+
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
|
124
|
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
125
|
+
CLANG_CXX_LIBRARY = "libc++";
|
|
126
|
+
CLANG_ENABLE_MODULES = YES;
|
|
127
|
+
CLANG_ENABLE_OBJC_ARC = YES;
|
|
128
|
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
|
129
|
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
130
|
+
CLANG_WARN_COMMA = YES;
|
|
131
|
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
132
|
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
|
133
|
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
134
|
+
CLANG_WARN_EMPTY_BODY = YES;
|
|
135
|
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
136
|
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
137
|
+
CLANG_WARN_INT_CONVERSION = YES;
|
|
138
|
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
|
139
|
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
|
140
|
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
|
141
|
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
142
|
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
|
143
|
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
|
144
|
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
|
145
|
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
|
146
|
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
147
|
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
148
|
+
COPY_PHASE_STRIP = NO;
|
|
149
|
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
150
|
+
ENABLE_TESTABILITY = YES;
|
|
151
|
+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
152
|
+
"EXCLUDED_ARCHS[sdk=*]" = arm64;
|
|
153
|
+
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
154
|
+
GCC_DYNAMIC_NO_PIC = NO;
|
|
155
|
+
GCC_NO_COMMON_BLOCKS = YES;
|
|
156
|
+
GCC_OPTIMIZATION_LEVEL = 0;
|
|
157
|
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
|
158
|
+
"DEBUG=1",
|
|
159
|
+
"$(inherited)",
|
|
160
|
+
);
|
|
161
|
+
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
|
162
|
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
163
|
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
164
|
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
165
|
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
166
|
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
167
|
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
168
|
+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
|
169
|
+
MTL_ENABLE_DEBUG_INFO = YES;
|
|
170
|
+
ONLY_ACTIVE_ARCH = YES;
|
|
171
|
+
SDKROOT = iphoneos;
|
|
172
|
+
};
|
|
173
|
+
name = Debug;
|
|
174
|
+
};
|
|
175
|
+
58B511EE1A9E6C8500147676 /* Release */ = {
|
|
176
|
+
isa = XCBuildConfiguration;
|
|
177
|
+
buildSettings = {
|
|
178
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
179
|
+
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
|
180
|
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
181
|
+
CLANG_CXX_LIBRARY = "libc++";
|
|
182
|
+
CLANG_ENABLE_MODULES = YES;
|
|
183
|
+
CLANG_ENABLE_OBJC_ARC = YES;
|
|
184
|
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
|
185
|
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
186
|
+
CLANG_WARN_COMMA = YES;
|
|
187
|
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
188
|
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
|
189
|
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
190
|
+
CLANG_WARN_EMPTY_BODY = YES;
|
|
191
|
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
192
|
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
193
|
+
CLANG_WARN_INT_CONVERSION = YES;
|
|
194
|
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
|
195
|
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
|
196
|
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
|
197
|
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
198
|
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
|
199
|
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
|
200
|
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
|
201
|
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
|
202
|
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
203
|
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
204
|
+
COPY_PHASE_STRIP = YES;
|
|
205
|
+
ENABLE_NS_ASSERTIONS = NO;
|
|
206
|
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
207
|
+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
208
|
+
"EXCLUDED_ARCHS[sdk=*]" = arm64;
|
|
209
|
+
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
210
|
+
GCC_NO_COMMON_BLOCKS = YES;
|
|
211
|
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
212
|
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
213
|
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
214
|
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
215
|
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
216
|
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
217
|
+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
|
218
|
+
MTL_ENABLE_DEBUG_INFO = NO;
|
|
219
|
+
SDKROOT = iphoneos;
|
|
220
|
+
VALIDATE_PRODUCT = YES;
|
|
221
|
+
};
|
|
222
|
+
name = Release;
|
|
223
|
+
};
|
|
224
|
+
58B511F01A9E6C8500147676 /* Debug */ = {
|
|
225
|
+
isa = XCBuildConfiguration;
|
|
226
|
+
buildSettings = {
|
|
227
|
+
HEADER_SEARCH_PATHS = (
|
|
228
|
+
"$(inherited)",
|
|
229
|
+
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
|
230
|
+
"$(SRCROOT)/../../../React/**",
|
|
231
|
+
"$(SRCROOT)/../../react-native/React/**",
|
|
232
|
+
);
|
|
233
|
+
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
234
|
+
OTHER_LDFLAGS = "-ObjC";
|
|
235
|
+
PRODUCT_NAME = StreamChatReactNative;
|
|
236
|
+
SKIP_INSTALL = YES;
|
|
237
|
+
};
|
|
238
|
+
name = Debug;
|
|
239
|
+
};
|
|
240
|
+
58B511F11A9E6C8500147676 /* Release */ = {
|
|
241
|
+
isa = XCBuildConfiguration;
|
|
242
|
+
buildSettings = {
|
|
243
|
+
HEADER_SEARCH_PATHS = (
|
|
244
|
+
"$(inherited)",
|
|
245
|
+
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
|
246
|
+
"$(SRCROOT)/../../../React/**",
|
|
247
|
+
"$(SRCROOT)/../../react-native/React/**",
|
|
248
|
+
);
|
|
249
|
+
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
250
|
+
OTHER_LDFLAGS = "-ObjC";
|
|
251
|
+
PRODUCT_NAME = StreamChatReactNative;
|
|
252
|
+
SKIP_INSTALL = YES;
|
|
253
|
+
};
|
|
254
|
+
name = Release;
|
|
255
|
+
};
|
|
256
|
+
/* End XCBuildConfiguration section */
|
|
257
|
+
|
|
258
|
+
/* Begin XCConfigurationList section */
|
|
259
|
+
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "StreamChatReactNative" */ = {
|
|
260
|
+
isa = XCConfigurationList;
|
|
261
|
+
buildConfigurations = (
|
|
262
|
+
58B511ED1A9E6C8500147676 /* Debug */,
|
|
263
|
+
58B511EE1A9E6C8500147676 /* Release */,
|
|
264
|
+
);
|
|
265
|
+
defaultConfigurationIsVisible = 0;
|
|
266
|
+
defaultConfigurationName = Release;
|
|
267
|
+
};
|
|
268
|
+
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "StreamChatReactNative" */ = {
|
|
269
|
+
isa = XCConfigurationList;
|
|
270
|
+
buildConfigurations = (
|
|
271
|
+
58B511F01A9E6C8500147676 /* Debug */,
|
|
272
|
+
58B511F11A9E6C8500147676 /* Release */,
|
|
273
|
+
);
|
|
274
|
+
defaultConfigurationIsVisible = 0;
|
|
275
|
+
defaultConfigurationName = Release;
|
|
276
|
+
};
|
|
277
|
+
/* End XCConfigurationList section */
|
|
278
|
+
};
|
|
279
|
+
rootObject = 58B511D31A9E6C8500147676 /* Project object */;
|
|
280
|
+
}
|