@moxtradeveloper/react-native-moxo-module 9.8.6 → 10.1.3

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 CHANGED
@@ -56,6 +56,25 @@ install! 'cocoapods', :deterministic_uuids => false
56
56
  # Rest of the file.....
57
57
  ```
58
58
 
59
+ Exception:
60
+ ![pod_error](./docs/pod_error.png)
61
+ if you getting this error post moxo plugin installation, please also add master cocoapod repo as source into Podfile under your iOS project.
62
+ Usually is https://github.com/CocoaPods/Specs.git
63
+
64
+ ```ruby
65
+ require_relative '../node_modules/react-native/scripts/react_native_pods'
66
+ require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
67
+ #Add moxo source here
68
+ source 'https://maven.moxtra.com/repo/moxtra-specs.git'
69
+ source 'https://github.com/CocoaPods/Specs.git'
70
+
71
+ #Change platform version if is not iOS 13
72
+ platform :ios, '13.0'
73
+ install! 'cocoapods', :deterministic_uuids => false
74
+
75
+ # Rest of the file.....
76
+ ```
77
+
59
78
  ## Initialization
60
79
 
61
80
  ### Login
@@ -148,7 +148,7 @@ dependencies {
148
148
  //noinspection GradleDynamicVersion
149
149
  implementation "com.facebook.react:react-native:+"
150
150
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
151
- implementation "com.moxtra:mep-sdk:9.8.6"
151
+ implementation "com.moxtra:mep-sdk:10.1.3"
152
152
  // From node_modules
153
153
  }
154
154
 
@@ -1,5 +1,5 @@
1
- MoxoModule_kotlinVersion=1.9.0
1
+ MoxoModule_kotlinVersion=1.7.0
2
2
  MoxoModule_minSdkVersion=21
3
- MoxoModule_targetSdkVersion=34
4
- MoxoModule_compileSdkVersion=34
3
+ MoxoModule_targetSdkVersion=31
4
+ MoxoModule_compileSdkVersion=31
5
5
  MoxoModule_ndkversion=21.4.7075529
@@ -7,8 +7,11 @@ import com.facebook.react.bridge.*
7
7
  import com.facebook.react.modules.core.DeviceEventManagerModule
8
8
  import com.moxtra.mepsdk.MEPClient
9
9
  import com.moxtra.mepsdk.MEPClientDelegate
10
+ import com.moxtra.mepsdk.data.MEPStartMeetOptions
10
11
  import com.moxtra.sdk.LinkConfig
12
+ import com.moxtra.sdk.common.ActionListener
11
13
  import com.moxtra.sdk.common.ApiCallback
14
+ import org.json.JSONArray
12
15
  import org.json.JSONException
13
16
  import org.json.JSONObject
14
17
 
@@ -20,7 +23,8 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
20
23
  private var mReactContext = reactContext
21
24
 
22
25
  private val UNREAD_MSG_EVENT = "onUnreadMessageCountUpdated"
23
-
26
+ private val TAP_WINDOW_CLOSE_EVENT = "tapWindowCloseEvent"
27
+
24
28
  override fun getName(): String {
25
29
  return NAME
26
30
  }
@@ -30,17 +34,15 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
30
34
  Log.d(TAG, "setup called with domain: $domain, options: $options")
31
35
  var linkConfig: LinkConfig? = null
32
36
  try {
33
- if (domain != null) {
34
- if (options != null && options is String) {
37
+ if (!domain.isNullOrEmpty() && !options.isNullOrEmpty()) {
35
38
  linkConfig = LinkConfig()
36
39
  val jsonObject = JSONObject(options)
37
40
  val certOrgName: String? = jsonObject.getString("certOrgName")
38
41
  val certPublicKey: String? = jsonObject.getString("certPublicKey")
39
42
  val ignoreBadCert: Boolean = jsonObject.getBoolean("ignoreBadCert")
40
- linkConfig.setCertOrganization(certOrgName)
41
- linkConfig.setCertPublicKey(certPublicKey)
42
- linkConfig.setIgnoreBadCert(ignoreBadCert)
43
- }
43
+ linkConfig.certOrganization = certOrgName
44
+ linkConfig.certPublicKey = certPublicKey
45
+ linkConfig.isIgnoreBadCert = ignoreBadCert
44
46
  }
45
47
  } catch (e: JSONException) {
46
48
 
@@ -49,16 +51,13 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
49
51
  mReactContext.runOnUiQueueThread {
50
52
  MEPClient.initialize(mReactContext?.applicationContext as Application)
51
53
  MEPClient.setupDomain(domain, linkConfig)
52
-
53
- //setup callbacks
54
- onUnreadMessageCountUpdated()
55
54
  }
56
55
  }
57
56
 
58
57
  @ReactMethod
59
58
  fun link(token: String?, promise: Promise?) {
60
59
  Log.d(TAG, "link called with token: $token")
61
- if (token == null || token.isEmpty()) {
60
+ if (token.isNullOrEmpty()) {
62
61
  promise?.reject("-1", "token is empty or null")
63
62
  return
64
63
  }
@@ -136,7 +135,7 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
136
135
  promise?.reject("-1", "Not linked")
137
136
  return
138
137
  }
139
- if (chatId?.isEmpty() == false) {
138
+ if (!chatId.isNullOrEmpty()) {
140
139
  MEPClient.openChat(chatId, feedSequence?.toLong() ?: 0, object : ApiCallback<Void?> {
141
140
  override fun onCompleted(rult: Void?) {
142
141
  Log.d(TAG, "openChat successful...")
@@ -177,9 +176,9 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
177
176
  )
178
177
  }
179
178
  }
180
- if (uniqueId?.isEmpty() == false) {
179
+ if (!uniqueId.isNullOrEmpty()) {
181
180
  MEPClient.openRelationChat(uniqueId, callback)
182
- } else if (email?.isEmpty() == false) {
181
+ } else if (!email.isNullOrEmpty()) {
183
182
  MEPClient.openRelationChatWithEmail(email, callback)
184
183
  } else {
185
184
  promise?.reject("-1", "Invalid parameter")
@@ -196,8 +195,19 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
196
195
 
197
196
  MEPClient.getClientDelegate().setOnUnreadMessageListener(listener)
198
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)
205
+ }
206
+ }
207
+ MEPClient.getClientDelegate().setOnCloseButtonListener(listener)
208
+ }
199
209
 
200
- private fun sendEvent(reactContext: ReactContext, eventName: String, params: Int?) {
210
+ private fun sendEvent(reactContext: ReactContext, eventName: String, params: Any?) {
201
211
  reactContext
202
212
  .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
203
213
  .emit(eventName, params)
@@ -206,6 +216,10 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
206
216
  @ReactMethod
207
217
  fun addListener(eventName: String) {
208
218
  Log.d(TAG, "addListener called...")
219
+ when (eventName) {
220
+ TAP_WINDOW_CLOSE_EVENT ->
221
+ onTapWindowClose()
222
+ }
209
223
  }
210
224
 
211
225
  @ReactMethod
@@ -219,7 +233,7 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
219
233
  TAG,
220
234
  "registerNotification called and token is " + (if (deviceToken == null) "null" else "not null")
221
235
  )
222
- if (deviceToken != null) {
236
+ if (!deviceToken.isNullOrEmpty()) {
223
237
  MEPClient.registerNotification(
224
238
  deviceToken,
225
239
  null, null, null,
@@ -265,7 +279,7 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
265
279
  else -> continue
266
280
  }
267
281
  }
268
- promise?.resolve(jsonObject.toString())
282
+ promise?.resolve(json2WritableNativeMap(jsonObject))
269
283
  }
270
284
 
271
285
  override fun onError(errorCode: Int, errorMsg: String?) {
@@ -316,6 +330,55 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
316
330
  }
317
331
  }
318
332
 
333
+ @ReactMethod
334
+ fun startMeet(topic: String, options: ReadableMap?, promise: Promise?) {
335
+ Log.d(TAG, "startMeet called with topic: $topic, options:" + options?.toString())
336
+ if (topic.isNullOrEmpty()) {
337
+ promise?.reject("-1", "Topic is empty!")
338
+ return
339
+ }
340
+
341
+ var callback: ApiCallback<String> = object : ApiCallback<String> {
342
+ override fun onCompleted(sessionId: String) {
343
+ Log.d(TAG, "startMeet success ...")
344
+ val jsonObject = JSONObject()
345
+ with(jsonObject) {
346
+ put("session_id", sessionId)
347
+ }
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
+ }
355
+ }
356
+
357
+ //map to MEPStartMeetOptions
358
+ var mepStartMeetOptions = MEPStartMeetOptions()
359
+ mepStartMeetOptions.topic = topic
360
+
361
+ var mapValues = options?.entryIterator;
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
+ }
375
+ }
376
+ }
377
+ }
378
+
379
+ MEPClient.startMeet(mepStartMeetOptions, callback)
380
+ }
381
+
319
382
  private fun json2Intent(jsonObject: JSONObject?): Intent {
320
383
  var intent = Intent()
321
384
  var keys = jsonObject?.keys();
@@ -341,6 +404,61 @@ class MoxoModuleModule(reactContext: ReactApplicationContext) :
341
404
  return intent
342
405
  }
343
406
 
407
+ private fun json2WritableNativeMap(jsonObject: JSONObject?): WritableNativeMap {
408
+ val writableMap = WritableNativeMap()
409
+ jsonObject?.let {
410
+ for (key in jsonObject.keys()) {
411
+ when (val value = jsonObject.get(key)) {
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
+ }
444
+ }
445
+ }
446
+ return writableMap
447
+ }
448
+
449
+ private fun json2WritableNativeArray(jsonArray: JSONArray?): WritableNativeArray {
450
+ val writableArray = WritableNativeArray()
451
+ jsonArray?.let {
452
+ for (i in 0 until jsonArray.length()) {
453
+ val jsonObject = jsonArray.get(i)
454
+ if (jsonObject is JSONObject) {
455
+ writableArray.pushMap(json2WritableNativeMap(jsonObject))
456
+ }
457
+ }
458
+ }
459
+ return writableArray
460
+ }
461
+
344
462
  companion object {
345
463
  const val NAME = "MoxoModule"
346
464
  }
package/ios/MoxoModule.m CHANGED
@@ -16,6 +16,10 @@ RCT_EXTERN_METHOD(openChat:(NSString *)chatId
16
16
  RCT_EXTERN_METHOD(openRelation:(NSDictionary *)user
17
17
  withResolver:(RCTPromiseResolveBlock)resolve
18
18
  withRejecter:(RCTPromiseRejectBlock)reject)
19
+ RCT_EXTERN_METHOD(startMeet:(NSString *)topic
20
+ options:(NSDictionary *)options
21
+ withResolver:(RCTPromiseResolveBlock)resolve
22
+ withRejecter:(RCTPromiseRejectBlock)reject)
19
23
  RCT_EXTERN_METHOD(getUnreadMessageCount:(NSDictionary *)options
20
24
  withResolver:(RCTPromiseResolveBlock)resolve
21
25
  withRejecter:(RCTPromiseRejectBlock)reject)
@@ -3,6 +3,7 @@ class MoxoModule: RCTEventEmitter, MEPClientDelegate {
3
3
  let default_error_code = 999
4
4
  let default_error_message = "invalid parameters"
5
5
  let unread_message_event = "onUnreadMessageCountUpdated"
6
+ let tap_close_event = "tapWindowCloseEvent"
6
7
  private var onUnreadMessageCountUpdated:RCTResponseSenderBlock? = nil;
7
8
 
8
9
  override class func moduleName() -> String! {
@@ -102,6 +103,28 @@ class MoxoModule: RCTEventEmitter, MEPClientDelegate {
102
103
  let ret = MEPClient.sharedInstance().getUnreadMessageCount()
103
104
  resolve(ret)
104
105
  }
106
+
107
+ @objc(startMeet:options:withResolver:withRejecter:)
108
+ func startMeet(topic: String, options:Dictionary<String, Any>,resolve:@escaping RCTPromiseResolveBlock, reject:@escaping RCTPromiseRejectBlock) {
109
+ DispatchQueue.main.async {
110
+ let meetOption = MEPStartMeetOptions()
111
+ meetOption.topic = topic
112
+ meetOption.chatID = options["chat_id"] as? String ?? nil
113
+ meetOption.uniqueIDs = options["unique_ids"] as? Array ?? nil
114
+ meetOption.autoJoinAudio = options["auto_join_audio"] as? Bool ?? true
115
+ meetOption.autoStartVideo = options["auto_start_video"] as? Bool ?? false
116
+ meetOption.autoRecording = options["auto_recording"] as? Bool ?? false
117
+ meetOption.instantCall = options["instant_call"] as? Bool ?? false
118
+ MEPClient.sharedInstance().startMeet(withOption: meetOption) { error, meetId in
119
+ if let err = error as? NSError {
120
+ reject("\(err.code)", err.localizedDescription, error)
121
+ } else {
122
+ let ret = ["session_id": meetId]
123
+ resolve(ret)
124
+ }
125
+ }
126
+ }
127
+ }
105
128
 
106
129
  //MARK: Notification
107
130
  @objc(registerNotification:withResolver:withRejecter:)
@@ -133,9 +156,13 @@ class MoxoModule: RCTEventEmitter, MEPClientDelegate {
133
156
  sendEvent(withName: unread_message_event, body: unreadCount)
134
157
  }
135
158
 
159
+ func client(_ client: MEPClient, didTapClose sender: Any?) {
160
+ sendEvent(withName: tap_close_event, body: nil)
161
+ }
162
+
136
163
  //MARK: RCTBridgeModule
137
164
  override func supportedEvents() -> [String]! {
138
- return [unread_message_event]
165
+ return [unread_message_event, tap_close_event]
139
166
  }
140
167
  }
141
168
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moxtradeveloper/react-native-moxo-module",
3
- "version": "9.8.6",
3
+ "version": "10.1.3",
4
4
  "description": "Plugin for adding Moxtra services to react-native Apps.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -57,6 +57,7 @@
57
57
  },
58
58
  "devDependencies": {
59
59
  "@react-native-community/eslint-config": "^3.0.2",
60
+ "@release-it/conventional-changelog": "^5.0.0",
60
61
  "@types/jest": "^28.1.2",
61
62
  "@types/react": "~17.0.21",
62
63
  "@types/react-native": "0.70.0",
@@ -70,12 +71,10 @@
70
71
  "react": "18.1.0",
71
72
  "react-native": "0.70.6",
72
73
  "react-native-builder-bob": "^0.20.0",
74
+ "release-it": "^15.0.0",
73
75
  "typedoc": "^0.24.8",
74
76
  "typescript": "^4.5.2"
75
77
  },
76
- "overrides": {
77
- "semver": "^7.5.3"
78
- },
79
78
  "resolutions": {
80
79
  "@types/react": "17.0.21"
81
80
  },
@@ -99,6 +98,23 @@
99
98
  "@commitlint/config-conventional"
100
99
  ]
101
100
  },
101
+ "release-it": {
102
+ "git": {
103
+ "commitMessage": "chore: release ${version}",
104
+ "tagName": "v${version}"
105
+ },
106
+ "npm": {
107
+ "publish": true
108
+ },
109
+ "github": {
110
+ "release": true
111
+ },
112
+ "plugins": {
113
+ "@release-it/conventional-changelog": {
114
+ "preset": "angular"
115
+ }
116
+ }
117
+ },
102
118
  "eslintConfig": {
103
119
  "root": true,
104
120
  "extends": [
@@ -143,4 +159,4 @@
143
159
  ]
144
160
  ]
145
161
  }
146
- }
162
+ }
@@ -17,7 +17,7 @@ Pod::Spec.new do |s|
17
17
  s.public_header_files = 'ios/*.h'
18
18
  s.swift_version = '5.0'
19
19
  s.dependency "React-Core"
20
- s.dependency 'MEPSDKDylib', '~> 9.8.6'
20
+ s.dependency 'MEPSDKDylib', '~> 10.1.3'
21
21
 
22
22
  # Don't install the dependencies when we run `pod install` in the old architecture.
23
23
  if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
package/src/index.tsx CHANGED
@@ -5,6 +5,7 @@ const LINKING_ERROR =
5
5
  '- You rebuilt the app after installing the package\n' +
6
6
  '- You are not using Expo Go\n';
7
7
  const UNREAD_MSG_EVENT = "onUnreadMessageCountUpdated";
8
+ const TAP_WINDOW_CLOSE_EVENT = "tapWindowCloseEvent";
8
9
 
9
10
  const MoxoModule = NativeModules.MoxoModule
10
11
  ? NativeModules.MoxoModule
@@ -149,3 +150,34 @@ export function showMeetRinger(sessionId:string): Promise<object> {
149
150
  return MoxoModule.showMeetRinger(sessionId);
150
151
  }
151
152
 
153
+ /**
154
+ * Start meet with options.
155
+ *
156
+ * @param topic Topic of meeting
157
+ * @param options Start meet options.
158
+ * {
159
+ * "unique_ids": ["unique_id_a", "unique_id_b", ...], //user unique id array
160
+ * "chat_id":"chat_id", //id of chat where this meeting will start
161
+ * "auto_join_audio": true/false, //default is true
162
+ * "auto_start_video": true/false, //default is false
163
+ * "auto_recording": true/false, //default is false
164
+ * "instant_call": true/false //default is false, set to true to enable call UI with dialer tone when start a meeting with only one user.
165
+ * //this option only works when unique_ids got only one user, and autoJoinAudio set to true.
166
+ * }
167
+ * @returns session id if start meet successfully:
168
+ * {
169
+ * "session_id": "255576178"
170
+ * }
171
+ */
172
+ export function startMeet(topic: string, options?: object): Promise<object> {
173
+ return MoxoModule.startMeet(topic, options);
174
+ }
175
+
176
+ /**
177
+ * Set the callback when user tap close button on MEP window
178
+ * You should call hideMEPWindow() to hide MEP window in this callback if you want to hide MEP window
179
+ */
180
+ export function onTapWindowClose(callback: () => void) {
181
+ MoxoEventEmitter.addListener(TAP_WINDOW_CLOSE_EVENT, callback);
182
+ }
183
+