@moxtradeveloper/react-native-moxo-module 10.11.2 → 10.13.1
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 +37 -1
- package/android/build.gradle +31 -137
- package/android/gradle.properties +3 -5
- package/android/src/main/java/com/moxomodule/MoxoModuleModule.kt +218 -330
- package/android/src/main/java/com/moxomodule/MoxoModulePackage.kt +17 -9
- package/ios/MoxoModule.h +5 -0
- package/ios/MoxoModule.mm +123 -0
- package/ios/MoxoModuleImpl.swift +153 -0
- package/package.json +39 -55
- package/react-native-moxo-module.podspec +6 -21
- package/scripts/download-mepsdk.js +19 -9
- package/src/NativeMoxoModule.ts +30 -0
- package/src/index.tsx +63 -53
- package/android/src/main/AndroidManifest.xml +0 -4
- package/ios/MoxoModule-Bridging-Header.h +0 -4
- package/ios/MoxoModule.m +0 -39
- package/ios/MoxoModule.swift +0 -183
- package/ios/MoxoModule.xcodeproj/project.pbxproj +0 -287
- package/ios/MoxoModuleBridge.h +0 -17
- package/ios/MoxoModuleBridge.m +0 -13
- package/scripts/bootstrap.js +0 -29
|
@@ -3,80 +3,54 @@ package com.moxomodule
|
|
|
3
3
|
import android.app.Application
|
|
4
4
|
import android.content.Intent
|
|
5
5
|
import android.util.Log
|
|
6
|
-
import com.facebook.react.bridge
|
|
7
|
-
import com.facebook.react.
|
|
6
|
+
import com.facebook.react.bridge.Arguments
|
|
7
|
+
import com.facebook.react.bridge.Promise
|
|
8
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
9
|
+
import com.facebook.react.bridge.ReadableMap
|
|
10
|
+
import com.facebook.react.bridge.ReadableType
|
|
11
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
8
12
|
import com.moxtra.mepsdk.MEPClient
|
|
9
13
|
import com.moxtra.mepsdk.MEPClientDelegate
|
|
10
14
|
import com.moxtra.mepsdk.data.MEPStartMeetOptions
|
|
11
15
|
import com.moxtra.sdk.LinkConfig
|
|
12
16
|
import com.moxtra.sdk.common.ActionListener
|
|
13
17
|
import com.moxtra.sdk.common.ApiCallback
|
|
14
|
-
import org.json.JSONArray
|
|
15
|
-
import org.json.JSONException
|
|
16
|
-
import org.json.JSONObject
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
@ReactModule(name = MoxoModuleModule.NAME)
|
|
20
|
+
class MoxoModuleModule(private val reactContext: ReactApplicationContext) :
|
|
21
|
+
NativeMoxoModuleSpec(reactContext) {
|
|
20
22
|
|
|
21
|
-
private
|
|
23
|
+
@Volatile private var tapWindowCloseEnabled = false
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
override fun getName(): String = NAME
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
private val TAP_WINDOW_CLOSE_EVENT = "tapWindowCloseEvent"
|
|
27
|
-
|
|
28
|
-
override fun getName(): String {
|
|
29
|
-
return NAME
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
@ReactMethod
|
|
33
|
-
fun setup(domain: String?, options: String?) {
|
|
27
|
+
override fun setup(domain: String, options: ReadableMap?) {
|
|
34
28
|
Log.d(TAG, "setup called with domain: $domain, options: $options")
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
if (!domain.isNullOrEmpty() && !options.isNullOrEmpty()) {
|
|
38
|
-
linkConfig = LinkConfig()
|
|
39
|
-
val jsonObject = JSONObject(options)
|
|
40
|
-
val certOrgName: String? = jsonObject.getString("certOrgName")
|
|
41
|
-
val certPublicKey: String? = jsonObject.getString("certPublicKey")
|
|
42
|
-
val ignoreBadCert: Boolean = jsonObject.getBoolean("ignoreBadCert")
|
|
43
|
-
linkConfig.certOrganization = certOrgName
|
|
44
|
-
linkConfig.certPublicKey = certPublicKey
|
|
45
|
-
linkConfig.isIgnoreBadCert = ignoreBadCert
|
|
46
|
-
}
|
|
47
|
-
} catch (e: JSONException) {
|
|
29
|
+
val linkConfig = if (domain.isNotEmpty() && options != null) toLinkConfig(options) else null
|
|
48
30
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
mReactContext.runOnUiQueueThread {
|
|
52
|
-
MEPClient.initialize(mReactContext?.applicationContext as Application)
|
|
31
|
+
runOnSdkThread {
|
|
32
|
+
MEPClient.initialize(reactContext.applicationContext as Application)
|
|
53
33
|
MEPClient.setupDomain(domain, linkConfig)
|
|
34
|
+
registerClientListeners()
|
|
54
35
|
}
|
|
55
36
|
}
|
|
56
37
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
promise?.reject("-1", "token is empty or null")
|
|
38
|
+
override fun link(token: String, promise: Promise) {
|
|
39
|
+
Log.d(TAG, "link called")
|
|
40
|
+
if (token.isEmpty()) {
|
|
41
|
+
promise.reject("-1", "token is empty or null")
|
|
62
42
|
return
|
|
63
43
|
}
|
|
64
|
-
|
|
44
|
+
runOnSdkThread(promise) {
|
|
65
45
|
MEPClient.linkWithAccessToken(token, object : ApiCallback<Void?> {
|
|
66
|
-
override fun onCompleted(
|
|
67
|
-
Log.d(
|
|
68
|
-
|
|
69
|
-
"initWithAccessToken successful..."
|
|
70
|
-
)
|
|
71
|
-
promise?.resolve(true)
|
|
46
|
+
override fun onCompleted(result: Void?) {
|
|
47
|
+
Log.d(TAG, "linkWithAccessToken successful...")
|
|
48
|
+
promise.resolve(true)
|
|
72
49
|
}
|
|
73
50
|
|
|
74
51
|
override fun onError(errorCode: Int, errorMsg: String) {
|
|
75
|
-
Log.d(
|
|
76
|
-
|
|
77
|
-
"initWithAccessToken failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
78
|
-
)
|
|
79
|
-
promise?.reject(
|
|
52
|
+
Log.d(TAG, "linkWithAccessToken failed, errCode:$errorCode, errMsg:$errorMsg")
|
|
53
|
+
promise.reject(
|
|
80
54
|
errorCode.toString(),
|
|
81
55
|
"initWithAccessToken failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
82
56
|
)
|
|
@@ -85,11 +59,10 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
|
|
|
85
59
|
}
|
|
86
60
|
}
|
|
87
61
|
|
|
88
|
-
|
|
89
|
-
fun unlink(keepNotification: Boolean) {
|
|
62
|
+
override fun unlink(keepNotification: Boolean) {
|
|
90
63
|
Log.d(TAG, "unlink called with keep notification $keepNotification")
|
|
91
|
-
val callback
|
|
92
|
-
override fun onCompleted(
|
|
64
|
+
val callback = object : ApiCallback<Void?> {
|
|
65
|
+
override fun onCompleted(result: Void?) {
|
|
93
66
|
Log.d(TAG, "unlink successful...")
|
|
94
67
|
}
|
|
95
68
|
|
|
@@ -97,369 +70,284 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
|
|
|
97
70
|
Log.w(TAG, "unlink failed with error code $errorCode and error message $errorMsg ...")
|
|
98
71
|
}
|
|
99
72
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
73
|
+
runOnSdkThread {
|
|
74
|
+
if (keepNotification) {
|
|
75
|
+
MEPClient.localUnlink(callback)
|
|
76
|
+
} else {
|
|
77
|
+
MEPClient.unlink(callback)
|
|
78
|
+
}
|
|
104
79
|
}
|
|
105
80
|
}
|
|
106
81
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
82
|
+
override fun getUnreadMessageCount(options: ReadableMap?, promise: Promise) {
|
|
83
|
+
runOnSdkThread(promise) {
|
|
84
|
+
promise.resolve(MEPClient.getUnreadMessageCount())
|
|
85
|
+
}
|
|
111
86
|
}
|
|
112
87
|
|
|
113
|
-
|
|
114
|
-
fun showMEPWindow() {
|
|
88
|
+
override fun showMEPWindow() {
|
|
115
89
|
Log.d(TAG, "showMEPWindow called...")
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
90
|
+
runOnSdkThread {
|
|
91
|
+
if (MEPClient.isLinked()) {
|
|
92
|
+
MEPClient.showMEPWindow(reactContext.baseContext)
|
|
93
|
+
}
|
|
119
94
|
}
|
|
120
95
|
}
|
|
121
96
|
|
|
122
|
-
|
|
123
|
-
fun hideMEPWindow() {
|
|
97
|
+
override fun hideMEPWindow() {
|
|
124
98
|
Log.d(TAG, "hideMEPWindow called...")
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
99
|
+
runOnSdkThread {
|
|
100
|
+
if (MEPClient.isLinked()) {
|
|
101
|
+
MEPClient.destroyMEPWindow()
|
|
102
|
+
}
|
|
128
103
|
}
|
|
129
104
|
}
|
|
130
105
|
|
|
131
|
-
|
|
132
|
-
fun openChat(chatId: String?, feedSequence: Double?, promise: Promise?) {
|
|
106
|
+
override fun openChat(chatId: String, feedSequence: Double?, promise: Promise) {
|
|
133
107
|
Log.d(TAG, "openChat called...")
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
108
|
+
runOnSdkThread(promise) {
|
|
109
|
+
if (!MEPClient.isLinked()) {
|
|
110
|
+
promise.reject("-1", "Not linked")
|
|
111
|
+
return@runOnSdkThread
|
|
112
|
+
}
|
|
113
|
+
if (chatId.isEmpty()) {
|
|
114
|
+
promise.reject("-1", "Invalid parameter")
|
|
115
|
+
return@runOnSdkThread
|
|
116
|
+
}
|
|
139
117
|
MEPClient.openChat(chatId, feedSequence?.toLong() ?: 0, object : ApiCallback<Void?> {
|
|
140
|
-
override fun onCompleted(
|
|
118
|
+
override fun onCompleted(result: Void?) {
|
|
141
119
|
Log.d(TAG, "openChat successful...")
|
|
142
|
-
promise
|
|
120
|
+
promise.resolve(true)
|
|
143
121
|
}
|
|
144
122
|
|
|
145
123
|
override fun onError(errorCode: Int, errorMsg: String) {
|
|
146
|
-
promise
|
|
147
|
-
errorCode.toString(),
|
|
148
|
-
"openChat failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
149
|
-
)
|
|
124
|
+
promise.reject(errorCode.toString(), "openChat failed, errCode:$errorCode, errMsg:$errorMsg")
|
|
150
125
|
}
|
|
151
126
|
})
|
|
152
|
-
} else {
|
|
153
|
-
promise?.reject("-1", "Invalid parameter")
|
|
154
127
|
}
|
|
155
128
|
}
|
|
156
129
|
|
|
157
|
-
|
|
158
|
-
fun openRelation(options: ReadableMap?, promise: Promise?) {
|
|
130
|
+
override fun openRelation(options: ReadableMap, promise: Promise) {
|
|
159
131
|
Log.d(TAG, "openRelation called...")
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
val uniqueId: String? = options?.getString("uniqueId")
|
|
165
|
-
val email: String? = options?.getString("email")
|
|
166
|
-
val callback: ApiCallback<Void?> = object : ApiCallback<Void?> {
|
|
167
|
-
override fun onCompleted(rult: Void?) {
|
|
132
|
+
val uniqueId = options.stringOrNull("uniqueId")
|
|
133
|
+
val email = options.stringOrNull("email")
|
|
134
|
+
val callback = object : ApiCallback<Void?> {
|
|
135
|
+
override fun onCompleted(result: Void?) {
|
|
168
136
|
Log.d(TAG, "openRelationChat successful...")
|
|
169
|
-
promise
|
|
137
|
+
promise.resolve(true)
|
|
170
138
|
}
|
|
171
139
|
|
|
172
140
|
override fun onError(errorCode: Int, errorMsg: String) {
|
|
173
|
-
promise
|
|
141
|
+
promise.reject(
|
|
174
142
|
errorCode.toString(),
|
|
175
143
|
"openRelationChat failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
176
144
|
)
|
|
177
145
|
}
|
|
178
146
|
}
|
|
179
|
-
|
|
180
|
-
MEPClient.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
} else {
|
|
184
|
-
promise?.reject("-1", "Invalid parameter")
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
private fun onUnreadMessageCountUpdated() {
|
|
189
|
-
Log.d(TAG, "onUnreadMessageCountUpdated called...")
|
|
190
|
-
val listener: MEPClientDelegate.OnUnreadMessageListener =
|
|
191
|
-
MEPClientDelegate.OnUnreadMessageListener { unreadCount ->
|
|
192
|
-
Log.d(TAG, "onUnreadMessageCountUpdated, count is $unreadCount")
|
|
193
|
-
sendEvent(mReactContext, UNREAD_MSG_EVENT, unreadCount)
|
|
147
|
+
runOnSdkThread(promise) {
|
|
148
|
+
if (!MEPClient.isLinked()) {
|
|
149
|
+
promise.reject("-1", "Not linked")
|
|
150
|
+
return@runOnSdkThread
|
|
194
151
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
private fun onTapWindowClose() {
|
|
200
|
-
Log.d(TAG, "onTapWindowClose called...")
|
|
201
|
-
val listener: ActionListener<Void> = ActionListener { _, _ ->
|
|
202
|
-
run {
|
|
203
|
-
Log.d(TAG, "onTapWindowClose button clicked...")
|
|
204
|
-
sendEvent(mReactContext, TAP_WINDOW_CLOSE_EVENT, null)
|
|
152
|
+
when {
|
|
153
|
+
!uniqueId.isNullOrEmpty() -> MEPClient.openRelationChat(uniqueId, callback)
|
|
154
|
+
!email.isNullOrEmpty() -> MEPClient.openRelationChatWithEmail(email, callback)
|
|
155
|
+
else -> promise.reject("-1", "Invalid parameter")
|
|
205
156
|
}
|
|
206
157
|
}
|
|
207
|
-
MEPClient.getClientDelegate().setOnCloseButtonListener(listener)
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
private fun sendEvent(reactContext: ReactContext, eventName: String, params: Any?) {
|
|
211
|
-
reactContext
|
|
212
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
213
|
-
.emit(eventName, params)
|
|
214
158
|
}
|
|
215
159
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
onTapWindowClose()
|
|
160
|
+
override fun registerNotification(deviceToken: String, promise: Promise) {
|
|
161
|
+
Log.d(TAG, "registerNotification called and token is " + if (deviceToken.isEmpty()) "empty" else "not empty")
|
|
162
|
+
if (deviceToken.isEmpty()) {
|
|
163
|
+
promise.reject("-1", "device token is empty")
|
|
164
|
+
return
|
|
222
165
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
fun removeListeners(count: Integer) {
|
|
227
|
-
Log.d(TAG, "removeListeners called...")
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
@ReactMethod
|
|
231
|
-
fun registerNotification(deviceToken: String?) {
|
|
232
|
-
Log.d(
|
|
233
|
-
TAG,
|
|
234
|
-
"registerNotification called and token is " + (if (deviceToken == null) "null" else "not null")
|
|
235
|
-
)
|
|
236
|
-
if (!deviceToken.isNullOrEmpty()) {
|
|
237
|
-
MEPClient.registerNotification(
|
|
238
|
-
deviceToken,
|
|
239
|
-
null, null, null,
|
|
240
|
-
object : ApiCallback<Void> {
|
|
241
|
-
override fun onCompleted(rlt: Void?) {
|
|
166
|
+
runOnSdkThread(promise) {
|
|
167
|
+
MEPClient.registerNotification(deviceToken, null, null, null, object : ApiCallback<Void> {
|
|
168
|
+
override fun onCompleted(result: Void?) {
|
|
242
169
|
Log.d(TAG, "registerNotification called and completed...")
|
|
170
|
+
promise.resolve(true)
|
|
243
171
|
}
|
|
244
172
|
|
|
245
173
|
override fun onError(errorCode: Int, errorMsg: String?) {
|
|
246
174
|
Log.w(TAG, "registerNotification called but failed with $errorCode and $errorMsg ...")
|
|
175
|
+
promise.reject(errorCode.toString(), "registerNotification failed, errCode:$errorCode, errMsg:$errorMsg")
|
|
247
176
|
}
|
|
248
177
|
})
|
|
249
178
|
}
|
|
250
179
|
}
|
|
251
180
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
object : ApiCallback<Map<String, String>> {
|
|
268
|
-
override fun onCompleted(rlt: Map<String, String>) {
|
|
269
|
-
var jsonObject = JSONObject()
|
|
270
|
-
var keys = rlt.keys
|
|
271
|
-
for (key in keys) {
|
|
272
|
-
when (key) {
|
|
273
|
-
"chat_id", "feed_sequence", "session_id" -> jsonObject.put(key, rlt.getValue(key))
|
|
274
|
-
"meet_id" -> {
|
|
275
|
-
var meetId = rlt.getValue(key)
|
|
276
|
-
jsonObject.put("session_id", meetId)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
else -> continue
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
promise?.resolve(json2WritableNativeMap(jsonObject))
|
|
181
|
+
override fun parseNotification(payload: ReadableMap, promise: Promise) {
|
|
182
|
+
Log.d(TAG, "parseNotification called and payload is $payload")
|
|
183
|
+
val intent = toIntent(payload)
|
|
184
|
+
runOnSdkThread(promise) {
|
|
185
|
+
if (!MEPClient.isMEPNotification(intent)) {
|
|
186
|
+
promise.reject("-1", "It is not moxo payload!")
|
|
187
|
+
return@runOnSdkThread
|
|
188
|
+
}
|
|
189
|
+
MEPClient.parseRemoteNotification(intent, object : ApiCallback<Map<String, String>> {
|
|
190
|
+
override fun onCompleted(result: Map<String, String>) {
|
|
191
|
+
val map = Arguments.createMap()
|
|
192
|
+
for ((key, value) in result) {
|
|
193
|
+
when (key) {
|
|
194
|
+
"chat_id", "feed_sequence", "session_id" -> map.putString(key, value)
|
|
195
|
+
"meet_id" -> map.putString("session_id", value)
|
|
283
196
|
}
|
|
197
|
+
}
|
|
198
|
+
promise.resolve(map)
|
|
199
|
+
}
|
|
284
200
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
} else {
|
|
293
|
-
promise?.reject("-1", "It is not moxo payload!")
|
|
294
|
-
}
|
|
295
|
-
} catch (e: JSONException) {
|
|
296
|
-
e.printStackTrace()
|
|
297
|
-
promise?.reject("-1", "Invalid parameter: Not fcm payload")
|
|
201
|
+
override fun onError(errorCode: Int, errorMsg: String?) {
|
|
202
|
+
promise.reject(
|
|
203
|
+
errorCode.toString(),
|
|
204
|
+
"parseRemoteNotification failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
})
|
|
298
208
|
}
|
|
299
209
|
}
|
|
300
210
|
|
|
301
|
-
|
|
302
|
-
fun showMeetRinger(sessionId: String, promise: Promise?) {
|
|
211
|
+
override fun showMeetRinger(sessionId: String, promise: Promise) {
|
|
303
212
|
Log.d(TAG, "show meet ringer called with session id $sessionId")
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (sessionId.isEmpty()) {
|
|
309
|
-
promise?.reject("-1", "session id is empty!")
|
|
310
|
-
return
|
|
311
|
-
}
|
|
312
|
-
MEPClient.showMeetRinger(sessionId, object : ApiCallback<Void> {
|
|
313
|
-
override fun onCompleted(rlt: Void?) {
|
|
314
|
-
Log.d(TAG, "show meet ringer success ...")
|
|
315
|
-
promise?.resolve("Show meet ringer success")
|
|
213
|
+
runOnSdkThread(promise) {
|
|
214
|
+
if (!MEPClient.isLinked()) {
|
|
215
|
+
promise.reject("-1", "Not linked")
|
|
216
|
+
return@runOnSdkThread
|
|
316
217
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
promise?.reject("-1", "Show meet ringer failed with $errorCode and $errorMsg")
|
|
218
|
+
if (sessionId.isEmpty()) {
|
|
219
|
+
promise.reject("-1", "session id is empty!")
|
|
220
|
+
return@runOnSdkThread
|
|
321
221
|
}
|
|
322
|
-
|
|
222
|
+
MEPClient.showMeetRinger(sessionId, object : ApiCallback<Void> {
|
|
223
|
+
override fun onCompleted(result: Void?) {
|
|
224
|
+
Log.d(TAG, "show meet ringer success ...")
|
|
225
|
+
promise.resolve("Show meet ringer success")
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
override fun onError(errorCode: Int, errorMsg: String?) {
|
|
229
|
+
Log.w(TAG, "show meet ringer failed with $errorCode and $errorMsg ...")
|
|
230
|
+
promise.reject("-1", "Show meet ringer failed with $errorCode and $errorMsg")
|
|
231
|
+
}
|
|
232
|
+
})
|
|
233
|
+
}
|
|
323
234
|
}
|
|
324
235
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
236
|
+
override fun changeLanguage(language: String) {
|
|
237
|
+
Log.d(TAG, "changeLanguage called with $language ...")
|
|
238
|
+
if (language.isEmpty()) {
|
|
239
|
+
return
|
|
240
|
+
}
|
|
241
|
+
runOnSdkThread {
|
|
242
|
+
MEPClient.changeLanguage(language)
|
|
330
243
|
}
|
|
331
244
|
}
|
|
332
245
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
promise?.reject("-1", "Topic is empty!")
|
|
246
|
+
override fun startMeet(topic: String, options: ReadableMap?, promise: Promise) {
|
|
247
|
+
Log.d(TAG, "startMeet called with topic: $topic, options: $options")
|
|
248
|
+
if (topic.isEmpty()) {
|
|
249
|
+
promise.reject("-1", "Topic is empty!")
|
|
338
250
|
return
|
|
339
251
|
}
|
|
340
252
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
253
|
+
val meetOptions = MEPStartMeetOptions().apply { this.topic = topic }
|
|
254
|
+
if (options != null) {
|
|
255
|
+
options.stringOrNull("chat_id")?.let { meetOptions.chatID = it }
|
|
256
|
+
options.booleanOrNull("auto_join_audio")?.let { meetOptions.setAutoJoinAudio(it) }
|
|
257
|
+
options.booleanOrNull("auto_start_video")?.let { meetOptions.setAutoStartVideo(it) }
|
|
258
|
+
options.booleanOrNull("auto_recording")?.let { meetOptions.isAutoRecordingEnabled = it }
|
|
259
|
+
options.booleanOrNull("instant_call")?.let { meetOptions.setInstantCall(it) }
|
|
260
|
+
if (options.hasKey("unique_ids") && options.getType("unique_ids") == ReadableType.Array) {
|
|
261
|
+
val ids = options.getArray("unique_ids")
|
|
262
|
+
if (ids != null) {
|
|
263
|
+
meetOptions.uniqueIDs = ArrayList((0 until ids.size()).mapNotNull { ids.getString(it) })
|
|
347
264
|
}
|
|
348
|
-
promise?.resolve(json2WritableNativeMap(jsonObject))
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
override fun onError(errorCode: Int, errorMsg: String?) {
|
|
352
|
-
Log.w(TAG, "startMeet failed with $errorCode and $errorMsg ...")
|
|
353
|
-
promise?.reject(errorCode.toString(), "startMeet failed with $errorCode and $errorMsg")
|
|
354
265
|
}
|
|
355
266
|
}
|
|
356
267
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
while (mapValues?.hasNext() == true) {
|
|
363
|
-
var mapEntry = mapValues.next()
|
|
364
|
-
when (mapEntry.key) {
|
|
365
|
-
"chat_id" -> mepStartMeetOptions.chatID = mapEntry.value.toString()
|
|
366
|
-
"auto_join_audio" -> mepStartMeetOptions.setAutoJoinAudio(mapEntry.value as Boolean)
|
|
367
|
-
"auto_start_video" -> mepStartMeetOptions.setAutoStartVideo(mapEntry.value as Boolean)
|
|
368
|
-
"auto_recording" -> mepStartMeetOptions.isAutoRecordingEnabled = mapEntry.value as Boolean
|
|
369
|
-
"instant_call" -> mepStartMeetOptions.setInstantCall(mapEntry.value as Boolean)
|
|
370
|
-
"unique_ids" -> {
|
|
371
|
-
val ids = mapEntry.value
|
|
372
|
-
if (ids is ReadableNativeArray) {
|
|
373
|
-
ids.toArrayList().also { mepStartMeetOptions.uniqueIDs = it as ArrayList<String> }
|
|
374
|
-
}
|
|
268
|
+
runOnSdkThread(promise) {
|
|
269
|
+
MEPClient.startMeet(meetOptions, object : ApiCallback<String> {
|
|
270
|
+
override fun onCompleted(sessionId: String) {
|
|
271
|
+
Log.d(TAG, "startMeet success ...")
|
|
272
|
+
promise.resolve(Arguments.createMap().apply { putString("session_id", sessionId) })
|
|
375
273
|
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
274
|
|
|
379
|
-
|
|
275
|
+
override fun onError(errorCode: Int, errorMsg: String?) {
|
|
276
|
+
Log.w(TAG, "startMeet failed with $errorCode and $errorMsg ...")
|
|
277
|
+
promise.reject(errorCode.toString(), "startMeet failed with $errorCode and $errorMsg")
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
}
|
|
380
281
|
}
|
|
381
282
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
intent.putExtra(key, jsonObject?.getString(key))
|
|
283
|
+
override fun enableTapWindowCloseEvent() {
|
|
284
|
+
Log.d(TAG, "enableTapWindowCloseEvent called...")
|
|
285
|
+
tapWindowCloseEnabled = true
|
|
286
|
+
runOnSdkThread {
|
|
287
|
+
registerCloseButtonListener()
|
|
388
288
|
}
|
|
389
|
-
return intent
|
|
390
289
|
}
|
|
391
290
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
is ArrayList<*> -> intent.putExtra(mapEntry.key, mapEntry.value as ArrayList<*>)
|
|
291
|
+
// SDK calls share the queue that setup() initializes MEPClient on, so they
|
|
292
|
+
// always run after it. SDK exceptions are reported instead of crashing the app.
|
|
293
|
+
private fun runOnSdkThread(promise: Promise? = null, block: () -> Unit) {
|
|
294
|
+
reactContext.runOnUiQueueThread {
|
|
295
|
+
try {
|
|
296
|
+
block()
|
|
297
|
+
} catch (e: RuntimeException) {
|
|
298
|
+
Log.w(TAG, "MEPClient call failed", e)
|
|
299
|
+
promise?.reject("-1", e.message, e)
|
|
402
300
|
}
|
|
403
301
|
}
|
|
404
|
-
return intent
|
|
405
302
|
}
|
|
406
303
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
is JSONObject -> {
|
|
413
|
-
writableMap.putMap(key, json2WritableNativeMap(value))
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
is JSONArray -> {
|
|
417
|
-
writableMap.putArray(key, json2WritableNativeArray(value))
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
is String -> {
|
|
421
|
-
writableMap.putString(key, value)
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
is Boolean -> {
|
|
425
|
-
writableMap.putBoolean(key, value)
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
is Double -> {
|
|
429
|
-
writableMap.putDouble(key, value)
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
is Int -> {
|
|
433
|
-
writableMap.putInt(key, value)
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
is Long -> {
|
|
437
|
-
writableMap.putDouble(key, value.toDouble());
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
else -> {
|
|
441
|
-
writableMap.putString(key, value.toString())
|
|
442
|
-
}
|
|
443
|
-
}
|
|
304
|
+
private fun registerClientListeners() {
|
|
305
|
+
MEPClient.getClientDelegate().setOnUnreadMessageListener(
|
|
306
|
+
MEPClientDelegate.OnUnreadMessageListener { unreadCount ->
|
|
307
|
+
Log.d(TAG, "onUnreadMessageCountUpdated, count is $unreadCount")
|
|
308
|
+
emitOnUnreadMessageCountUpdated(unreadCount.toDouble())
|
|
444
309
|
}
|
|
310
|
+
)
|
|
311
|
+
if (tapWindowCloseEnabled) {
|
|
312
|
+
registerCloseButtonListener()
|
|
445
313
|
}
|
|
446
|
-
return writableMap
|
|
447
314
|
}
|
|
448
315
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
316
|
+
// Setting this listener replaces the SDK's default close behavior, so it is
|
|
317
|
+
// only installed once JS subscribes to onTapWindowClose.
|
|
318
|
+
private fun registerCloseButtonListener() {
|
|
319
|
+
MEPClient.getClientDelegate().setOnCloseButtonListener(ActionListener<Void> { _, _ ->
|
|
320
|
+
Log.d(TAG, "onTapWindowClose button clicked...")
|
|
321
|
+
emitOnTapWindowClose()
|
|
322
|
+
})
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
private fun toLinkConfig(options: ReadableMap): LinkConfig = LinkConfig().apply {
|
|
326
|
+
options.stringOrNull("certOrgName")?.let { certOrganization = it }
|
|
327
|
+
options.stringOrNull("certPublicKey")?.let { certPublicKey = it }
|
|
328
|
+
options.booleanOrNull("ignoreBadCert")?.let { isIgnoreBadCert = it }
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Only top-level strings and numbers are passed on to the SDK.
|
|
332
|
+
private fun toIntent(payload: ReadableMap): Intent {
|
|
333
|
+
val intent = Intent()
|
|
334
|
+
for ((key, value) in payload.toHashMap()) {
|
|
335
|
+
when (value) {
|
|
336
|
+
is String -> intent.putExtra(key, value)
|
|
337
|
+
is Double -> intent.putExtra(key, value)
|
|
457
338
|
}
|
|
458
339
|
}
|
|
459
|
-
return
|
|
340
|
+
return intent
|
|
460
341
|
}
|
|
461
342
|
|
|
343
|
+
private fun ReadableMap.stringOrNull(key: String): String? =
|
|
344
|
+
if (hasKey(key) && getType(key) == ReadableType.String) getString(key) else null
|
|
345
|
+
|
|
346
|
+
private fun ReadableMap.booleanOrNull(key: String): Boolean? =
|
|
347
|
+
if (hasKey(key) && getType(key) == ReadableType.Boolean) getBoolean(key) else null
|
|
348
|
+
|
|
462
349
|
companion object {
|
|
463
|
-
const val NAME =
|
|
350
|
+
const val NAME = NativeMoxoModuleSpec.NAME
|
|
351
|
+
private const val TAG = "MoxoModuleModule"
|
|
464
352
|
}
|
|
465
353
|
}
|