@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.
@@ -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
+ }