react-native-ux-cam 5.4.16 → 6.0.0
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/CHANGELOG.md +1 -0
- package/RNUxcam.podspec +21 -2
- package/android/build.gradle +38 -4
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/android/gradlew +240 -0
- package/android/gradlew.bat +91 -0
- package/android/src/main/java/com/uxcam/RNUxViewFinder.java +7 -0
- package/android/src/main/java/com/uxcam/RNUxcamModuleImpl.java +446 -0
- package/android/src/main/java/com/uxcam/RNUxcamPackage.java +33 -18
- package/android/src/newarch/java/com/uxcam/RNUxcamModule.java +208 -0
- package/android/src/oldarch/java/com/uxcam/RNUxcamModule.java +205 -0
- package/ios/RNUxcam/RNUxcam.h +16 -0
- package/ios/RNUxcam/RNUxcam.mm +526 -0
- package/package.json +36 -32
- package/src/NativeRNUxcam.ts +60 -0
- package/src/UXCam.js +343 -0
- package/src/UXCamOcclusion.tsx +29 -0
- package/{index.d.ts → src/index.d.ts} +9 -130
- package/src/index.js +3 -0
- package/src/types.ts +19 -0
- package/UXCam.js +0 -570
- package/UXCamOcclusion.tsx +0 -36
- package/android/.classpath +0 -6
- package/android/src/main/java/com/uxcam/RNUxcamModule.java +0 -559
- package/index.js +0 -3
- package/ios/RNUxcam.h +0 -19
- package/ios/RNUxcam.m +0 -670
- package/ios/RNUxcam.xcodeproj/project.pbxproj +0 -266
- package/ios/RNUxcam.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/ios/RNUxcam.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- /package/{jest.config.js → src/jest.config.js} +0 -0
- /package/{tsconfig.json → src/tsconfig.json} +0 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
#import "RNUxcam.h"
|
|
2
|
+
#import <UXCam/UXCam.h>
|
|
3
|
+
#import <UXCam/UXCamConfiguration.h>
|
|
4
|
+
#import <UXCam/UXOcclusionHeaders.h>
|
|
5
|
+
#import <React/RCTUIManager.h>
|
|
6
|
+
#import <React/RCTUIManagerUtils.h>
|
|
7
|
+
#import <React/RCTConvert.h>
|
|
8
|
+
|
|
9
|
+
// Thanks to this guard, we won't import this header when we build for the old architecture.
|
|
10
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
11
|
+
#import "RNUxcamSpec.h"
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
static NSString* const RNUxcam_VerifyEvent_Name = @"UXCam_Verification_Event";
|
|
15
|
+
|
|
16
|
+
// Configuration Keys
|
|
17
|
+
static NSString* const RNUxcam_AppKey = @"userAppKey";
|
|
18
|
+
static NSString* const RNUxcam_MultiSession = @"enableMultiSessionRecord";
|
|
19
|
+
static NSString* const RNUxcam_CrashHandling = @"enableCrashHandling";
|
|
20
|
+
static NSString* const RNUxcam_ScreenTag = @"enableAutomaticScreenNameTagging";
|
|
21
|
+
static NSString* const RNUxcam_AdvancedGestures = @"enableAdvancedGestureRecognition";
|
|
22
|
+
static NSString* const RNUxcam_EnableNetworkLogs = @"enableNetworkLogging";
|
|
23
|
+
|
|
24
|
+
static NSString* const RNUxcam_Occlusion = @"occlusions";
|
|
25
|
+
static NSString* const RNUxcam_OccludeScreens = @"screens";
|
|
26
|
+
static NSString* const RNUxcam_ExcludeScreens = @"excludeMentionedScreens";
|
|
27
|
+
static NSString* const RNUxcam_OcclusionType = @"type";
|
|
28
|
+
static NSString* const RNUxcam_BlurName = @"name";
|
|
29
|
+
static NSString* const RNUxcam_BlurRadius = @"blurRadius";
|
|
30
|
+
static NSString* const RNUxcam_HideGestures = @"hideGestures";
|
|
31
|
+
static NSString* const RNUxcam_OverlayColor = @"color";
|
|
32
|
+
|
|
33
|
+
static NSString* const RNUxcam_PluginType = @"react-native";
|
|
34
|
+
static NSString* const RNUxcam_PluginVersion = @"6.0.0";
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@interface RNUxcam ()
|
|
38
|
+
@property (atomic, strong) NSNumber* lastVerifyResult;
|
|
39
|
+
@property (atomic, assign) NSInteger numEventListeners;
|
|
40
|
+
@end
|
|
41
|
+
|
|
42
|
+
@implementation RNUxcam
|
|
43
|
+
|
|
44
|
+
RCT_EXPORT_MODULE();
|
|
45
|
+
|
|
46
|
+
@synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED;
|
|
47
|
+
|
|
48
|
+
/// TODO: Investigate if we can remove this and run on a general background Q
|
|
49
|
+
- (dispatch_queue_t)methodQueue
|
|
50
|
+
{
|
|
51
|
+
return dispatch_get_main_queue();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
+ (BOOL)requiresMainQueueSetup
|
|
55
|
+
{
|
|
56
|
+
return YES;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#pragma mark The main entry point - start the UXCam system with the provided configuration
|
|
60
|
+
RCT_EXPORT_METHOD(startWithConfiguration:(NSDictionary *)config)
|
|
61
|
+
{
|
|
62
|
+
self.lastVerifyResult = nil;
|
|
63
|
+
[UXCam pluginType:RNUxcam_PluginType version:RNUxcam_PluginVersion];
|
|
64
|
+
|
|
65
|
+
NSString *userAppKey = config[RNUxcam_AppKey];
|
|
66
|
+
if (!userAppKey || ![userAppKey isKindOfClass:NSString.class])
|
|
67
|
+
{
|
|
68
|
+
[self verifyEventSender:NO];
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
UXCamConfiguration *configuration = [[UXCamConfiguration alloc] initWithAppKey:userAppKey];
|
|
72
|
+
[self updateConfiguration:configuration fromDict:config];
|
|
73
|
+
[UXCam startWithConfiguration:configuration completionBlock:^(BOOL started)
|
|
74
|
+
{
|
|
75
|
+
self.lastVerifyResult = @(started);
|
|
76
|
+
}
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
RCT_EXPORT_METHOD(configurationForUXCam:(RCTPromiseResolveBlock)resolve
|
|
81
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
82
|
+
{
|
|
83
|
+
UXCamConfiguration *configuration = UXCam.configuration;
|
|
84
|
+
|
|
85
|
+
if (configuration)
|
|
86
|
+
{
|
|
87
|
+
NSDictionary *configDict = @{
|
|
88
|
+
RNUxcam_AppKey: configuration.userAppKey,
|
|
89
|
+
RNUxcam_MultiSession: @(configuration.enableMultiSessionRecord),
|
|
90
|
+
RNUxcam_CrashHandling: @(configuration.enableCrashHandling),
|
|
91
|
+
RNUxcam_ScreenTag: @(configuration.enableAutomaticScreenNameTagging),
|
|
92
|
+
RNUxcam_AdvancedGestures: @(configuration.enableAdvancedGestureRecognition),
|
|
93
|
+
RNUxcam_EnableNetworkLogs: @(configuration.enableNetworkLogging)
|
|
94
|
+
};
|
|
95
|
+
resolve(configDict);
|
|
96
|
+
}
|
|
97
|
+
else
|
|
98
|
+
{
|
|
99
|
+
NSString *code = @"no_configuration";
|
|
100
|
+
NSString *message = @"Please start UXCam with startWithConfiguration first to get configuration";
|
|
101
|
+
NSError *error = [NSError errorWithDomain:@"RNUXCam" code:1 userInfo:@{NSLocalizedDescriptionKey : message}];
|
|
102
|
+
|
|
103
|
+
reject(code, message, error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
RCT_EXPORT_METHOD(updateConfiguration:(NSDictionary *)config)
|
|
108
|
+
{
|
|
109
|
+
UXCamConfiguration *configuration = UXCam.configuration;
|
|
110
|
+
if (!configuration)
|
|
111
|
+
{
|
|
112
|
+
NSLog(@"Please start UXCam with startWithConfiguration first before updating configuration");
|
|
113
|
+
return;
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
[self updateConfiguration:configuration fromDict:config];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
- (void)updateConfiguration:(UXCamConfiguration *)configuration fromDict:(NSDictionary *)config
|
|
120
|
+
{
|
|
121
|
+
NSNumber *enableMultiSessionRecord = config[RNUxcam_MultiSession];
|
|
122
|
+
if (enableMultiSessionRecord)
|
|
123
|
+
{
|
|
124
|
+
configuration.enableMultiSessionRecord = [RCTConvert BOOL:enableMultiSessionRecord];
|
|
125
|
+
}
|
|
126
|
+
NSNumber *enableCrashHandling = config[RNUxcam_CrashHandling];
|
|
127
|
+
if (enableCrashHandling)
|
|
128
|
+
{
|
|
129
|
+
configuration.enableCrashHandling = [RCTConvert BOOL:enableCrashHandling];
|
|
130
|
+
}
|
|
131
|
+
NSNumber *enableAutomaticScreenNameTagging = config[RNUxcam_ScreenTag];
|
|
132
|
+
if (enableAutomaticScreenNameTagging)
|
|
133
|
+
{
|
|
134
|
+
configuration.enableAutomaticScreenNameTagging = [RCTConvert BOOL:enableAutomaticScreenNameTagging];
|
|
135
|
+
}
|
|
136
|
+
NSNumber *enableAdvancedGestureRecognition = config[RNUxcam_AdvancedGestures];
|
|
137
|
+
if (enableAdvancedGestureRecognition)
|
|
138
|
+
{
|
|
139
|
+
configuration.enableAdvancedGestureRecognition = [RCTConvert BOOL:enableAdvancedGestureRecognition];
|
|
140
|
+
}
|
|
141
|
+
NSNumber *enableNetworkLogging = config[RNUxcam_EnableNetworkLogs];
|
|
142
|
+
if (enableNetworkLogging)
|
|
143
|
+
{
|
|
144
|
+
configuration.enableNetworkLogging = [RCTConvert BOOL:enableNetworkLogging];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
NSArray *occlusionList = config[RNUxcam_Occlusion];
|
|
148
|
+
if (occlusionList && ![occlusionList isKindOfClass:NSNull.class]) {
|
|
149
|
+
UXCamOcclusion *occlusion = [[UXCamOcclusion alloc] init];
|
|
150
|
+
for (NSDictionary *occlusionJson in occlusionList) {
|
|
151
|
+
id <UXCamOcclusionSetting> setting = [self getOcclusionSettingFromJson:occlusionJson];
|
|
152
|
+
if (setting)
|
|
153
|
+
{
|
|
154
|
+
NSArray *screens = [RCTConvert NSArray:occlusionJson[RNUxcam_OccludeScreens]];
|
|
155
|
+
BOOL excludeMentionedScreens = [RCTConvert BOOL:occlusionJson[RNUxcam_ExcludeScreens]];
|
|
156
|
+
[occlusion applySettings:@[setting] screens:screens excludeMentionedScreens: excludeMentionedScreens];
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
configuration.occlusion = occlusion;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
- (id<UXCamOcclusionSetting>)getOcclusionSettingFromJson:(NSDictionary *)json
|
|
164
|
+
{
|
|
165
|
+
NSNumber *type = [RCTConvert NSNumber:json[RNUxcam_OcclusionType]];
|
|
166
|
+
UXOcclusionType occlusionType = static_cast<UXOcclusionType>(type.integerValue ?: 3);
|
|
167
|
+
|
|
168
|
+
switch (occlusionType) {
|
|
169
|
+
case UXOcclusionTypeBlur:
|
|
170
|
+
{
|
|
171
|
+
NSString *name = [RCTConvert NSString:json[RNUxcam_BlurName]];
|
|
172
|
+
UXBlurType blurType = [UXCamOcclusion getBlurTypeFromName:name];
|
|
173
|
+
NSNumber *radiusValue = [RCTConvert NSNumber:json[RNUxcam_BlurRadius]];
|
|
174
|
+
int radius = radiusValue.intValue ?: 10;
|
|
175
|
+
UXCamBlurSetting *blur = [[UXCamBlurSetting alloc] initWithBlurType:blurType radius:radius];
|
|
176
|
+
NSNumber *hideGestures = [RCTConvert NSNumber:json[RNUxcam_HideGestures]];
|
|
177
|
+
if (hideGestures) {
|
|
178
|
+
blur.hideGestures = hideGestures.boolValue;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return blur;
|
|
182
|
+
}
|
|
183
|
+
case UXOcclusionTypeOverlay:
|
|
184
|
+
{
|
|
185
|
+
UXCamOverlaySetting *overlay = [[UXCamOverlaySetting alloc] init];
|
|
186
|
+
NSNumber *colorCode = [RCTConvert NSNumber:json[RNUxcam_OverlayColor]];
|
|
187
|
+
if (colorCode)
|
|
188
|
+
{
|
|
189
|
+
int colorValue = colorCode.intValue;
|
|
190
|
+
float redValue = (colorValue >> 16 & 0xff) / 0xff;
|
|
191
|
+
float greenValue = (colorValue >> 8 & 0xff) / 0xff;
|
|
192
|
+
float blueValue = (colorValue & 0xff) / 0xff;
|
|
193
|
+
|
|
194
|
+
UIColor *color = [UIColor colorWithRed:redValue green:greenValue blue:blueValue alpha: 1];
|
|
195
|
+
overlay.color = color;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
NSNumber *hideGestures = [RCTConvert NSNumber:json[RNUxcam_HideGestures]];
|
|
199
|
+
if (hideGestures) {
|
|
200
|
+
overlay.hideGestures = hideGestures.boolValue;
|
|
201
|
+
}
|
|
202
|
+
return overlay;
|
|
203
|
+
}
|
|
204
|
+
case UXOcclusionTypeOccludeAllTextFields:
|
|
205
|
+
{
|
|
206
|
+
UXCamOccludeAllTextFields *occlude = [[UXCamOccludeAllTextFields alloc] init];
|
|
207
|
+
return occlude;
|
|
208
|
+
}
|
|
209
|
+
default:
|
|
210
|
+
return nil;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
RCT_EXPORT_METHOD(applyOcclusion:(NSDictionary *)occlusion)
|
|
215
|
+
{
|
|
216
|
+
if (occlusion && ![occlusion isKindOfClass:NSNull.class]) {
|
|
217
|
+
id <UXCamOcclusionSetting> setting = [self getOcclusionSettingFromJson:occlusion];
|
|
218
|
+
if (setting)
|
|
219
|
+
{
|
|
220
|
+
[UXCam applyOcclusion:setting];
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
RCT_EXPORT_METHOD(removeOcclusion:(NSDictionary *)occlusion)
|
|
226
|
+
{
|
|
227
|
+
if (occlusion && ![occlusion isKindOfClass:NSNull.class]) {
|
|
228
|
+
id <UXCamOcclusionSetting> setting = [self getOcclusionSettingFromJson:occlusion];
|
|
229
|
+
if (setting)
|
|
230
|
+
{
|
|
231
|
+
[UXCam removeOcclusionOfType:setting.type];
|
|
232
|
+
}
|
|
233
|
+
else
|
|
234
|
+
{
|
|
235
|
+
[UXCam removeOcclusion];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
#pragma mark Event related methods
|
|
241
|
+
- (NSArray<NSString *> *)supportedEvents
|
|
242
|
+
{
|
|
243
|
+
return @[RNUxcam_VerifyEvent_Name];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/// Will be called when this module's first listener is added.
|
|
247
|
+
-(void)startObserving
|
|
248
|
+
{
|
|
249
|
+
// Set up any upstream listeners or background tasks as necessary
|
|
250
|
+
if (self.numEventListeners == 0)
|
|
251
|
+
{
|
|
252
|
+
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addObserverForVerificationNotification:) name:RNUxcam_VerifyEvent_Name object:nil];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
self.numEventListeners++;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/// Will be called when this module's last listener is removed, or on dealloc.
|
|
259
|
+
-(void)stopObserving
|
|
260
|
+
{
|
|
261
|
+
self.numEventListeners--;
|
|
262
|
+
if (self.numEventListeners == 0)
|
|
263
|
+
{
|
|
264
|
+
[[NSNotificationCenter defaultCenter] removeObserver:self name:RNUxcam_VerifyEvent_Name object:nil];
|
|
265
|
+
}
|
|
266
|
+
else if (self.numEventListeners < 0)
|
|
267
|
+
{
|
|
268
|
+
NSLog(@"RNUxcam: Removed more event listeners than were added.");
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
- (void)addObserverForVerificationNotification:(NSNotification *)notification
|
|
273
|
+
{
|
|
274
|
+
if (![notification.name isEqualToString:RNUxcam_VerifyEvent_Name])
|
|
275
|
+
{
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
BOOL started = [notification.userInfo[@"started"] boolValue];
|
|
279
|
+
[self verifyEventSender:started];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
- (void)verifyEventSender:(BOOL)verifyResult
|
|
283
|
+
{
|
|
284
|
+
if (self.numEventListeners > 0)
|
|
285
|
+
{
|
|
286
|
+
NSDictionary* eventBody = @{@"success": @(verifyResult)};
|
|
287
|
+
if (verifyResult == FALSE)
|
|
288
|
+
{
|
|
289
|
+
NSString *message = @"UXCam session verification failed"; /// TODO: Localise
|
|
290
|
+
NSError *error = [NSError errorWithDomain:@"RNUXCam" code:1 userInfo:@{NSLocalizedDescriptionKey : message}];
|
|
291
|
+
|
|
292
|
+
eventBody = @{@"success": @(verifyResult), @"error": error};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
[self sendEventWithName:RNUxcam_VerifyEvent_Name body:eventBody];
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
RCT_EXPORT_METHOD(occludeAllTextFields:(BOOL)occludeAll)
|
|
300
|
+
{
|
|
301
|
+
[UXCam occludeAllTextFields:occludeAll];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
RCT_EXPORT_METHOD(occludeSensitiveScreen:(BOOL)hideScreen hideGestures:(BOOL)hideGestures)
|
|
305
|
+
{
|
|
306
|
+
[UXCam occludeSensitiveScreen:hideScreen hideGestures:hideGestures];
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
RCT_EXPORT_METHOD(occludeSensitiveView:(double)tag hideGestures:(BOOL)hideGestures)
|
|
310
|
+
{
|
|
311
|
+
RCTExecuteOnUIManagerQueue(^{
|
|
312
|
+
[self->_viewRegistry_DEPRECATED addUIBlock:^(RCTViewRegistry *viewRegistry) {
|
|
313
|
+
RCTExecuteOnMainQueue(^{
|
|
314
|
+
UIView *view = [self->_viewRegistry_DEPRECATED viewForReactTag:@(tag)];
|
|
315
|
+
// Temporary fix for handling null views in new architecture mode until this is fully migrated to shadow nodes
|
|
316
|
+
if (![self isViewAvailableAndAttachedToSuperView:view]) {
|
|
317
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
|
318
|
+
UIView *view = [self->_viewRegistry_DEPRECATED viewForReactTag:@(tag)];
|
|
319
|
+
if ([self isViewAvailableAndAttachedToSuperView:view]) {
|
|
320
|
+
[self occludeView:view hideGesture:hideGestures];
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
} else {
|
|
324
|
+
[self occludeView:view hideGesture:hideGestures];
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}];
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
- (BOOL)isViewAvailableAndAttachedToSuperView:(UIView *)view {
|
|
333
|
+
return view != nil && view.superview != nil;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
- (void)occludeView:(UIView *)view hideGesture:(BOOL)hideGesture {
|
|
337
|
+
if (hideGesture) {
|
|
338
|
+
[UXCam occludeSensitiveViewWithoutGesture:view];
|
|
339
|
+
} else {
|
|
340
|
+
[UXCam occludeSensitiveView:view];
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
RCT_EXPORT_METHOD(unOccludeSensitiveView:(double)tag)
|
|
345
|
+
{
|
|
346
|
+
UIView *view = [_viewRegistry_DEPRECATED viewForReactTag:@(tag)];
|
|
347
|
+
if (view) {
|
|
348
|
+
[UXCam unOccludeSensitiveView:view];
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
RCT_EXPORT_METHOD(optInOverall)
|
|
353
|
+
{
|
|
354
|
+
[UXCam optInOverall];
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
RCT_EXPORT_METHOD(optOutOverall)
|
|
358
|
+
{
|
|
359
|
+
[UXCam optOutOverall];
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, optInOverallStatus)
|
|
363
|
+
{
|
|
364
|
+
return @(UXCam.optInOverallStatus);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
RCT_EXPORT_METHOD(optIntoSchematicRecordings)
|
|
368
|
+
{
|
|
369
|
+
[UXCam optIntoSchematicRecordings];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
RCT_EXPORT_METHOD(optOutOfSchematicRecordings)
|
|
373
|
+
{
|
|
374
|
+
[UXCam optOutOfSchematicRecordings];
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, optInSchematicRecordingStatus)
|
|
378
|
+
{
|
|
379
|
+
return @(UXCam.optInSchematicRecordingStatus);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
RCT_EXPORT_METHOD(optIntoVideoRecording)
|
|
383
|
+
{
|
|
384
|
+
// fallback to schematic recording
|
|
385
|
+
[UXCam optIntoSchematicRecordings];
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
RCT_EXPORT_METHOD(optOutOfVideoRecording)
|
|
389
|
+
{
|
|
390
|
+
[UXCam optOutOfSchematicRecordings];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, optInVideoRecordingStatus)
|
|
394
|
+
{
|
|
395
|
+
return @(UXCam.optInSchematicRecordingStatus);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
RCT_EXPORT_METHOD(startNewSession)
|
|
399
|
+
{
|
|
400
|
+
[UXCam startNewSession];
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
RCT_EXPORT_METHOD(stopSessionAndUploadData)
|
|
404
|
+
{
|
|
405
|
+
[UXCam stopSessionAndUploadData];
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
RCT_EXPORT_METHOD(cancelCurrentSession)
|
|
409
|
+
{
|
|
410
|
+
[UXCam cancelCurrentSession];
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
RCT_EXPORT_METHOD(urlForCurrentSession:(RCTPromiseResolveBlock)resolve
|
|
414
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
415
|
+
{
|
|
416
|
+
NSString *url = [UXCam urlForCurrentSession];
|
|
417
|
+
|
|
418
|
+
if (url)
|
|
419
|
+
{
|
|
420
|
+
resolve(url);
|
|
421
|
+
}
|
|
422
|
+
else
|
|
423
|
+
{
|
|
424
|
+
NSString *code = @"no_url";
|
|
425
|
+
NSString *message = @"Could not retrieve the url for the current session.";
|
|
426
|
+
NSError *error = [NSError errorWithDomain:@"RNUXCam" code:2 userInfo:nil];
|
|
427
|
+
|
|
428
|
+
reject(code, message, error);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
RCT_EXPORT_METHOD(urlForCurrentUser:(RCTPromiseResolveBlock)resolve
|
|
433
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
434
|
+
{
|
|
435
|
+
NSString *url = [UXCam urlForCurrentUser];
|
|
436
|
+
|
|
437
|
+
if (url)
|
|
438
|
+
{
|
|
439
|
+
resolve(url);
|
|
440
|
+
}
|
|
441
|
+
else
|
|
442
|
+
{
|
|
443
|
+
NSString *code = @"no_url";
|
|
444
|
+
NSString *message = @"Could not retrieve the url for the current user.";
|
|
445
|
+
NSError *error = [NSError errorWithDomain:@"RNUXCam" code:1 userInfo:nil];
|
|
446
|
+
|
|
447
|
+
reject(code, message, error);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
RCT_EXPORT_METHOD(uploadPendingSession)
|
|
452
|
+
{
|
|
453
|
+
[UXCam uploadingPendingSessions:nil];
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, pendingSessionCount)
|
|
457
|
+
{
|
|
458
|
+
return @(UXCam.pendingUploads);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
RCT_EXPORT_METHOD(deletePendingUploads)
|
|
462
|
+
{
|
|
463
|
+
[UXCam deletePendingUploads];
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
RCT_EXPORT_METHOD(allowShortBreakForAnotherApp:(BOOL)continueSession)
|
|
467
|
+
{
|
|
468
|
+
[UXCam allowShortBreakForAnotherApp:continueSession];
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
RCT_EXPORT_METHOD(allowShortBreakForAnotherAppInMillis:(double)duration)
|
|
472
|
+
{
|
|
473
|
+
[UXCam allowShortBreakForAnotherApp:YES];
|
|
474
|
+
[UXCam setAllowShortBreakMaxDuration:duration];
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, isRecording)
|
|
478
|
+
{
|
|
479
|
+
return @(UXCam.isRecording);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
RCT_EXPORT_METHOD(pauseScreenRecording)
|
|
483
|
+
{
|
|
484
|
+
[UXCam pauseScreenRecording];
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
RCT_EXPORT_METHOD(resumeScreenRecording)
|
|
488
|
+
{
|
|
489
|
+
[UXCam resumeScreenRecording];
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
RCT_EXPORT_METHOD(tagScreenName:(NSString *)screenName)
|
|
493
|
+
{
|
|
494
|
+
[UXCam tagScreenName:screenName];
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
RCT_EXPORT_METHOD(logEvent:(NSString *)eventName properties:(nullable NSDictionary<NSString *, id> *)properties)
|
|
498
|
+
{
|
|
499
|
+
[UXCam logEvent:eventName withProperties:properties];
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
RCT_EXPORT_METHOD(setUserIdentity:(NSString *)userIdentity)
|
|
503
|
+
{
|
|
504
|
+
[UXCam setUserIdentity:userIdentity];
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
RCT_EXPORT_METHOD(setUserProperty:(NSString *)propertyName value:(NSString *)value)
|
|
508
|
+
{
|
|
509
|
+
[UXCam setUserProperty:propertyName value:value];
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
RCT_EXPORT_METHOD(setSessionProperty:(NSString *)propertyName value:(NSString *)value)
|
|
513
|
+
{
|
|
514
|
+
[UXCam setSessionProperty:propertyName value:value];
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Thanks to this guard, we won't compile this code when we build for the old architecture.
|
|
518
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
519
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
520
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
521
|
+
{
|
|
522
|
+
return std::make_shared<facebook::react::NativeRNUxcamSpecJSI>(params);
|
|
523
|
+
}
|
|
524
|
+
#endif
|
|
525
|
+
|
|
526
|
+
@end
|
package/package.json
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"ux-cam"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
2
|
+
"name": "react-native-ux-cam",
|
|
3
|
+
"version": "6.0.0",
|
|
4
|
+
"description": "React Native wrapper for uxcam.com.",
|
|
5
|
+
"react-native": "src/index",
|
|
6
|
+
"main": "src/index",
|
|
7
|
+
"source": "src/index",
|
|
8
|
+
"types": "src/index.d.ts",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"react-native",
|
|
11
|
+
"android",
|
|
12
|
+
"ios",
|
|
13
|
+
"react-native",
|
|
14
|
+
"user-sessions",
|
|
15
|
+
"ux",
|
|
16
|
+
"uxcam",
|
|
17
|
+
"ux-cam"
|
|
18
|
+
],
|
|
19
|
+
"repository": "https://github.com/uxcam/react-native-ux-cam",
|
|
20
|
+
"author": "admin@uxcam.com",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"homepage": "https://github.com/uxcam/react-native-ux-cam",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/jest": "^27.5.0",
|
|
25
|
+
"@types/react": "^18.0.8",
|
|
26
|
+
"@types/react-native": "^0.67.6",
|
|
27
|
+
"@types/react-test-renderer": "^18.0.0",
|
|
28
|
+
"typescript": "^4.6.4"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react-native": ">=0.60.0"
|
|
32
|
+
},
|
|
33
|
+
"codegenConfig": {
|
|
34
|
+
"name": "RNUxcamSpec",
|
|
35
|
+
"type": "all",
|
|
36
|
+
"jsSrcsDir": "src"
|
|
37
|
+
}
|
|
34
38
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
3
|
+
import { Configuration } from './types';
|
|
4
|
+
|
|
5
|
+
export interface Spec extends TurboModule {
|
|
6
|
+
startWithConfiguration: (configuration: Object) => void;
|
|
7
|
+
|
|
8
|
+
optInOverall: () => void;
|
|
9
|
+
optOutOverall: () => void;
|
|
10
|
+
optIntoSchematicRecordings: () => void;
|
|
11
|
+
optOutOfSchematicRecordings: () => void;
|
|
12
|
+
optInOverallStatus: () => boolean;
|
|
13
|
+
optInSchematicRecordingStatus: () => boolean;
|
|
14
|
+
optIntoVideoRecording: () => void;
|
|
15
|
+
optOutOfVideoRecording: () => void;
|
|
16
|
+
optInVideoRecordingStatus: () => boolean;
|
|
17
|
+
|
|
18
|
+
startNewSession: () => void;
|
|
19
|
+
stopSessionAndUploadData: () => void;
|
|
20
|
+
cancelCurrentSession: () => void;
|
|
21
|
+
|
|
22
|
+
urlForCurrentSession: () => Promise<string | undefined | null>;
|
|
23
|
+
urlForCurrentUser: () => Promise<string | undefined | null>;
|
|
24
|
+
|
|
25
|
+
uploadPendingSession: () => void;
|
|
26
|
+
pendingSessionCount: () => number;
|
|
27
|
+
deletePendingUploads: () => void;
|
|
28
|
+
|
|
29
|
+
allowShortBreakForAnotherApp: (continueSession: boolean) => void;
|
|
30
|
+
allowShortBreakForAnotherAppInMillis: (duration: number) => void;
|
|
31
|
+
|
|
32
|
+
isRecording: () => boolean;
|
|
33
|
+
pauseScreenRecording: () => void;
|
|
34
|
+
resumeScreenRecording: () => void;
|
|
35
|
+
|
|
36
|
+
tagScreenName: (screenName: string) => void;
|
|
37
|
+
|
|
38
|
+
logEvent: (eventName: string, properties?: Object) => void;
|
|
39
|
+
setUserIdentity: (userIdentity: string) => void;
|
|
40
|
+
|
|
41
|
+
// Here value should be either number | string but as union types are not officially supported, we pass value as string
|
|
42
|
+
setUserProperty: (propertyName: string, value: string) => void;
|
|
43
|
+
setSessionProperty: (propertyName: string, value: string) => void;
|
|
44
|
+
|
|
45
|
+
// Occlusion APIs
|
|
46
|
+
occludeAllTextFields: (occludeAll: boolean) => void;
|
|
47
|
+
occludeSensitiveScreen: (hideScreen: boolean, hideGestures: boolean) => void;
|
|
48
|
+
occludeSensitiveView: (tag: number, hideGestures: boolean) => void;
|
|
49
|
+
unOccludeSensitiveView: (tag: number) => void;
|
|
50
|
+
|
|
51
|
+
applyOcclusion: (occlusion: Object) => void;
|
|
52
|
+
removeOcclusion: (occlusion: Object) => void;
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
// Event Listeneres
|
|
56
|
+
addListener: (eventType: string) => void;
|
|
57
|
+
removeListeners: (count: number) => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('RNUxcam');
|