react-native-newinstance-chat 0.1.2 → 0.2.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/NewinstanceChat.podspec +1 -1
- package/README.md +87 -3
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/newinstancechat/NewinstanceChatModule.kt +78 -10
- package/ios/NewinstanceChat.mm +10 -0
- package/ios/NewinstanceChatImpl.swift +77 -15
- package/lib/module/NativeNewinstanceChat.js.map +1 -1
- package/lib/module/index.js +13 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/NativeNewinstanceChat.d.ts +3 -1
- package/lib/typescript/src/NativeNewinstanceChat.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +5 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +56 -3
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +9 -3
- package/src/NativeNewinstanceChat.ts +3 -1
- package/src/index.tsx +14 -1
- package/src/types.ts +78 -3
package/NewinstanceChat.podspec
CHANGED
|
@@ -18,7 +18,7 @@ Pod::Spec.new do |s|
|
|
|
18
18
|
s.pod_target_xcconfig = { "DEFINES_MODULE" => "YES" }
|
|
19
19
|
|
|
20
20
|
# Native chat SDK we wrap, published on CocoaPods Trunk.
|
|
21
|
-
s.dependency "LiveAndAiChat", "~> 0.
|
|
21
|
+
s.dependency "LiveAndAiChat", "~> 0.2.0"
|
|
22
22
|
|
|
23
23
|
install_modules_dependencies(s)
|
|
24
24
|
end
|
package/README.md
CHANGED
|
@@ -86,17 +86,101 @@ unsub();
|
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
Event names: `messageReceived`, `messageSent`, `agentTypingChanged`,
|
|
89
|
-
`connectionStateChanged`, `unreadCountChanged`, `error
|
|
90
|
-
for payload shapes.
|
|
89
|
+
`connectionStateChanged`, `unreadCountChanged`, `error`,
|
|
90
|
+
`attachmentUpdated`, `chatClosed`. See `src/types.ts` for payload shapes.
|
|
91
|
+
|
|
92
|
+
### The chat-close event
|
|
93
|
+
|
|
94
|
+
`chatClosed` fires **exactly once per chat presentation**, however the
|
|
95
|
+
screen went away: the in-chat close button, Android back navigation
|
|
96
|
+
(button or gesture), an iOS dismissal gesture, `closeChat()`,
|
|
97
|
+
`destroy()` (reason `session_ended`), or the host app navigating the
|
|
98
|
+
screen away. Rerenders and lifecycle churn never produce duplicates.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
const unsub = sdk.addListener('chatClosed', (e) => {
|
|
103
|
+
// e.reason: 'close_button' | 'back_navigation' | 'gesture' |
|
|
104
|
+
// 'programmatic' | 'session_ended' | 'host_navigation'
|
|
105
|
+
// e.initiator: 'user' | 'host' | 'sdk'
|
|
106
|
+
// plus: timestamp, conversationId, assignmentId, channel,
|
|
107
|
+
// previousState, unreadCount, hasDraft,
|
|
108
|
+
// pendingAttachmentCount, metadata
|
|
109
|
+
analytics.track('chat_closed', { reason: e.reason });
|
|
110
|
+
});
|
|
111
|
+
return unsub; // always clean up on unmount
|
|
112
|
+
}, []);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Ordering: `chatClosed` is emitted after the SDK has left the open
|
|
116
|
+
state (`unreadCount` and `pendingAttachmentCount` reflect the moment of
|
|
117
|
+
dismissal). The event never contains message contents, credentials, or
|
|
118
|
+
attachment bytes.
|
|
91
119
|
|
|
92
120
|
### Sending messages programmatically
|
|
93
121
|
|
|
94
122
|
```ts
|
|
95
123
|
sdk.sendMessage('Hi, I have a question.');
|
|
96
|
-
sdk.attachFile({ uri: 'file:///…', name: 'screenshot.png', mimeType: 'image/png' });
|
|
97
124
|
sdk.retryMessage(failedMessageId);
|
|
98
125
|
```
|
|
99
126
|
|
|
127
|
+
### Programmatic attachments
|
|
128
|
+
|
|
129
|
+
`attachFile` accepts base64, data URIs, local file paths,
|
|
130
|
+
`content://` / `file://` URIs (picker outputs), and — when the native
|
|
131
|
+
SDK is configured with `allowRemoteAttachmentUrls` — remote URLs.
|
|
132
|
+
`sourceType: 'auto'` (the default) safely detects string inputs.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
// Base64 (e.g. from a camera or canvas):
|
|
136
|
+
const id = await sdk.attachFile({
|
|
137
|
+
source: pngBase64,
|
|
138
|
+
sourceType: 'base64',
|
|
139
|
+
name: 'photo.png',
|
|
140
|
+
mimeType: 'image/png',
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// React Native document picker result:
|
|
144
|
+
const [doc] = await pick(); // e.g. @react-native-documents/picker
|
|
145
|
+
await sdk.attachFile({
|
|
146
|
+
source: doc.uri, // content:// on Android, file:// on iOS
|
|
147
|
+
name: doc.name ?? 'document.pdf',
|
|
148
|
+
mimeType: doc.type ?? 'application/pdf',
|
|
149
|
+
size: doc.size ?? undefined,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Data URI:
|
|
153
|
+
await sdk.attachFile({ source: dataUri, name: 'chart.png' });
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The returned promise resolves with the attachment **id** as soon as the
|
|
157
|
+
request is accepted and queued. Validation and upload run in the
|
|
158
|
+
background and never block the UI thread — failures surface as
|
|
159
|
+
`attachmentUpdated` with `status: 'failed'` plus an `error` event — and
|
|
160
|
+
the message is never sent until the upload succeeds (send drains only
|
|
161
|
+
uploaded attachments). Track progress and results via
|
|
162
|
+
`attachmentUpdated`:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
sdk.addListener('attachmentUpdated', (a) => {
|
|
166
|
+
// a.status: 'queued' | 'uploading' | 'uploaded' | 'failed' | 'cancelled'
|
|
167
|
+
// a.progress: 0..1 real byte progress
|
|
168
|
+
if (a.status === 'failed') console.warn(a.error);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
sdk.removeAttachment(id); // cancels an in-flight upload
|
|
172
|
+
sdk.clearAttachments();
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Validation happens before anything is queued: base64 must decode, URIs
|
|
176
|
+
must be readable, files must be non-empty and at most 25 MB, the MIME
|
|
177
|
+
type must be one of png/jpeg/webp/gif/pdf, a mismatched `size` is
|
|
178
|
+
rejected as corruption, and the extension must agree with the MIME
|
|
179
|
+
type. Attachment contents are never written to logs.
|
|
180
|
+
|
|
181
|
+
Allowed MIME types and the 25 MB cap mirror the web widget; keys and
|
|
182
|
+
limits are enforced again server-side.
|
|
183
|
+
|
|
100
184
|
Handoff to a live agent and typing indicators are driven automatically
|
|
101
185
|
by the native chat screen — there's nothing to wire up from the host.
|
|
102
186
|
|
package/android/build.gradle
CHANGED
|
@@ -73,5 +73,5 @@ repositories {
|
|
|
73
73
|
dependencies {
|
|
74
74
|
implementation "com.facebook.react:react-android"
|
|
75
75
|
// Native chat SDK the bridge wraps. Published under cloud.newinstance.
|
|
76
|
-
implementation "cloud.newinstance:liveandaichat:0.
|
|
76
|
+
implementation "cloud.newinstance:liveandaichat:0.2.0"
|
|
77
77
|
}
|
|
@@ -5,8 +5,12 @@ import cloud.newinstance.liveandaichat.LiveAndAiChat
|
|
|
5
5
|
import cloud.newinstance.liveandaichat.LiveAndAiChatConfig
|
|
6
6
|
import cloud.newinstance.liveandaichat.LiveAndAiChatError
|
|
7
7
|
import cloud.newinstance.liveandaichat.ChatUser
|
|
8
|
+
import cloud.newinstance.liveandaichat.model.AttachmentRequest
|
|
9
|
+
import cloud.newinstance.liveandaichat.model.AttachmentSource
|
|
10
|
+
import cloud.newinstance.liveandaichat.model.ChatCloseEvent
|
|
8
11
|
import cloud.newinstance.liveandaichat.model.ChatMessage
|
|
9
12
|
import cloud.newinstance.liveandaichat.model.TransportMode
|
|
13
|
+
import cloud.newinstance.liveandaichat.upload.QueuedAttachment
|
|
10
14
|
import com.facebook.react.bridge.Arguments
|
|
11
15
|
import com.facebook.react.bridge.Promise
|
|
12
16
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
@@ -124,24 +128,57 @@ class NewinstanceChatModule(reactContext: ReactApplicationContext) :
|
|
|
124
128
|
promise.reject("E_NOT_CONFIGURED", "configure() must be called first")
|
|
125
129
|
return
|
|
126
130
|
}
|
|
127
|
-
val uri = opts.getString("uri")
|
|
128
131
|
val name = opts.getString("name")
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
if (name.isNullOrBlank()) {
|
|
133
|
+
promise.reject("E_ARGS", "name is required")
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
val sourceValue = opts.getString("source") ?: opts.getString("uri")
|
|
137
|
+
if (sourceValue.isNullOrBlank()) {
|
|
138
|
+
promise.reject("E_ARGS", "source (or legacy uri) is required")
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
val sourceType = opts.getString("sourceType") ?: "auto"
|
|
142
|
+
val source = AttachmentSource.fromTypeName(sourceType, sourceValue)
|
|
143
|
+
if (source == null) {
|
|
144
|
+
promise.reject(
|
|
145
|
+
"E_SOURCE",
|
|
146
|
+
if (sourceType == "auto") "Could not detect the attachment source type — pass sourceType explicitly"
|
|
147
|
+
else "Unknown sourceType: $sourceType",
|
|
148
|
+
)
|
|
132
149
|
return
|
|
133
150
|
}
|
|
151
|
+
val mimeType = opts.getString("mimeType")
|
|
152
|
+
val declaredSize = if (opts.hasKey("size") && !opts.isNull("size")) opts.getDouble("size").toLong() else null
|
|
153
|
+
val metadata = mutableMapOf<String, String>()
|
|
154
|
+
if (opts.hasKey("metadata") && !opts.isNull("metadata")) {
|
|
155
|
+
val map = opts.getMap("metadata")
|
|
156
|
+
map?.entryIterator?.forEach { (key, value) -> metadata[key] = value.toString() }
|
|
157
|
+
}
|
|
134
158
|
try {
|
|
135
|
-
val
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
159
|
+
val id = current.attach(
|
|
160
|
+
AttachmentRequest(
|
|
161
|
+
source = source,
|
|
162
|
+
name = name,
|
|
163
|
+
mimeType = mimeType,
|
|
164
|
+
declaredSize = declaredSize,
|
|
165
|
+
metadata = metadata,
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
promise.resolve(id)
|
|
140
169
|
} catch (e: Exception) {
|
|
141
|
-
promise.reject("
|
|
170
|
+
promise.reject("E_ATTACH", e.message, e)
|
|
142
171
|
}
|
|
143
172
|
}
|
|
144
173
|
|
|
174
|
+
override fun removeAttachment(id: String) {
|
|
175
|
+
sdk?.removeAttachment(id)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
override fun clearAttachments() {
|
|
179
|
+
sdk?.clearAttachments()
|
|
180
|
+
}
|
|
181
|
+
|
|
145
182
|
override fun destroy() {
|
|
146
183
|
sdk?.destroy()
|
|
147
184
|
sdk = null
|
|
@@ -170,6 +207,37 @@ class NewinstanceChatModule(reactContext: ReactApplicationContext) :
|
|
|
170
207
|
override fun onUnreadCountChange(count: Int) {
|
|
171
208
|
emit("unreadCountChanged", count)
|
|
172
209
|
}
|
|
210
|
+
override fun onAttachmentUpdate(attachment: QueuedAttachment) {
|
|
211
|
+
val map = Arguments.createMap()
|
|
212
|
+
map.putString("id", attachment.id)
|
|
213
|
+
map.putString("name", attachment.name)
|
|
214
|
+
map.putString("mimeType", attachment.mimeType)
|
|
215
|
+
map.putDouble("size", attachment.size.toDouble())
|
|
216
|
+
map.putString("status", attachment.status.name.lowercase())
|
|
217
|
+
map.putDouble("progress", attachment.progress.toDouble())
|
|
218
|
+
attachment.publicUrl?.let { map.putString("url", it) }
|
|
219
|
+
attachment.errorReason?.let { map.putString("error", it) }
|
|
220
|
+
emit("attachmentUpdated", map)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
override fun onChatClosed(event: ChatCloseEvent) {
|
|
224
|
+
val map = Arguments.createMap()
|
|
225
|
+
map.putString("reason", event.reason.wire)
|
|
226
|
+
map.putString("initiator", event.initiator.wire)
|
|
227
|
+
map.putDouble("timestamp", event.timestamp.toDouble())
|
|
228
|
+
event.conversationId?.let { map.putString("conversationId", it) }
|
|
229
|
+
event.assignmentId?.let { map.putString("assignmentId", it) }
|
|
230
|
+
map.putString("channel", event.channel)
|
|
231
|
+
map.putString("previousState", event.previousState)
|
|
232
|
+
map.putInt("unreadCount", event.unreadCount)
|
|
233
|
+
map.putBoolean("hasDraft", event.hasDraft)
|
|
234
|
+
map.putInt("pendingAttachmentCount", event.pendingAttachmentCount)
|
|
235
|
+
val meta = Arguments.createMap()
|
|
236
|
+
event.metadata.forEach { (k, v) -> meta.putString(k, v) }
|
|
237
|
+
map.putMap("metadata", meta)
|
|
238
|
+
emit("chatClosed", map)
|
|
239
|
+
}
|
|
240
|
+
|
|
173
241
|
override fun onError(error: LiveAndAiChatError) {
|
|
174
242
|
val map = Arguments.createMap()
|
|
175
243
|
map.putString("type", error.type.name.lowercase())
|
package/ios/NewinstanceChat.mm
CHANGED
|
@@ -76,6 +76,16 @@ RCT_EXPORT_MODULE()
|
|
|
76
76
|
[_impl attachFile:opts resolver:resolve rejecter:reject];
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
- (void)removeAttachment:(NSString *)attachmentId
|
|
80
|
+
{
|
|
81
|
+
[_impl removeAttachment:attachmentId];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
- (void)clearAttachments
|
|
85
|
+
{
|
|
86
|
+
[_impl clearAttachments];
|
|
87
|
+
}
|
|
88
|
+
|
|
79
89
|
// NativeEventEmitter wires these so it can track subscriber counts. The
|
|
80
90
|
// actual event payloads flow through RCTDeviceEventEmitter, so these are
|
|
81
91
|
// intentional no-ops.
|
|
@@ -140,24 +140,51 @@ public final class NewinstanceChatImpl: NSObject, LiveAndAiChatDelegate {
|
|
|
140
140
|
rejecter("E_NOT_CONFIGURED", "configure() must be called first", nil)
|
|
141
141
|
return
|
|
142
142
|
}
|
|
143
|
-
guard let
|
|
144
|
-
|
|
145
|
-
let mimeType = opts["mimeType"] as? String,
|
|
146
|
-
let url = URL(string: uri) else {
|
|
147
|
-
rejecter("E_ARGS", "uri, name, mimeType are required", nil)
|
|
143
|
+
guard let name = opts["name"] as? String, !name.isEmpty else {
|
|
144
|
+
rejecter("E_ARGS", "name is required", nil)
|
|
148
145
|
return
|
|
149
146
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
147
|
+
guard let sourceValue = (opts["source"] as? String) ?? (opts["uri"] as? String), !sourceValue.isEmpty else {
|
|
148
|
+
rejecter("E_ARGS", "source (or legacy uri) is required", nil)
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
let sourceType = (opts["sourceType"] as? String) ?? "auto"
|
|
152
|
+
guard let source = AttachmentSource.fromTypeName(sourceType, value: sourceValue) else {
|
|
153
|
+
rejecter(
|
|
154
|
+
"E_SOURCE",
|
|
155
|
+
sourceType == "auto"
|
|
156
|
+
? "Could not detect the attachment source type — pass sourceType explicitly"
|
|
157
|
+
: "Unknown sourceType: \(sourceType)",
|
|
158
|
+
nil
|
|
159
|
+
)
|
|
160
|
+
return
|
|
160
161
|
}
|
|
162
|
+
let mimeType = opts["mimeType"] as? String
|
|
163
|
+
let declaredSize = (opts["size"] as? NSNumber)?.int64Value
|
|
164
|
+
var metadata: [String: String] = [:]
|
|
165
|
+
if let raw = opts["metadata"] as? [String: Any] {
|
|
166
|
+
for (key, value) in raw { metadata[key] = String(describing: value) }
|
|
167
|
+
}
|
|
168
|
+
let request = AttachmentRequest(
|
|
169
|
+
source: source,
|
|
170
|
+
name: name,
|
|
171
|
+
mimeType: mimeType,
|
|
172
|
+
declaredSize: declaredSize,
|
|
173
|
+
metadata: metadata
|
|
174
|
+
)
|
|
175
|
+
DispatchQueue.main.async {
|
|
176
|
+
let id = sdk.attach(request)
|
|
177
|
+
resolver(id)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@objc(removeAttachment:)
|
|
182
|
+
public func removeAttachment(_ id: String) {
|
|
183
|
+
DispatchQueue.main.async { [weak self] in self?.sdk?.removeAttachment(id: id) }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@objc public func clearAttachments() {
|
|
187
|
+
DispatchQueue.main.async { [weak self] in self?.sdk?.clearAttachments() }
|
|
161
188
|
}
|
|
162
189
|
|
|
163
190
|
@objc public func destroy() {
|
|
@@ -171,6 +198,41 @@ public final class NewinstanceChatImpl: NSObject, LiveAndAiChatDelegate {
|
|
|
171
198
|
|
|
172
199
|
// MARK: - LiveAndAiChatDelegate
|
|
173
200
|
|
|
201
|
+
public func unreadCountDidChange(_ count: Int) {
|
|
202
|
+
emitter?.emitEvent("unreadCountChanged", body: count)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public func attachmentDidUpdate(_ attachment: QueuedAttachment) {
|
|
206
|
+
var body: [String: Any] = [
|
|
207
|
+
"id": attachment.id,
|
|
208
|
+
"name": attachment.name,
|
|
209
|
+
"mimeType": attachment.mimeType,
|
|
210
|
+
"size": attachment.size,
|
|
211
|
+
"status": attachment.status.rawValue,
|
|
212
|
+
"progress": attachment.progress,
|
|
213
|
+
]
|
|
214
|
+
if let url = attachment.publicUrl { body["url"] = url }
|
|
215
|
+
if let error = attachment.errorReason { body["error"] = error }
|
|
216
|
+
emitter?.emitEvent("attachmentUpdated", body: body)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
public func chatDidClose(_ event: ChatCloseEvent) {
|
|
220
|
+
var body: [String: Any] = [
|
|
221
|
+
"reason": event.reason.rawValue,
|
|
222
|
+
"initiator": event.initiator.rawValue,
|
|
223
|
+
"timestamp": event.timestamp,
|
|
224
|
+
"channel": event.channel,
|
|
225
|
+
"previousState": event.previousState,
|
|
226
|
+
"unreadCount": event.unreadCount,
|
|
227
|
+
"hasDraft": event.hasDraft,
|
|
228
|
+
"pendingAttachmentCount": event.pendingAttachmentCount,
|
|
229
|
+
"metadata": event.metadata,
|
|
230
|
+
]
|
|
231
|
+
if let id = event.conversationId { body["conversationId"] = id }
|
|
232
|
+
if let id = event.assignmentId { body["assignmentId"] = id }
|
|
233
|
+
emitter?.emitEvent("chatClosed", body: body)
|
|
234
|
+
}
|
|
235
|
+
|
|
174
236
|
public func didReceiveMessage(_ message: ChatMessage) {
|
|
175
237
|
emitter?.emitEvent("messageReceived", body: Self.chatMessageToDict(message))
|
|
176
238
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeNewinstanceChat.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;;AAEpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeNewinstanceChat.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;;AAEpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAoBA,eAAeA,mBAAmB,CAACC,YAAY,CAAO,iBAAiB,CAAC","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -65,9 +65,22 @@ export class NewinstanceChat {
|
|
|
65
65
|
* uploaded reference into the next `sendMessage()`.
|
|
66
66
|
*/
|
|
67
67
|
attachFile(opts) {
|
|
68
|
+
if (!opts.source && !opts.uri) {
|
|
69
|
+
return Promise.reject(new Error('attachFile requires `source` (or the legacy `uri`)'));
|
|
70
|
+
}
|
|
68
71
|
return NativeNewinstanceChat.attachFile(opts);
|
|
69
72
|
}
|
|
70
73
|
|
|
74
|
+
/** Remove a queued attachment; cancels its upload if still in flight. */
|
|
75
|
+
removeAttachment(id) {
|
|
76
|
+
NativeNewinstanceChat.removeAttachment(id);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Remove every queued attachment and cancel in-flight uploads. */
|
|
80
|
+
clearAttachments() {
|
|
81
|
+
NativeNewinstanceChat.clearAttachments();
|
|
82
|
+
}
|
|
83
|
+
|
|
71
84
|
/**
|
|
72
85
|
* Subscribe to a native event. Returns an unsubscribe function — call it
|
|
73
86
|
* when your component unmounts to avoid leaks.
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeEventEmitter","NativeModules","NativeNewinstanceChat","emitterSource","NewinstanceChat","emitter","constructor","config","ready","configure","setUser","user","initialize","openChat","closeChat","sendMessage","text","retryMessage","messageId","attachFile","opts","addListener","event","handler","sub","remove","destroy"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,kBAAkB,EAClBC,aAAa,QAER,cAAc;AAErB,OAAOC,qBAAqB,MAAM,4BAAyB;AAqB3D;AACA;AACA;AACA,MAAMC,aAAkB,GACtBF,aAAa,CAACG,eAAe,IAAKF,qBAAiC;AACrE,MAAMG,OAAO,GAAG,IAAIL,kBAAkB,CAACG,aAAa,CAAC;;AAErD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,CAAC;EAC3B;;EAGAE,WAAWA,CAACC,MAA6B,EAAE;IACzC,IAAI,CAACC,KAAK,GAAGN,qBAAqB,CAACO,SAAS,CAACF,MAAM,CAAC;EACtD;;EAEA;AACF;AACA;AACA;AACA;EACEG,OAAOA,CAACC,IAAc,EAAQ;IAC5BT,qBAAqB,CAACQ,OAAO,CAACC,IAAI,CAAC;EACrC;;EAEA;AACF;AACA;AACA;AACA;EACEC,UAAUA,CAAA,EAAkB;IAC1B,OAAOV,qBAAqB,CAACU,UAAU,CAAC,CAAC;EAC3C;;EAEA;EACAC,QAAQA,CAAA,EAAS;IACfX,qBAAqB,CAACW,QAAQ,CAAC,CAAC;EAClC;;EAEA;EACAC,SAASA,CAAA,EAAS;IAChBZ,qBAAqB,CAACY,SAAS,CAAC,CAAC;EACnC;EAEAC,WAAWA,CAACC,IAAY,EAAQ;IAC9Bd,qBAAqB,CAACa,WAAW,CAACC,IAAI,CAAC;EACzC;EAEAC,YAAYA,CAACC,SAAiB,EAAQ;IACpChB,qBAAqB,CAACe,YAAY,CAACC,SAAS,CAAC;EAC/C;;EAEA;AACF;AACA;AACA;AACA;EACEC,UAAUA,CAACC,IAAqB,
|
|
1
|
+
{"version":3,"names":["NativeEventEmitter","NativeModules","NativeNewinstanceChat","emitterSource","NewinstanceChat","emitter","constructor","config","ready","configure","setUser","user","initialize","openChat","closeChat","sendMessage","text","retryMessage","messageId","attachFile","opts","source","uri","Promise","reject","Error","removeAttachment","id","clearAttachments","addListener","event","handler","sub","remove","destroy"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,kBAAkB,EAClBC,aAAa,QAER,cAAc;AAErB,OAAOC,qBAAqB,MAAM,4BAAyB;AAqB3D;AACA;AACA;AACA,MAAMC,aAAkB,GACtBF,aAAa,CAACG,eAAe,IAAKF,qBAAiC;AACrE,MAAMG,OAAO,GAAG,IAAIL,kBAAkB,CAACG,aAAa,CAAC;;AAErD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,CAAC;EAC3B;;EAGAE,WAAWA,CAACC,MAA6B,EAAE;IACzC,IAAI,CAACC,KAAK,GAAGN,qBAAqB,CAACO,SAAS,CAACF,MAAM,CAAC;EACtD;;EAEA;AACF;AACA;AACA;AACA;EACEG,OAAOA,CAACC,IAAc,EAAQ;IAC5BT,qBAAqB,CAACQ,OAAO,CAACC,IAAI,CAAC;EACrC;;EAEA;AACF;AACA;AACA;AACA;EACEC,UAAUA,CAAA,EAAkB;IAC1B,OAAOV,qBAAqB,CAACU,UAAU,CAAC,CAAC;EAC3C;;EAEA;EACAC,QAAQA,CAAA,EAAS;IACfX,qBAAqB,CAACW,QAAQ,CAAC,CAAC;EAClC;;EAEA;EACAC,SAASA,CAAA,EAAS;IAChBZ,qBAAqB,CAACY,SAAS,CAAC,CAAC;EACnC;EAEAC,WAAWA,CAACC,IAAY,EAAQ;IAC9Bd,qBAAqB,CAACa,WAAW,CAACC,IAAI,CAAC;EACzC;EAEAC,YAAYA,CAACC,SAAiB,EAAQ;IACpChB,qBAAqB,CAACe,YAAY,CAACC,SAAS,CAAC;EAC/C;;EAEA;AACF;AACA;AACA;AACA;EACEC,UAAUA,CAACC,IAAqB,EAAmB;IACjD,IAAI,CAACA,IAAI,CAACC,MAAM,IAAI,CAACD,IAAI,CAACE,GAAG,EAAE;MAC7B,OAAOC,OAAO,CAACC,MAAM,CAAC,IAAIC,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxF;IACA,OAAOvB,qBAAqB,CAACiB,UAAU,CAACC,IAAI,CAAC;EAC/C;;EAEA;EACAM,gBAAgBA,CAACC,EAAU,EAAQ;IACjCzB,qBAAqB,CAACwB,gBAAgB,CAACC,EAAE,CAAC;EAC5C;;EAEA;EACAC,gBAAgBA,CAAA,EAAS;IACvB1B,qBAAqB,CAAC0B,gBAAgB,CAAC,CAAC;EAC1C;;EAEA;AACF;AACA;AACA;EACEC,WAAWA,CACTC,KAAQ,EACRC,OAAwB,EACZ;IACZ,MAAMC,GAAwB,GAAG3B,OAAO,CAACwB,WAAW,CAClDC,KAAK,EACLC,OACF,CAAC;IACD,OAAO,MAAMC,GAAG,CAACC,MAAM,CAAC,CAAC;EAC3B;;EAEA;AACF;AACA;AACA;EACEC,OAAOA,CAAA,EAAS;IACdhC,qBAAqB,CAACgC,OAAO,CAAC,CAAC;EACjC;AACF","ignoreList":[]}
|
|
@@ -17,7 +17,9 @@ export interface Spec extends TurboModule {
|
|
|
17
17
|
closeChat(): void;
|
|
18
18
|
sendMessage(text: string): void;
|
|
19
19
|
retryMessage(messageId: string): void;
|
|
20
|
-
attachFile(opts: Object): Promise<
|
|
20
|
+
attachFile(opts: Object): Promise<string>;
|
|
21
|
+
removeAttachment(id: string): void;
|
|
22
|
+
clearAttachments(): void;
|
|
21
23
|
destroy(): void;
|
|
22
24
|
addListener(eventName: string): void;
|
|
23
25
|
removeListeners(count: number): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeNewinstanceChat.d.ts","sourceRoot":"","sources":["../../../src/NativeNewinstanceChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE;;;;;;;;;GASG;AACH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,IAAI,IAAI,CAAC;IACjB,SAAS,IAAI,IAAI,CAAC;IAClB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeNewinstanceChat.d.ts","sourceRoot":"","sources":["../../../src/NativeNewinstanceChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE;;;;;;;;;GASG;AACH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,IAAI,IAAI,CAAC;IACjB,SAAS,IAAI,IAAI,CAAC;IAClB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,IAAI,IAAI,CAAC;IACzB,OAAO,IAAI,IAAI,CAAC;IAIhB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAAyE"}
|
|
@@ -37,7 +37,11 @@ export declare class NewinstanceChat {
|
|
|
37
37
|
* `uri`, pushes them through the SDK's upload pipeline, and bundles the
|
|
38
38
|
* uploaded reference into the next `sendMessage()`.
|
|
39
39
|
*/
|
|
40
|
-
attachFile(opts: AttachmentInput): Promise<
|
|
40
|
+
attachFile(opts: AttachmentInput): Promise<string>;
|
|
41
|
+
/** Remove a queued attachment; cancels its upload if still in flight. */
|
|
42
|
+
removeAttachment(id: string): void;
|
|
43
|
+
/** Remove every queued attachment and cancel in-flight uploads. */
|
|
44
|
+
clearAttachments(): void;
|
|
41
45
|
/**
|
|
42
46
|
* Subscribe to a native event. Returns an unsubscribe function — call it
|
|
43
47
|
* when your component unmounts to avoid leaks.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,eAAe,EACf,WAAW,EACX,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,SAAS,EACT,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,SAAS,CAAC;AASjB;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAElB,MAAM,EAAE,qBAAqB;IAIzC;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAI7B;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,uEAAuE;IACvE,QAAQ,IAAI,IAAI;IAIhB,sCAAsC;IACtC,SAAS,IAAI,IAAI;IAIjB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIrC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,eAAe,EACf,WAAW,EACX,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,SAAS,EACT,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,SAAS,CAAC;AASjB;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAElB,MAAM,EAAE,qBAAqB;IAIzC;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAI7B;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,uEAAuE;IACvE,QAAQ,IAAI,IAAI;IAIhB,sCAAsC;IACtC,SAAS,IAAI,IAAI;IAIjB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIrC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAOlD,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIlC,mEAAmE;IACnE,gBAAgB,IAAI,IAAI;IAIxB;;;OAGG;IACH,WAAW,CAAC,CAAC,SAAS,SAAS,EAC7B,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GACvB,MAAM,IAAI;IAQb;;;OAGG;IACH,OAAO,IAAI,IAAI;CAGhB"}
|
|
@@ -20,12 +20,63 @@ export interface ChatUser {
|
|
|
20
20
|
customerEmail?: string;
|
|
21
21
|
customerId?: string;
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
export type AttachmentSourceType = 'auto' | 'base64' | 'dataUri' | 'file' | 'contentUri' | 'url';
|
|
24
|
+
/**
|
|
25
|
+
* A programmatic attachment. Provide `source` + optional `sourceType`
|
|
26
|
+
* (`'auto'` detects data URIs, `content://`/`file://` URIs, absolute
|
|
27
|
+
* paths, http(s) URLs — remote URLs upload only when the native SDK is
|
|
28
|
+
* configured with `allowRemoteAttachmentUrls` — and raw base64).
|
|
29
|
+
* The legacy `uri` field keeps working and behaves like
|
|
30
|
+
* `source` + `sourceType: 'auto'`.
|
|
31
|
+
*/
|
|
24
32
|
export interface AttachmentInput {
|
|
25
|
-
/**
|
|
26
|
-
|
|
33
|
+
/** Attachment data or locator, interpreted per `sourceType`. */
|
|
34
|
+
source?: string;
|
|
35
|
+
sourceType?: AttachmentSourceType;
|
|
36
|
+
/** @deprecated Use `source`. Local file URI, still fully supported. */
|
|
37
|
+
uri?: string;
|
|
38
|
+
name: string;
|
|
39
|
+
/** Required unless the source itself carries one (data URIs, content URIs) or the extension resolves it. */
|
|
40
|
+
mimeType?: string;
|
|
41
|
+
/** Expected byte size — validated against the resolved data as a corruption guard. */
|
|
42
|
+
size?: number;
|
|
43
|
+
/** Free-form string metadata carried on the queued attachment. */
|
|
44
|
+
metadata?: Record<string, string>;
|
|
45
|
+
}
|
|
46
|
+
export type AttachmentStatus = 'queued' | 'uploading' | 'uploaded' | 'failed' | 'cancelled';
|
|
47
|
+
/** Streamed on `attachmentUpdated` for every attachment state/progress change. */
|
|
48
|
+
export interface AttachmentUpdate {
|
|
49
|
+
id: string;
|
|
27
50
|
name: string;
|
|
28
51
|
mimeType: string;
|
|
52
|
+
size: number;
|
|
53
|
+
status: AttachmentStatus;
|
|
54
|
+
/** 0..1 — real byte progress while uploading. */
|
|
55
|
+
progress: number;
|
|
56
|
+
/** Public URL once `status === 'uploaded'`. */
|
|
57
|
+
url?: string;
|
|
58
|
+
/** Failure reason once `status === 'failed'`. */
|
|
59
|
+
error?: string;
|
|
60
|
+
}
|
|
61
|
+
export type ChatCloseReason = 'close_button' | 'back_navigation' | 'gesture' | 'programmatic' | 'session_ended' | 'host_navigation';
|
|
62
|
+
/**
|
|
63
|
+
* Fired exactly once per chat presentation when the chat screen goes
|
|
64
|
+
* away, however it was dismissed. Never contains message contents,
|
|
65
|
+
* credentials, or attachment data.
|
|
66
|
+
*/
|
|
67
|
+
export interface ChatClosedEvent {
|
|
68
|
+
reason: ChatCloseReason;
|
|
69
|
+
initiator: 'user' | 'host' | 'sdk';
|
|
70
|
+
/** Unix milliseconds. */
|
|
71
|
+
timestamp: number;
|
|
72
|
+
conversationId?: string;
|
|
73
|
+
assignmentId?: string;
|
|
74
|
+
channel: string;
|
|
75
|
+
previousState: string;
|
|
76
|
+
unreadCount: number;
|
|
77
|
+
hasDraft: boolean;
|
|
78
|
+
pendingAttachmentCount: number;
|
|
79
|
+
metadata: Record<string, string>;
|
|
29
80
|
}
|
|
30
81
|
export type ConnectionState = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'offline';
|
|
31
82
|
export interface ChatMessage {
|
|
@@ -63,6 +114,8 @@ export interface EventMap {
|
|
|
63
114
|
connectionStateChanged: (state: ConnectionState) => void;
|
|
64
115
|
unreadCountChanged: (count: number) => void;
|
|
65
116
|
error: (e: NewinstanceChatError) => void;
|
|
117
|
+
attachmentUpdated: (attachment: AttachmentUpdate) => void;
|
|
118
|
+
chatClosed: (event: ChatClosedEvent) => void;
|
|
66
119
|
}
|
|
67
120
|
export type EventName = keyof EventMap;
|
|
68
121
|
export type EventHandler<K extends EventName> = EventMap[K];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yGAAyG;IACzG,SAAS,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACzB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-newinstance-chat",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "New instance LiveAndAiChat React Native SDK
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "New instance LiveAndAiChat React Native SDK \u2014 AI + live-agent chat, drop-in native chat screen for iOS and Android.",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -130,7 +130,9 @@
|
|
|
130
130
|
"preset": "@react-native/jest-preset",
|
|
131
131
|
"modulePathIgnorePatterns": [
|
|
132
132
|
"<rootDir>/example/node_modules",
|
|
133
|
-
"<rootDir>/lib/"
|
|
133
|
+
"<rootDir>/lib/",
|
|
134
|
+
"<rootDir>/example/ios",
|
|
135
|
+
"<rootDir>/example/android"
|
|
134
136
|
]
|
|
135
137
|
},
|
|
136
138
|
"release-it": {
|
|
@@ -162,5 +164,9 @@
|
|
|
162
164
|
"vite"
|
|
163
165
|
],
|
|
164
166
|
"version": "0.62.0"
|
|
167
|
+
},
|
|
168
|
+
"resolutions": {
|
|
169
|
+
"jest-environment-node": "^30.4.1",
|
|
170
|
+
"jest-mock": "^30.4.1"
|
|
165
171
|
}
|
|
166
172
|
}
|
|
@@ -18,7 +18,9 @@ export interface Spec extends TurboModule {
|
|
|
18
18
|
closeChat(): void;
|
|
19
19
|
sendMessage(text: string): void;
|
|
20
20
|
retryMessage(messageId: string): void;
|
|
21
|
-
attachFile(opts: Object): Promise<
|
|
21
|
+
attachFile(opts: Object): Promise<string>;
|
|
22
|
+
removeAttachment(id: string): void;
|
|
23
|
+
clearAttachments(): void;
|
|
22
24
|
destroy(): void;
|
|
23
25
|
|
|
24
26
|
// NativeEventEmitter on iOS calls these to track listener counts.
|
package/src/index.tsx
CHANGED
|
@@ -91,10 +91,23 @@ export class NewinstanceChat {
|
|
|
91
91
|
* `uri`, pushes them through the SDK's upload pipeline, and bundles the
|
|
92
92
|
* uploaded reference into the next `sendMessage()`.
|
|
93
93
|
*/
|
|
94
|
-
attachFile(opts: AttachmentInput): Promise<
|
|
94
|
+
attachFile(opts: AttachmentInput): Promise<string> {
|
|
95
|
+
if (!opts.source && !opts.uri) {
|
|
96
|
+
return Promise.reject(new Error('attachFile requires `source` (or the legacy `uri`)'));
|
|
97
|
+
}
|
|
95
98
|
return NativeNewinstanceChat.attachFile(opts);
|
|
96
99
|
}
|
|
97
100
|
|
|
101
|
+
/** Remove a queued attachment; cancels its upload if still in flight. */
|
|
102
|
+
removeAttachment(id: string): void {
|
|
103
|
+
NativeNewinstanceChat.removeAttachment(id);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Remove every queued attachment and cancel in-flight uploads. */
|
|
107
|
+
clearAttachments(): void {
|
|
108
|
+
NativeNewinstanceChat.clearAttachments();
|
|
109
|
+
}
|
|
110
|
+
|
|
98
111
|
/**
|
|
99
112
|
* Subscribe to a native event. Returns an unsubscribe function — call it
|
|
100
113
|
* when your component unmounts to avoid leaks.
|
package/src/types.ts
CHANGED
|
@@ -23,12 +23,85 @@ export interface ChatUser {
|
|
|
23
23
|
customerId?: string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
export type AttachmentSourceType =
|
|
27
|
+
| 'auto'
|
|
28
|
+
| 'base64'
|
|
29
|
+
| 'dataUri'
|
|
30
|
+
| 'file'
|
|
31
|
+
| 'contentUri'
|
|
32
|
+
| 'url';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A programmatic attachment. Provide `source` + optional `sourceType`
|
|
36
|
+
* (`'auto'` detects data URIs, `content://`/`file://` URIs, absolute
|
|
37
|
+
* paths, http(s) URLs — remote URLs upload only when the native SDK is
|
|
38
|
+
* configured with `allowRemoteAttachmentUrls` — and raw base64).
|
|
39
|
+
* The legacy `uri` field keeps working and behaves like
|
|
40
|
+
* `source` + `sourceType: 'auto'`.
|
|
41
|
+
*/
|
|
27
42
|
export interface AttachmentInput {
|
|
28
|
-
/**
|
|
29
|
-
|
|
43
|
+
/** Attachment data or locator, interpreted per `sourceType`. */
|
|
44
|
+
source?: string;
|
|
45
|
+
sourceType?: AttachmentSourceType;
|
|
46
|
+
/** @deprecated Use `source`. Local file URI, still fully supported. */
|
|
47
|
+
uri?: string;
|
|
48
|
+
name: string;
|
|
49
|
+
/** Required unless the source itself carries one (data URIs, content URIs) or the extension resolves it. */
|
|
50
|
+
mimeType?: string;
|
|
51
|
+
/** Expected byte size — validated against the resolved data as a corruption guard. */
|
|
52
|
+
size?: number;
|
|
53
|
+
/** Free-form string metadata carried on the queued attachment. */
|
|
54
|
+
metadata?: Record<string, string>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type AttachmentStatus =
|
|
58
|
+
| 'queued'
|
|
59
|
+
| 'uploading'
|
|
60
|
+
| 'uploaded'
|
|
61
|
+
| 'failed'
|
|
62
|
+
| 'cancelled';
|
|
63
|
+
|
|
64
|
+
/** Streamed on `attachmentUpdated` for every attachment state/progress change. */
|
|
65
|
+
export interface AttachmentUpdate {
|
|
66
|
+
id: string;
|
|
30
67
|
name: string;
|
|
31
68
|
mimeType: string;
|
|
69
|
+
size: number;
|
|
70
|
+
status: AttachmentStatus;
|
|
71
|
+
/** 0..1 — real byte progress while uploading. */
|
|
72
|
+
progress: number;
|
|
73
|
+
/** Public URL once `status === 'uploaded'`. */
|
|
74
|
+
url?: string;
|
|
75
|
+
/** Failure reason once `status === 'failed'`. */
|
|
76
|
+
error?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type ChatCloseReason =
|
|
80
|
+
| 'close_button'
|
|
81
|
+
| 'back_navigation'
|
|
82
|
+
| 'gesture'
|
|
83
|
+
| 'programmatic'
|
|
84
|
+
| 'session_ended'
|
|
85
|
+
| 'host_navigation';
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Fired exactly once per chat presentation when the chat screen goes
|
|
89
|
+
* away, however it was dismissed. Never contains message contents,
|
|
90
|
+
* credentials, or attachment data.
|
|
91
|
+
*/
|
|
92
|
+
export interface ChatClosedEvent {
|
|
93
|
+
reason: ChatCloseReason;
|
|
94
|
+
initiator: 'user' | 'host' | 'sdk';
|
|
95
|
+
/** Unix milliseconds. */
|
|
96
|
+
timestamp: number;
|
|
97
|
+
conversationId?: string;
|
|
98
|
+
assignmentId?: string;
|
|
99
|
+
channel: string;
|
|
100
|
+
previousState: string;
|
|
101
|
+
unreadCount: number;
|
|
102
|
+
hasDraft: boolean;
|
|
103
|
+
pendingAttachmentCount: number;
|
|
104
|
+
metadata: Record<string, string>;
|
|
32
105
|
}
|
|
33
106
|
|
|
34
107
|
export type ConnectionState =
|
|
@@ -80,6 +153,8 @@ export interface EventMap {
|
|
|
80
153
|
connectionStateChanged: (state: ConnectionState) => void;
|
|
81
154
|
unreadCountChanged: (count: number) => void;
|
|
82
155
|
error: (e: NewinstanceChatError) => void;
|
|
156
|
+
attachmentUpdated: (attachment: AttachmentUpdate) => void;
|
|
157
|
+
chatClosed: (event: ChatClosedEvent) => void;
|
|
83
158
|
}
|
|
84
159
|
|
|
85
160
|
export type EventName = keyof EventMap;
|