@developer_tribe/react-native-comnyx 0.13.13 → 0.15.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/android/generated/RCTAppDependencyProvider.h +25 -0
- package/android/generated/RCTAppDependencyProvider.mm +55 -0
- package/android/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
- package/android/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
- package/android/generated/RCTThirdPartyComponentsProvider.h +16 -0
- package/android/generated/RCTThirdPartyComponentsProvider.mm +23 -0
- package/android/generated/ReactAppDependencyProvider.podspec +34 -0
- package/android/generated/jni/CMakeLists.txt +36 -0
- package/android/generated/jni/RNComnyxSpec-generated.cpp +22 -0
- package/android/generated/jni/RNComnyxSpec.h +24 -0
- package/android/generated/jni/react/renderer/components/RNComnyxSpec/RNComnyxSpecJSI-generated.cpp +17 -0
- package/android/generated/jni/react/renderer/components/RNComnyxSpec/RNComnyxSpecJSI.h +19 -0
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/AndroidManifestNew.xml +4 -0
- package/android/src/main/java/com/comnyx/ComnyxMediaPickerModule.kt +347 -0
- package/android/src/main/java/com/comnyx/ComnyxPackage.kt +1 -1
- package/android/src/main/java/com/comnyx/VideoPlayerActivity.kt +91 -0
- package/ios/ComnyxMediaPicker.m +29 -0
- package/ios/ComnyxMediaPicker.swift +436 -0
- package/lib/commonjs/NativeComnyxMediaPicker.js +83 -0
- package/lib/commonjs/NativeComnyxMediaPicker.js.map +1 -0
- package/lib/commonjs/api/index.js +19 -0
- package/lib/commonjs/api/index.js.map +1 -1
- package/lib/commonjs/api/media.js +76 -0
- package/lib/commonjs/api/media.js.map +1 -0
- package/lib/commonjs/assets/attachment-01.png +0 -0
- package/lib/commonjs/assets/gallery.png +0 -0
- package/lib/commonjs/assets/video-play.png +0 -0
- package/lib/commonjs/assets/x-circle.png +0 -0
- package/lib/commonjs/components/ChatList.js +48 -22
- package/lib/commonjs/components/ChatList.js.map +1 -1
- package/lib/commonjs/components/LinkifyText.js +5 -1
- package/lib/commonjs/components/LinkifyText.js.map +1 -1
- package/lib/commonjs/components/MediaMessageItem.js +333 -0
- package/lib/commonjs/components/MediaMessageItem.js.map +1 -0
- package/lib/commonjs/components/MediaPickerButton.js +244 -0
- package/lib/commonjs/components/MediaPickerButton.js.map +1 -0
- package/lib/commonjs/components/MediaViewerModal.js +164 -0
- package/lib/commonjs/components/MediaViewerModal.js.map +1 -0
- package/lib/commonjs/components/MessageInput.js +344 -73
- package/lib/commonjs/components/MessageInput.js.map +1 -1
- package/lib/commonjs/components/MessageItem.js +17 -8
- package/lib/commonjs/components/MessageItem.js.map +1 -1
- package/lib/commonjs/constants/translations.js +174 -29
- package/lib/commonjs/constants/translations.js.map +1 -1
- package/lib/commonjs/data/fake/media.js +105 -0
- package/lib/commonjs/data/fake/media.js.map +1 -0
- package/lib/commonjs/types/MediaTypes.js +2 -0
- package/lib/commonjs/types/MediaTypes.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/NativeComnyxMediaPicker.js +73 -0
- package/lib/module/NativeComnyxMediaPicker.js.map +1 -0
- package/lib/module/api/index.js +1 -0
- package/lib/module/api/index.js.map +1 -1
- package/lib/module/api/media.js +70 -0
- package/lib/module/api/media.js.map +1 -0
- package/lib/module/assets/attachment-01.png +0 -0
- package/lib/module/assets/gallery.png +0 -0
- package/lib/module/assets/video-play.png +0 -0
- package/lib/module/assets/x-circle.png +0 -0
- package/lib/module/components/ChatList.js +48 -22
- package/lib/module/components/ChatList.js.map +1 -1
- package/lib/module/components/LinkifyText.js +5 -1
- package/lib/module/components/LinkifyText.js.map +1 -1
- package/lib/module/components/MediaMessageItem.js +330 -0
- package/lib/module/components/MediaMessageItem.js.map +1 -0
- package/lib/module/components/MediaPickerButton.js +240 -0
- package/lib/module/components/MediaPickerButton.js.map +1 -0
- package/lib/module/components/MediaViewerModal.js +160 -0
- package/lib/module/components/MediaViewerModal.js.map +1 -0
- package/lib/module/components/MessageInput.js +347 -75
- package/lib/module/components/MessageInput.js.map +1 -1
- package/lib/module/components/MessageItem.js +17 -8
- package/lib/module/components/MessageItem.js.map +1 -1
- package/lib/module/constants/translations.js +174 -29
- package/lib/module/constants/translations.js.map +1 -1
- package/lib/module/data/fake/media.js +99 -0
- package/lib/module/data/fake/media.js.map +1 -0
- package/lib/module/types/MediaTypes.js +2 -0
- package/lib/module/types/MediaTypes.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/src/NativeComnyxMediaPicker.d.ts +9 -0
- package/lib/typescript/src/NativeComnyxMediaPicker.d.ts.map +1 -0
- package/lib/typescript/src/api/index.d.ts +1 -0
- package/lib/typescript/src/api/index.d.ts.map +1 -1
- package/lib/typescript/src/api/media.d.ts +7 -0
- package/lib/typescript/src/api/media.d.ts.map +1 -0
- package/lib/typescript/src/components/ChatList.d.ts.map +1 -1
- package/lib/typescript/src/components/LinkifyText.d.ts.map +1 -1
- package/lib/typescript/src/components/MediaMessageItem.d.ts +6 -0
- package/lib/typescript/src/components/MediaMessageItem.d.ts.map +1 -0
- package/lib/typescript/src/components/MediaPickerButton.d.ts +5 -0
- package/lib/typescript/src/components/MediaPickerButton.d.ts.map +1 -0
- package/lib/typescript/src/components/MediaViewerModal.d.ts +8 -0
- package/lib/typescript/src/components/MediaViewerModal.d.ts.map +1 -0
- package/lib/typescript/src/components/MessageInput.d.ts.map +1 -1
- package/lib/typescript/src/components/MessageItem.d.ts.map +1 -1
- package/lib/typescript/src/constants/translations.d.ts.map +1 -1
- package/lib/typescript/src/data/fake/media.d.ts +6 -0
- package/lib/typescript/src/data/fake/media.d.ts.map +1 -0
- package/lib/typescript/src/types/Conversation.d.ts +19 -0
- package/lib/typescript/src/types/Conversation.d.ts.map +1 -1
- package/lib/typescript/src/types/LocalizationKeys.d.ts +5 -0
- package/lib/typescript/src/types/LocalizationKeys.d.ts.map +1 -1
- package/lib/typescript/src/types/MediaTypes.d.ts +26 -0
- package/lib/typescript/src/types/MediaTypes.d.ts.map +1 -0
- package/lib/typescript/src/version.d.ts +1 -1
- package/lib/typescript/src/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/NativeComnyxMediaPicker.ts +83 -0
- package/src/api/index.ts +1 -0
- package/src/api/media.ts +116 -0
- package/src/assets/attachment-01.png +0 -0
- package/src/assets/gallery.png +0 -0
- package/src/assets/video-play.png +0 -0
- package/src/assets/x-circle.png +0 -0
- package/src/components/ChatList.tsx +81 -24
- package/src/components/CustomerForm.tsx +1 -1
- package/src/components/LinkifyText.tsx +3 -2
- package/src/components/MediaMessageItem.tsx +390 -0
- package/src/components/MediaPickerButton.tsx +269 -0
- package/src/components/MediaViewerModal.tsx +168 -0
- package/src/components/MessageInput.tsx +396 -84
- package/src/components/MessageItem.tsx +19 -5
- package/src/constants/translations.ts +145 -0
- package/src/data/fake/media.ts +110 -0
- package/src/types/Conversation.ts +20 -0
- package/src/types/LocalizationKeys.ts +5 -0
- package/src/types/MediaTypes.ts +27 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
import PhotosUI
|
|
4
|
+
import AVFoundation
|
|
5
|
+
import AVKit
|
|
6
|
+
import React
|
|
7
|
+
|
|
8
|
+
@objc(ComnyxMediaPicker)
|
|
9
|
+
class ComnyxMediaPicker: NSObject, RCTBridgeModule {
|
|
10
|
+
|
|
11
|
+
static func moduleName() -> String! {
|
|
12
|
+
return "ComnyxMediaPicker"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static func requiresMainQueueSetup() -> Bool {
|
|
16
|
+
return true
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private var resolveBlock: RCTPromiseResolveBlock?
|
|
20
|
+
private var rejectBlock: RCTPromiseRejectBlock?
|
|
21
|
+
|
|
22
|
+
private func rejectPendingPromise() {
|
|
23
|
+
rejectBlock?("CANCELLED", "A new picker request was made before the previous one completed", nil)
|
|
24
|
+
resolveBlock = nil
|
|
25
|
+
rejectBlock = nil
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private func getRootViewController() -> UIViewController? {
|
|
29
|
+
return UIApplication.shared.delegate?.window??.rootViewController?.presentedViewController
|
|
30
|
+
?? UIApplication.shared.delegate?.window??.rootViewController
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
// MARK: - Pick Media (both images and videos)
|
|
35
|
+
|
|
36
|
+
@objc
|
|
37
|
+
func pickMedia(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
38
|
+
rejectPendingPromise()
|
|
39
|
+
self.resolveBlock = resolve
|
|
40
|
+
self.rejectBlock = reject
|
|
41
|
+
|
|
42
|
+
DispatchQueue.main.async {
|
|
43
|
+
if #available(iOS 14.0, *) {
|
|
44
|
+
var config = PHPickerConfiguration()
|
|
45
|
+
config.filter = .any(of: [.images, .videos])
|
|
46
|
+
config.selectionLimit = 0
|
|
47
|
+
let picker = PHPickerViewController(configuration: config)
|
|
48
|
+
picker.delegate = self
|
|
49
|
+
self.getRootViewController()?.present(picker, animated: true)
|
|
50
|
+
} else {
|
|
51
|
+
let picker = UIImagePickerController()
|
|
52
|
+
picker.sourceType = .photoLibrary
|
|
53
|
+
picker.mediaTypes = ["public.image", "public.movie"]
|
|
54
|
+
picker.delegate = self
|
|
55
|
+
self.getRootViewController()?.present(picker, animated: true)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// MARK: - Pick Image Only
|
|
61
|
+
|
|
62
|
+
@objc
|
|
63
|
+
func pickImage(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
64
|
+
rejectPendingPromise()
|
|
65
|
+
self.resolveBlock = resolve
|
|
66
|
+
self.rejectBlock = reject
|
|
67
|
+
|
|
68
|
+
DispatchQueue.main.async {
|
|
69
|
+
if #available(iOS 14.0, *) {
|
|
70
|
+
var config = PHPickerConfiguration()
|
|
71
|
+
config.filter = .images
|
|
72
|
+
config.selectionLimit = 0
|
|
73
|
+
let picker = PHPickerViewController(configuration: config)
|
|
74
|
+
picker.delegate = self
|
|
75
|
+
self.getRootViewController()?.present(picker, animated: true)
|
|
76
|
+
} else {
|
|
77
|
+
let picker = UIImagePickerController()
|
|
78
|
+
picker.sourceType = .photoLibrary
|
|
79
|
+
picker.mediaTypes = ["public.image"]
|
|
80
|
+
picker.delegate = self
|
|
81
|
+
self.getRootViewController()?.present(picker, animated: true)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// MARK: - Pick Video Only
|
|
87
|
+
|
|
88
|
+
@objc
|
|
89
|
+
func pickVideo(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
90
|
+
rejectPendingPromise()
|
|
91
|
+
self.resolveBlock = resolve
|
|
92
|
+
self.rejectBlock = reject
|
|
93
|
+
|
|
94
|
+
DispatchQueue.main.async {
|
|
95
|
+
if #available(iOS 14.0, *) {
|
|
96
|
+
var config = PHPickerConfiguration()
|
|
97
|
+
config.filter = .videos
|
|
98
|
+
config.selectionLimit = 0
|
|
99
|
+
let picker = PHPickerViewController(configuration: config)
|
|
100
|
+
picker.delegate = self
|
|
101
|
+
self.getRootViewController()?.present(picker, animated: true)
|
|
102
|
+
} else {
|
|
103
|
+
let picker = UIImagePickerController()
|
|
104
|
+
picker.sourceType = .photoLibrary
|
|
105
|
+
picker.mediaTypes = ["public.movie"]
|
|
106
|
+
picker.delegate = self
|
|
107
|
+
self.getRootViewController()?.present(picker, animated: true)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// MARK: - Generate Thumbnail from Video URL
|
|
113
|
+
|
|
114
|
+
@objc
|
|
115
|
+
func generateThumbnail(_ videoUrl: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
116
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
117
|
+
guard let url = URL(string: videoUrl) else {
|
|
118
|
+
resolve(nil)
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
let asset = AVAsset(url: url)
|
|
122
|
+
let generator = AVAssetImageGenerator(asset: asset)
|
|
123
|
+
generator.appliesPreferredTrackTransform = true
|
|
124
|
+
let time = CMTimeMake(value: 0, timescale: 1)
|
|
125
|
+
do {
|
|
126
|
+
let cgImage = try generator.copyCGImage(at: time, actualTime: nil)
|
|
127
|
+
let uiImage = UIImage(cgImage: cgImage)
|
|
128
|
+
if let data = uiImage.jpegData(compressionQuality: 0.8) {
|
|
129
|
+
let fileName = "thumb_\(Int(Date().timeIntervalSince1970 * 1000)).jpg"
|
|
130
|
+
let tempDir = NSTemporaryDirectory()
|
|
131
|
+
let filePath = (tempDir as NSString).appendingPathComponent(fileName)
|
|
132
|
+
try data.write(to: URL(fileURLWithPath: filePath))
|
|
133
|
+
resolve("file://" + filePath)
|
|
134
|
+
} else {
|
|
135
|
+
resolve(nil)
|
|
136
|
+
}
|
|
137
|
+
} catch {
|
|
138
|
+
resolve(nil)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// MARK: - Open Video
|
|
144
|
+
|
|
145
|
+
@objc
|
|
146
|
+
func openVideo(_ uri: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
147
|
+
guard let url = URL(string: uri) else {
|
|
148
|
+
reject("INVALID_URL", "Invalid video URL", nil)
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
DispatchQueue.main.async { [weak self] in
|
|
152
|
+
guard let rootVC = self?.getRootViewController() else {
|
|
153
|
+
reject("NO_VC", "No view controller available", nil)
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
let player = AVPlayer(url: url)
|
|
157
|
+
let playerVC = AVPlayerViewController()
|
|
158
|
+
playerVC.player = player
|
|
159
|
+
rootVC.present(playerVC, animated: true) {
|
|
160
|
+
player.play()
|
|
161
|
+
}
|
|
162
|
+
resolve(nil)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// MARK: - Compress Image
|
|
167
|
+
|
|
168
|
+
private func compressImageIfNeeded(imageURL: URL, originalData: Data) -> (URL, Data, String) {
|
|
169
|
+
let fileSize = originalData.count
|
|
170
|
+
let threshold = 500 * 1024 // 500KB
|
|
171
|
+
|
|
172
|
+
if fileSize > threshold, let uiImage = UIImage(data: originalData) {
|
|
173
|
+
// Compress to 80% JPEG quality
|
|
174
|
+
if let compressedData = uiImage.jpegData(compressionQuality: 0.8) {
|
|
175
|
+
let tempDir = NSTemporaryDirectory()
|
|
176
|
+
let compressedFileName = UUID().uuidString + ".jpg"
|
|
177
|
+
let compressedURL = URL(fileURLWithPath: tempDir).appendingPathComponent(compressedFileName)
|
|
178
|
+
do {
|
|
179
|
+
try compressedData.write(to: compressedURL)
|
|
180
|
+
if imageURL != compressedURL {
|
|
181
|
+
try? FileManager.default.removeItem(at: imageURL)
|
|
182
|
+
}
|
|
183
|
+
return (compressedURL, compressedData, "image/jpeg")
|
|
184
|
+
} catch {
|
|
185
|
+
// Fall back to original
|
|
186
|
+
return (imageURL, originalData, self.mimeType(for: imageURL))
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return (imageURL, originalData, self.mimeType(for: imageURL))
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private func mimeType(for url: URL) -> String {
|
|
194
|
+
let ext = url.pathExtension.lowercased()
|
|
195
|
+
switch ext {
|
|
196
|
+
case "jpg", "jpeg": return "image/jpeg"
|
|
197
|
+
case "png": return "image/png"
|
|
198
|
+
case "gif": return "image/gif"
|
|
199
|
+
case "heic", "heif": return "image/heic"
|
|
200
|
+
case "mp4": return "video/mp4"
|
|
201
|
+
case "mov": return "video/quicktime"
|
|
202
|
+
case "m4v": return "video/x-m4v"
|
|
203
|
+
default: return "application/octet-stream"
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private func resolveWithAsset(url: URL, type: String, mimeType: String, fileSize: Int, thumbnailUri: String? = nil) {
|
|
208
|
+
var result: [String: Any] = [
|
|
209
|
+
"uri": url.absoluteString,
|
|
210
|
+
"type": type,
|
|
211
|
+
"fileName": url.lastPathComponent,
|
|
212
|
+
"fileSize": fileSize,
|
|
213
|
+
"mimeType": mimeType,
|
|
214
|
+
]
|
|
215
|
+
if let thumb = thumbnailUri {
|
|
216
|
+
result["thumbnailUri"] = thumb
|
|
217
|
+
}
|
|
218
|
+
resolveBlock?([result])
|
|
219
|
+
resolveBlock = nil
|
|
220
|
+
rejectBlock = nil
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private func generateVideoThumbnail(for videoURL: URL) -> String? {
|
|
224
|
+
let asset = AVAsset(url: videoURL)
|
|
225
|
+
let generator = AVAssetImageGenerator(asset: asset)
|
|
226
|
+
generator.appliesPreferredTrackTransform = true
|
|
227
|
+
generator.maximumSize = CGSize(width: 500, height: 500)
|
|
228
|
+
|
|
229
|
+
do {
|
|
230
|
+
let cgImage = try generator.copyCGImage(at: CMTime.zero, actualTime: nil)
|
|
231
|
+
let uiImage = UIImage(cgImage: cgImage)
|
|
232
|
+
if let jpegData = uiImage.jpegData(compressionQuality: 0.7) {
|
|
233
|
+
let tempDir = NSTemporaryDirectory()
|
|
234
|
+
let thumbFileName = "thumb_" + UUID().uuidString + ".jpg"
|
|
235
|
+
let thumbURL = URL(fileURLWithPath: tempDir).appendingPathComponent(thumbFileName)
|
|
236
|
+
try jpegData.write(to: thumbURL)
|
|
237
|
+
return thumbURL.absoluteString
|
|
238
|
+
}
|
|
239
|
+
} catch {
|
|
240
|
+
// Thumbnail generation failed, return nil
|
|
241
|
+
}
|
|
242
|
+
return nil
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
@objc
|
|
246
|
+
func deleteTempFile(_ uri: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
247
|
+
DispatchQueue.global(qos: .utility).async {
|
|
248
|
+
let path = uri.replacingOccurrences(of: "file://", with: "")
|
|
249
|
+
let fileManager = FileManager.default
|
|
250
|
+
if fileManager.fileExists(atPath: path) {
|
|
251
|
+
try? fileManager.removeItem(atPath: path)
|
|
252
|
+
}
|
|
253
|
+
resolve(nil)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@objc
|
|
258
|
+
func cleanupTempFiles(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
259
|
+
DispatchQueue.global(qos: .utility).async {
|
|
260
|
+
let tempDir = NSTemporaryDirectory()
|
|
261
|
+
let fileManager = FileManager.default
|
|
262
|
+
do {
|
|
263
|
+
let files = try fileManager.contentsOfDirectory(atPath: tempDir)
|
|
264
|
+
for file in files {
|
|
265
|
+
let lower = file.lowercased()
|
|
266
|
+
if lower.hasPrefix("thumb_") || lower.hasPrefix("compressed_") || lower.contains("_") && (lower.hasSuffix(".jpg") || lower.hasSuffix(".jpeg") || lower.hasSuffix(".png") || lower.hasSuffix(".mp4") || lower.hasSuffix(".mov")) {
|
|
267
|
+
let fullPath = (tempDir as NSString).appendingPathComponent(file)
|
|
268
|
+
try? fileManager.removeItem(atPath: fullPath)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
resolve(nil)
|
|
272
|
+
} catch {
|
|
273
|
+
resolve(nil)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// MARK: - PHPickerViewControllerDelegate (iOS 14+)
|
|
280
|
+
|
|
281
|
+
@available(iOS 14.0, *)
|
|
282
|
+
extension ComnyxMediaPicker: PHPickerViewControllerDelegate {
|
|
283
|
+
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
|
|
284
|
+
picker.dismiss(animated: true)
|
|
285
|
+
|
|
286
|
+
guard !results.isEmpty else {
|
|
287
|
+
resolveBlock?(nil)
|
|
288
|
+
resolveBlock = nil
|
|
289
|
+
rejectBlock = nil
|
|
290
|
+
return
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
let allAssets = NSMutableArray()
|
|
294
|
+
let lock = NSLock()
|
|
295
|
+
let group = DispatchGroup()
|
|
296
|
+
|
|
297
|
+
for result in results {
|
|
298
|
+
let provider = result.itemProvider
|
|
299
|
+
|
|
300
|
+
// Handle Image
|
|
301
|
+
if provider.hasItemConformingToTypeIdentifier("public.image") {
|
|
302
|
+
group.enter()
|
|
303
|
+
provider.loadFileRepresentation(forTypeIdentifier: "public.image") { [weak self] url, error in
|
|
304
|
+
defer { group.leave() }
|
|
305
|
+
guard let self = self, let sourceURL = url, error == nil else {
|
|
306
|
+
print("[ComnyxMediaPicker] Image load failed: \(error?.localizedDescription ?? "no url")")
|
|
307
|
+
return
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
let tempDir = NSTemporaryDirectory()
|
|
311
|
+
let tempURL = URL(fileURLWithPath: tempDir).appendingPathComponent(UUID().uuidString + "_" + sourceURL.lastPathComponent)
|
|
312
|
+
do {
|
|
313
|
+
if FileManager.default.fileExists(atPath: tempURL.path) {
|
|
314
|
+
try FileManager.default.removeItem(at: tempURL)
|
|
315
|
+
}
|
|
316
|
+
try FileManager.default.copyItem(at: sourceURL, to: tempURL)
|
|
317
|
+
let data = try Data(contentsOf: tempURL)
|
|
318
|
+
let (finalURL, finalData, finalMimeType) = self.compressImageIfNeeded(imageURL: tempURL, originalData: data)
|
|
319
|
+
let asset: [String: Any] = [
|
|
320
|
+
"uri": finalURL.absoluteString,
|
|
321
|
+
"type": "image",
|
|
322
|
+
"fileName": finalURL.lastPathComponent,
|
|
323
|
+
"fileSize": finalData.count,
|
|
324
|
+
"mimeType": finalMimeType,
|
|
325
|
+
]
|
|
326
|
+
print("[ComnyxMediaPicker] Image asset ready: \(asset)")
|
|
327
|
+
lock.lock()
|
|
328
|
+
allAssets.add(asset)
|
|
329
|
+
lock.unlock()
|
|
330
|
+
} catch {
|
|
331
|
+
print("[ComnyxMediaPicker] Image processing error: \(error)")
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
continue
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Handle Video
|
|
338
|
+
if provider.hasItemConformingToTypeIdentifier("public.movie") {
|
|
339
|
+
group.enter()
|
|
340
|
+
provider.loadFileRepresentation(forTypeIdentifier: "public.movie") { [weak self] url, error in
|
|
341
|
+
defer { group.leave() }
|
|
342
|
+
guard let self = self, let sourceURL = url, error == nil else {
|
|
343
|
+
print("[ComnyxMediaPicker] Video load failed: \(error?.localizedDescription ?? "no url")")
|
|
344
|
+
return
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
let tempDir = NSTemporaryDirectory()
|
|
348
|
+
let tempURL = URL(fileURLWithPath: tempDir).appendingPathComponent(UUID().uuidString + "_" + sourceURL.lastPathComponent)
|
|
349
|
+
do {
|
|
350
|
+
if FileManager.default.fileExists(atPath: tempURL.path) {
|
|
351
|
+
try FileManager.default.removeItem(at: tempURL)
|
|
352
|
+
}
|
|
353
|
+
try FileManager.default.copyItem(at: sourceURL, to: tempURL)
|
|
354
|
+
let attrs = try FileManager.default.attributesOfItem(atPath: tempURL.path)
|
|
355
|
+
let fileSize = attrs[.size] as? Int ?? 0
|
|
356
|
+
let mime = self.mimeType(for: tempURL)
|
|
357
|
+
let thumbnailUri = self.generateVideoThumbnail(for: tempURL)
|
|
358
|
+
var asset: [String: Any] = [
|
|
359
|
+
"uri": tempURL.absoluteString,
|
|
360
|
+
"type": "video",
|
|
361
|
+
"fileName": tempURL.lastPathComponent,
|
|
362
|
+
"fileSize": fileSize,
|
|
363
|
+
"mimeType": mime,
|
|
364
|
+
]
|
|
365
|
+
if let thumb = thumbnailUri {
|
|
366
|
+
asset["thumbnailUri"] = thumb
|
|
367
|
+
}
|
|
368
|
+
print("[ComnyxMediaPicker] Video asset ready: \(asset)")
|
|
369
|
+
lock.lock()
|
|
370
|
+
allAssets.add(asset)
|
|
371
|
+
lock.unlock()
|
|
372
|
+
} catch {
|
|
373
|
+
print("[ComnyxMediaPicker] Video processing error: \(error)")
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
continue
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
group.notify(queue: .main) { [weak self] in
|
|
381
|
+
print("[ComnyxMediaPicker] All assets processed. Count: \(allAssets.count)")
|
|
382
|
+
if allAssets.count == 0 {
|
|
383
|
+
self?.resolveBlock?(nil)
|
|
384
|
+
} else {
|
|
385
|
+
let result = allAssets.map { $0 }
|
|
386
|
+
print("[ComnyxMediaPicker] Resolving with \(result.count) assets")
|
|
387
|
+
self?.resolveBlock?(result)
|
|
388
|
+
}
|
|
389
|
+
self?.resolveBlock = nil
|
|
390
|
+
self?.rejectBlock = nil
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// MARK: - UIImagePickerControllerDelegate (Fallback)
|
|
396
|
+
|
|
397
|
+
extension ComnyxMediaPicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
|
398
|
+
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
|
|
399
|
+
picker.dismiss(animated: true)
|
|
400
|
+
|
|
401
|
+
if let imageURL = info[.imageURL] as? URL {
|
|
402
|
+
do {
|
|
403
|
+
let data = try Data(contentsOf: imageURL)
|
|
404
|
+
let (finalURL, finalData, finalMimeType) = compressImageIfNeeded(imageURL: imageURL, originalData: data)
|
|
405
|
+
resolveWithAsset(url: finalURL, type: "image", mimeType: finalMimeType, fileSize: finalData.count)
|
|
406
|
+
} catch {
|
|
407
|
+
rejectBlock?("FILE_ERROR", error.localizedDescription, error)
|
|
408
|
+
resolveBlock = nil
|
|
409
|
+
rejectBlock = nil
|
|
410
|
+
}
|
|
411
|
+
} else if let videoURL = info[.mediaURL] as? URL {
|
|
412
|
+
do {
|
|
413
|
+
let attrs = try FileManager.default.attributesOfItem(atPath: videoURL.path)
|
|
414
|
+
let fileSize = attrs[.size] as? Int ?? 0
|
|
415
|
+
let mime = mimeType(for: videoURL)
|
|
416
|
+
let thumbnailUri = generateVideoThumbnail(for: videoURL)
|
|
417
|
+
resolveWithAsset(url: videoURL, type: "video", mimeType: mime, fileSize: fileSize, thumbnailUri: thumbnailUri)
|
|
418
|
+
} catch {
|
|
419
|
+
rejectBlock?("FILE_ERROR", error.localizedDescription, error)
|
|
420
|
+
resolveBlock = nil
|
|
421
|
+
rejectBlock = nil
|
|
422
|
+
}
|
|
423
|
+
} else {
|
|
424
|
+
resolveBlock?(nil)
|
|
425
|
+
resolveBlock = nil
|
|
426
|
+
rejectBlock = nil
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
|
431
|
+
picker.dismiss(animated: true)
|
|
432
|
+
resolveBlock?(nil)
|
|
433
|
+
resolveBlock = nil
|
|
434
|
+
rejectBlock = nil
|
|
435
|
+
}
|
|
436
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.cleanupTempFiles = cleanupTempFiles;
|
|
7
|
+
exports.deleteTempFile = deleteTempFile;
|
|
8
|
+
exports.generateThumbnail = generateThumbnail;
|
|
9
|
+
exports.openVideo = openVideo;
|
|
10
|
+
exports.pickImage = pickImage;
|
|
11
|
+
exports.pickMedia = pickMedia;
|
|
12
|
+
exports.pickVideo = pickVideo;
|
|
13
|
+
var _reactNative = require("react-native");
|
|
14
|
+
const {
|
|
15
|
+
ComnyxMediaPicker
|
|
16
|
+
} = _reactNative.NativeModules;
|
|
17
|
+
function mapResults(results) {
|
|
18
|
+
return results.map(result => {
|
|
19
|
+
const isImage = result.type === 'image' || result.mimeType && result.mimeType.startsWith('image');
|
|
20
|
+
return {
|
|
21
|
+
uri: result.uri,
|
|
22
|
+
type: isImage ? 'image' : 'video',
|
|
23
|
+
fileName: result.fileName,
|
|
24
|
+
fileSize: result.fileSize,
|
|
25
|
+
mimeType: result.mimeType,
|
|
26
|
+
width: isImage ? result.width : undefined,
|
|
27
|
+
height: isImage ? result.height : undefined,
|
|
28
|
+
duration: isImage ? undefined : result.duration,
|
|
29
|
+
thumbnailUri: isImage ? undefined : result.thumbnailUri
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async function pickMedia() {
|
|
34
|
+
if (!ComnyxMediaPicker) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
const results = await ComnyxMediaPicker.pickMedia();
|
|
38
|
+
if (!results || !Array.isArray(results) || results.length === 0) return [];
|
|
39
|
+
return mapResults(results);
|
|
40
|
+
}
|
|
41
|
+
async function pickImage() {
|
|
42
|
+
if (!ComnyxMediaPicker) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
const results = await ComnyxMediaPicker.pickImage();
|
|
46
|
+
if (!results || !Array.isArray(results) || results.length === 0) return [];
|
|
47
|
+
return mapResults(results);
|
|
48
|
+
}
|
|
49
|
+
async function pickVideo() {
|
|
50
|
+
if (!ComnyxMediaPicker) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
const results = await ComnyxMediaPicker.pickVideo();
|
|
54
|
+
if (!results || !Array.isArray(results) || results.length === 0) return [];
|
|
55
|
+
return mapResults(results);
|
|
56
|
+
}
|
|
57
|
+
async function openVideo(uri) {
|
|
58
|
+
if (!ComnyxMediaPicker) {
|
|
59
|
+
console.warn('[Comnyx] ComnyxMediaPicker native module is not available');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
await ComnyxMediaPicker.openVideo(uri);
|
|
63
|
+
}
|
|
64
|
+
async function generateThumbnail(videoUrl) {
|
|
65
|
+
if (!ComnyxMediaPicker) {
|
|
66
|
+
console.warn('[Comnyx] ComnyxMediaPicker native module is not available');
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return ComnyxMediaPicker.generateThumbnail(videoUrl);
|
|
70
|
+
}
|
|
71
|
+
async function deleteTempFile(uri) {
|
|
72
|
+
if (!ComnyxMediaPicker) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
return ComnyxMediaPicker.deleteTempFile(uri);
|
|
76
|
+
}
|
|
77
|
+
async function cleanupTempFiles() {
|
|
78
|
+
if (!ComnyxMediaPicker) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
return ComnyxMediaPicker.cleanupTempFiles();
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=NativeComnyxMediaPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","ComnyxMediaPicker","NativeModules","mapResults","results","map","result","isImage","type","mimeType","startsWith","uri","fileName","fileSize","width","undefined","height","duration","thumbnailUri","pickMedia","Array","isArray","length","pickImage","pickVideo","openVideo","console","warn","generateThumbnail","videoUrl","deleteTempFile","cleanupTempFiles"],"sourceRoot":"../../src","sources":["NativeComnyxMediaPicker.ts"],"mappings":";;;;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAGA,MAAM;EAAEC;AAAkB,CAAC,GAAGC,0BAAa;AAE3C,SAASC,UAAUA,CAACC,OAAc,EAAgB;EAChD,OAAOA,OAAO,CAACC,GAAG,CAAEC,MAAW,IAAK;IAClC,MAAMC,OAAO,GACXD,MAAM,CAACE,IAAI,KAAK,OAAO,IACtBF,MAAM,CAACG,QAAQ,IAAIH,MAAM,CAACG,QAAQ,CAACC,UAAU,CAAC,OAAO,CAAE;IAE1D,OAAO;MACLC,GAAG,EAAEL,MAAM,CAACK,GAAG;MACfH,IAAI,EAAED,OAAO,GAAI,OAAO,GAAc,OAAiB;MACvDK,QAAQ,EAAEN,MAAM,CAACM,QAAQ;MACzBC,QAAQ,EAAEP,MAAM,CAACO,QAAQ;MACzBJ,QAAQ,EAAEH,MAAM,CAACG,QAAQ;MACzBK,KAAK,EAAEP,OAAO,GAAGD,MAAM,CAACQ,KAAK,GAAGC,SAAS;MACzCC,MAAM,EAAET,OAAO,GAAGD,MAAM,CAACU,MAAM,GAAGD,SAAS;MAC3CE,QAAQ,EAAEV,OAAO,GAAGQ,SAAS,GAAGT,MAAM,CAACW,QAAQ;MAC/CC,YAAY,EAAEX,OAAO,GAAGQ,SAAS,GAAGT,MAAM,CAACY;IAC7C,CAAC;EACH,CAAC,CAAC;AACJ;AAEO,eAAeC,SAASA,CAAA,EAA0B;EACvD,IAAI,CAAClB,iBAAiB,EAAE;IACtB,OAAO,EAAE;EACX;EACA,MAAMG,OAAO,GAAG,MAAMH,iBAAiB,CAACkB,SAAS,CAAC,CAAC;EACnD,IAAI,CAACf,OAAO,IAAI,CAACgB,KAAK,CAACC,OAAO,CAACjB,OAAO,CAAC,IAAIA,OAAO,CAACkB,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE;EAC1E,OAAOnB,UAAU,CAACC,OAAO,CAAC;AAC5B;AAEO,eAAemB,SAASA,CAAA,EAA0B;EACvD,IAAI,CAACtB,iBAAiB,EAAE;IACtB,OAAO,EAAE;EACX;EACA,MAAMG,OAAO,GAAG,MAAMH,iBAAiB,CAACsB,SAAS,CAAC,CAAC;EACnD,IAAI,CAACnB,OAAO,IAAI,CAACgB,KAAK,CAACC,OAAO,CAACjB,OAAO,CAAC,IAAIA,OAAO,CAACkB,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE;EAC1E,OAAOnB,UAAU,CAACC,OAAO,CAAC;AAC5B;AAEO,eAAeoB,SAASA,CAAA,EAA0B;EACvD,IAAI,CAACvB,iBAAiB,EAAE;IACtB,OAAO,EAAE;EACX;EACA,MAAMG,OAAO,GAAG,MAAMH,iBAAiB,CAACuB,SAAS,CAAC,CAAC;EACnD,IAAI,CAACpB,OAAO,IAAI,CAACgB,KAAK,CAACC,OAAO,CAACjB,OAAO,CAAC,IAAIA,OAAO,CAACkB,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE;EAC1E,OAAOnB,UAAU,CAACC,OAAO,CAAC;AAC5B;AAEO,eAAeqB,SAASA,CAACd,GAAW,EAAiB;EAC1D,IAAI,CAACV,iBAAiB,EAAE;IACtByB,OAAO,CAACC,IAAI,CAAC,2DAA2D,CAAC;IACzE;EACF;EACA,MAAM1B,iBAAiB,CAACwB,SAAS,CAACd,GAAG,CAAC;AACxC;AAEO,eAAeiB,iBAAiBA,CACrCC,QAAgB,EACQ;EACxB,IAAI,CAAC5B,iBAAiB,EAAE;IACtByB,OAAO,CAACC,IAAI,CAAC,2DAA2D,CAAC;IACzE,OAAO,IAAI;EACb;EACA,OAAO1B,iBAAiB,CAAC2B,iBAAiB,CAACC,QAAQ,CAAC;AACtD;AAEO,eAAeC,cAAcA,CAACnB,GAAW,EAAiB;EAC/D,IAAI,CAACV,iBAAiB,EAAE;IACtB;EACF;EACA,OAAOA,iBAAiB,CAAC6B,cAAc,CAACnB,GAAG,CAAC;AAC9C;AAEO,eAAeoB,gBAAgBA,CAAA,EAAkB;EACtD,IAAI,CAAC9B,iBAAiB,EAAE;IACtB;EACF;EACA,OAAOA,iBAAiB,CAAC8B,gBAAgB,CAAC,CAAC;AAC7C","ignoreList":[]}
|
|
@@ -21,13 +21,32 @@ Object.defineProperty(exports, "getNewCustomerConversation", {
|
|
|
21
21
|
return _conversations.getNewCustomerConversation;
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
|
+
Object.defineProperty(exports, "getUploadUrl", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _media.getUploadUrl;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
24
30
|
Object.defineProperty(exports, "sendCustomerMessage", {
|
|
25
31
|
enumerable: true,
|
|
26
32
|
get: function () {
|
|
27
33
|
return _messages.sendCustomerMessage;
|
|
28
34
|
}
|
|
29
35
|
});
|
|
36
|
+
Object.defineProperty(exports, "sendMediaMessage", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _media.sendMediaMessage;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "uploadFileToS3", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _media.uploadFileToS3;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
30
48
|
var _customers = require("./customers.js");
|
|
31
49
|
var _conversations = require("./conversations.js");
|
|
32
50
|
var _messages = require("./messages.js");
|
|
51
|
+
var _media = require("./media.js");
|
|
33
52
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_customers","require","_conversations","_messages"],"sourceRoot":"../../../src","sources":["api/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_customers","require","_conversations","_messages","_media"],"sourceRoot":"../../../src","sources":["api/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AACA,IAAAC,cAAA,GAAAD,OAAA;AAIA,IAAAE,SAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA","ignoreList":[]}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getUploadUrl = getUploadUrl;
|
|
7
|
+
exports.sendMediaMessage = sendMediaMessage;
|
|
8
|
+
exports.uploadFileToS3 = uploadFileToS3;
|
|
9
|
+
var _reactNative = require("react-native");
|
|
10
|
+
var _api = require("./api.js");
|
|
11
|
+
var _media = require("../data/fake/media.js");
|
|
12
|
+
function getUploadUrl(fileName, contentType, options) {
|
|
13
|
+
if (options.fake) {
|
|
14
|
+
return (0, _media.getFakeUploadUrlResponse)(fileName);
|
|
15
|
+
}
|
|
16
|
+
return _api.axiosInstance.post('/api/media/presign', {
|
|
17
|
+
fileName,
|
|
18
|
+
fileType: contentType
|
|
19
|
+
}).then(res => res.data);
|
|
20
|
+
}
|
|
21
|
+
function uploadFileToS3(uploadUrl, fileUri, contentType, onProgress, options) {
|
|
22
|
+
if (options?.fake) {
|
|
23
|
+
return (0, _media.fakeUploadToS3)(onProgress);
|
|
24
|
+
}
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const xhr = new XMLHttpRequest();
|
|
27
|
+
xhr.upload.addEventListener('progress', event => {
|
|
28
|
+
if (event.lengthComputable && onProgress) {
|
|
29
|
+
const percentage = Math.min(100, Math.round(event.loaded / event.total * 100));
|
|
30
|
+
onProgress(percentage);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
xhr.addEventListener('load', () => {
|
|
34
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
35
|
+
resolve();
|
|
36
|
+
} else {
|
|
37
|
+
console.error('[Comnyx] Upload failed:', xhr.status, xhr.responseText);
|
|
38
|
+
reject(new Error(`Upload failed with status ${xhr.status}`));
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
xhr.addEventListener('error', () => {
|
|
42
|
+
console.error('[Comnyx] Upload XHR error, status:', xhr.status, 'response:', xhr.responseText);
|
|
43
|
+
reject(new Error('Upload failed'));
|
|
44
|
+
});
|
|
45
|
+
xhr.addEventListener('abort', () => {
|
|
46
|
+
reject(new Error('Upload aborted'));
|
|
47
|
+
});
|
|
48
|
+
xhr.open('PUT', uploadUrl);
|
|
49
|
+
xhr.setRequestHeader('Content-Type', contentType);
|
|
50
|
+
|
|
51
|
+
// React Native supports sending file URIs directly via XHR
|
|
52
|
+
const file = {
|
|
53
|
+
uri: _reactNative.Platform.OS === 'android' ? fileUri : fileUri.replace('file://', ''),
|
|
54
|
+
type: contentType,
|
|
55
|
+
name: fileUri.split('/').pop() || 'file'
|
|
56
|
+
};
|
|
57
|
+
xhr.send(file);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function sendMediaMessage(externalId, fileUrls, mediaType, content, options) {
|
|
61
|
+
if (options.fake) {
|
|
62
|
+
return (0, _media.getFakeMediaMessageResponse)(fileUrls, mediaType);
|
|
63
|
+
}
|
|
64
|
+
return _api.axiosInstance.post('/api/customers/message', {
|
|
65
|
+
externalId,
|
|
66
|
+
content,
|
|
67
|
+
files: fileUrls,
|
|
68
|
+
media_type: mediaType
|
|
69
|
+
}, {
|
|
70
|
+
headers: {
|
|
71
|
+
'Accept': 'application/json',
|
|
72
|
+
'Content-Type': 'application/json'
|
|
73
|
+
}
|
|
74
|
+
}).then(res => res.data);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_api","_media","getUploadUrl","fileName","contentType","options","fake","getFakeUploadUrlResponse","axiosInstance","post","fileType","then","res","data","uploadFileToS3","uploadUrl","fileUri","onProgress","fakeUploadToS3","Promise","resolve","reject","xhr","XMLHttpRequest","upload","addEventListener","event","lengthComputable","percentage","Math","min","round","loaded","total","status","console","error","responseText","Error","open","setRequestHeader","file","uri","Platform","OS","replace","type","name","split","pop","send","sendMediaMessage","externalId","fileUrls","mediaType","content","getFakeMediaMessageResponse","files","media_type","headers"],"sourceRoot":"../../../src","sources":["api/media.ts"],"mappings":"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","ignoreList":[]}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|