@regantis-sdk/react-native-chat 0.1.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/README.md +157 -0
- package/RegantisReactNativeChat.podspec +17 -0
- package/android/build.gradle +24 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/technology/regantis/chat/RegantisChatNativeModule.java +244 -0
- package/android/src/main/java/technology/regantis/chat/RegantisChatPackage.java +28 -0
- package/index.d.ts +91 -0
- package/index.js +10 -0
- package/ios/RegantisChatNative.h +5 -0
- package/ios/RegantisChatNative.m +191 -0
- package/package.json +35 -0
- package/src/RegantisChat.js +539 -0
- package/src/client.js +630 -0
- package/src/defaults.js +43 -0
- package/src/native.js +56 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#import "RegantisChatNative.h"
|
|
2
|
+
#import <AudioToolbox/AudioToolbox.h>
|
|
3
|
+
#import <React/RCTUtils.h>
|
|
4
|
+
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
|
5
|
+
|
|
6
|
+
@interface RegantisChatNative ()
|
|
7
|
+
@property (nonatomic, copy) RCTPromiseResolveBlock pickerResolve;
|
|
8
|
+
@property (nonatomic, copy) RCTPromiseRejectBlock pickerReject;
|
|
9
|
+
@end
|
|
10
|
+
|
|
11
|
+
@implementation RegantisChatNative
|
|
12
|
+
|
|
13
|
+
RCT_EXPORT_MODULE(RegantisChatNative)
|
|
14
|
+
|
|
15
|
+
+ (BOOL)requiresMainQueueSetup
|
|
16
|
+
{
|
|
17
|
+
return NO;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
- (NSString *)storageKey:(NSString *)key
|
|
21
|
+
{
|
|
22
|
+
return [@"regantis_chat_" stringByAppendingString:key ?: @""];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
RCT_REMAP_METHOD(getItem,
|
|
26
|
+
getItem:(NSString *)key
|
|
27
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
28
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
29
|
+
{
|
|
30
|
+
resolve([[NSUserDefaults standardUserDefaults] stringForKey:[self storageKey:key]]);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
RCT_REMAP_METHOD(setItem,
|
|
34
|
+
setItem:(NSString *)key
|
|
35
|
+
value:(NSString *)value
|
|
36
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
37
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
38
|
+
{
|
|
39
|
+
[[NSUserDefaults standardUserDefaults] setObject:value ?: @"" forKey:[self storageKey:key]];
|
|
40
|
+
resolve(nil);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
RCT_REMAP_METHOD(removeItem,
|
|
44
|
+
removeItem:(NSString *)key
|
|
45
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
46
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
47
|
+
{
|
|
48
|
+
[[NSUserDefaults standardUserDefaults] removeObjectForKey:[self storageKey:key]];
|
|
49
|
+
resolve(nil);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
RCT_REMAP_METHOD(getAppInfo,
|
|
53
|
+
getAppInfoWithResolver:(RCTPromiseResolveBlock)resolve
|
|
54
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
55
|
+
{
|
|
56
|
+
NSBundle *bundle = [NSBundle mainBundle];
|
|
57
|
+
resolve(@{
|
|
58
|
+
@"appId": bundle.bundleIdentifier ?: @"",
|
|
59
|
+
@"appVersion": [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"] ?: @"",
|
|
60
|
+
@"platform": @"ios"
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
RCT_EXPORT_METHOD(playIncomingSound)
|
|
65
|
+
{
|
|
66
|
+
AudioServicesPlaySystemSound(1007);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
RCT_REMAP_METHOD(captureScreenshot,
|
|
70
|
+
captureScreenshotWithResolver:(RCTPromiseResolveBlock)resolve
|
|
71
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
72
|
+
{
|
|
73
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
74
|
+
UIViewController *controller = RCTPresentedViewController();
|
|
75
|
+
UIWindow *window = controller.view.window ?: UIApplication.sharedApplication.keyWindow;
|
|
76
|
+
if (window == nil) {
|
|
77
|
+
reject(@"SCREENSHOT_FAILED", @"No active iOS window", nil);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithBounds:window.bounds];
|
|
82
|
+
UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
|
|
83
|
+
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
|
|
84
|
+
}];
|
|
85
|
+
NSData *data = UIImagePNGRepresentation(image);
|
|
86
|
+
if (data == nil) {
|
|
87
|
+
reject(@"SCREENSHOT_FAILED", @"Unable to encode screenshot", nil);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
NSString *filename = [NSString stringWithFormat:@"screenshot-%lld.png", (long long)(NSDate.date.timeIntervalSince1970 * 1000.0)];
|
|
92
|
+
NSString *directory = [NSTemporaryDirectory() stringByAppendingPathComponent:@"regantis-chat"];
|
|
93
|
+
NSError *directoryError = nil;
|
|
94
|
+
[[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&directoryError];
|
|
95
|
+
if (directoryError != nil) {
|
|
96
|
+
reject(@"SCREENSHOT_FAILED", directoryError.localizedDescription, directoryError);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
NSString *path = [directory stringByAppendingPathComponent:filename];
|
|
101
|
+
NSError *writeError = nil;
|
|
102
|
+
if (![data writeToFile:path options:NSDataWritingAtomic error:&writeError]) {
|
|
103
|
+
reject(@"SCREENSHOT_FAILED", writeError.localizedDescription, writeError);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
resolve(@{
|
|
108
|
+
@"uri": [NSURL fileURLWithPath:path].absoluteString ?: @"",
|
|
109
|
+
@"name": filename,
|
|
110
|
+
@"type": @"image/png",
|
|
111
|
+
@"size": @(data.length)
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
RCT_REMAP_METHOD(pickAttachment,
|
|
117
|
+
pickAttachment:(NSString *)kind
|
|
118
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
119
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
120
|
+
{
|
|
121
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
122
|
+
if (self.pickerResolve != nil) {
|
|
123
|
+
reject(@"PICKER_BUSY", @"An attachment picker is already open", nil);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
NSArray<UTType *> *types = [kind isEqualToString:@"image"]
|
|
128
|
+
? @[UTTypeImage]
|
|
129
|
+
: @[UTTypeContent];
|
|
130
|
+
|
|
131
|
+
UIDocumentPickerViewController *picker = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:types asCopy:YES];
|
|
132
|
+
picker.delegate = self;
|
|
133
|
+
picker.allowsMultipleSelection = NO;
|
|
134
|
+
self.pickerResolve = resolve;
|
|
135
|
+
self.pickerReject = reject;
|
|
136
|
+
|
|
137
|
+
UIViewController *controller = RCTPresentedViewController();
|
|
138
|
+
if (controller == nil) {
|
|
139
|
+
self.pickerResolve = nil;
|
|
140
|
+
self.pickerReject = nil;
|
|
141
|
+
reject(@"NO_VIEW_CONTROLLER", @"No active iOS view controller", nil);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
[controller presentViewController:picker animated:YES completion:nil];
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller
|
|
150
|
+
{
|
|
151
|
+
if (self.pickerResolve) self.pickerResolve(nil);
|
|
152
|
+
self.pickerResolve = nil;
|
|
153
|
+
self.pickerReject = nil;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls
|
|
157
|
+
{
|
|
158
|
+
RCTPromiseResolveBlock resolve = self.pickerResolve;
|
|
159
|
+
RCTPromiseRejectBlock reject = self.pickerReject;
|
|
160
|
+
self.pickerResolve = nil;
|
|
161
|
+
self.pickerReject = nil;
|
|
162
|
+
|
|
163
|
+
NSURL *url = urls.firstObject;
|
|
164
|
+
if (url == nil) {
|
|
165
|
+
if (resolve) resolve(nil);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
NSError *error = nil;
|
|
170
|
+
NSDictionary *values = [url resourceValuesForKeys:@[NSURLNameKey, NSURLFileSizeKey, NSURLContentTypeKey] error:&error];
|
|
171
|
+
if (error != nil && reject) {
|
|
172
|
+
reject(@"PICKER_FILE_ERROR", error.localizedDescription, error);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
NSString *name = values[NSURLNameKey] ?: url.lastPathComponent ?: @"attachment";
|
|
177
|
+
NSNumber *size = values[NSURLFileSizeKey] ?: @0;
|
|
178
|
+
UTType *contentType = values[NSURLContentTypeKey];
|
|
179
|
+
NSString *mimeType = contentType.preferredMIMEType ?: @"application/octet-stream";
|
|
180
|
+
|
|
181
|
+
if (resolve) {
|
|
182
|
+
resolve(@{
|
|
183
|
+
@"uri": url.absoluteString ?: @"",
|
|
184
|
+
@"name": name,
|
|
185
|
+
@"type": mimeType,
|
|
186
|
+
@"size": size
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@end
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@regantis-sdk/react-native-chat",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Regantis customer support chat SDK for React Native Android and iOS",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"react-native": "index.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"index.js",
|
|
10
|
+
"index.d.ts",
|
|
11
|
+
"src",
|
|
12
|
+
"android",
|
|
13
|
+
"ios",
|
|
14
|
+
"RegantisReactNativeChat.podspec",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"react-native",
|
|
19
|
+
"chat",
|
|
20
|
+
"support",
|
|
21
|
+
"customer-service",
|
|
22
|
+
"regantis"
|
|
23
|
+
],
|
|
24
|
+
"license": "UNLICENSED",
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": ">=18.2.0",
|
|
27
|
+
"react-native": ">=0.77.0 <1.0.0"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
}
|
|
35
|
+
}
|