@moxtradeveloper/react-native-moxo-module 8.9.5
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/LICENSE +6 -0
- package/README.md +179 -0
- package/android/build.gradle +161 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/moxomodule/MoxoModuleModule.kt +287 -0
- package/android/src/main/java/com/moxomodule/MoxoModulePackage.kt +17 -0
- package/ios/MoxoModule-Bridging-Header.h +4 -0
- package/ios/MoxoModule.m +34 -0
- package/ios/MoxoModule.swift +149 -0
- package/ios/MoxoModule.xcodeproj/project.pbxproj +287 -0
- package/ios/MoxoModule.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
- package/ios/MoxoModuleBridge.h +17 -0
- package/ios/MoxoModuleBridge.m +13 -0
- package/package.json +164 -0
- package/react-native-moxo-module.podspec +36 -0
- package/src/index.tsx +136 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 john.hu
|
|
4
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
5
|
+
|
|
6
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# react-native-moxo-module
|
|
2
|
+
reactnative-moxo-module is based on native Moxo MEPSDK, for now it only provides ability to call native SDK functions.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm install react-native-moxo-module
|
|
8
|
+
```
|
|
9
|
+
#### Supported platforms
|
|
10
|
+
iOS: iOS 13, Xcode 14
|
|
11
|
+
|
|
12
|
+
Android:
|
|
13
|
+
|
|
14
|
+
### iOS Specific Steps
|
|
15
|
+
* Add moxo cocoapod repo as source into Podfile under your iOS project.
|
|
16
|
+
* Change pod deployment platform to iOS 13
|
|
17
|
+
|
|
18
|
+
Sample:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
|
22
|
+
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
|
23
|
+
#Add moxo source here
|
|
24
|
+
source 'https://maven.moxtra.com/repo/moxtra-specs.git'
|
|
25
|
+
|
|
26
|
+
#Change platform version if is not iOS 13
|
|
27
|
+
platform :ios, '13.0'
|
|
28
|
+
install! 'cocoapods', :deterministic_uuids => false
|
|
29
|
+
|
|
30
|
+
# Rest of the file.....
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
```js
|
|
35
|
+
import * as moxo from 'react-native-moxo-module';
|
|
36
|
+
|
|
37
|
+
// Setup domain
|
|
38
|
+
moxo.setup('myenv.moxo.com')
|
|
39
|
+
|
|
40
|
+
// Get access token
|
|
41
|
+
const response = await fetch('https://myenv.moxo.com/v1/core/oauth/token', {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
headers: {
|
|
44
|
+
Accept: 'application/json',
|
|
45
|
+
'Content-Type': 'application/json'
|
|
46
|
+
},
|
|
47
|
+
body: JSON.stringify({
|
|
48
|
+
client_id: 'my_clientid',
|
|
49
|
+
org_id: 'my_orgid',
|
|
50
|
+
unique_id: 'my_uniqueid',
|
|
51
|
+
client_secret: 'my_clientsecret'
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
const json = await response.json();
|
|
55
|
+
token = json.access_token
|
|
56
|
+
|
|
57
|
+
//Login and show moxo engagement platform window
|
|
58
|
+
moxo.link(token).then((success)=>{
|
|
59
|
+
if (result)
|
|
60
|
+
moxo.showMEPWindow();
|
|
61
|
+
}).catch((err=>{
|
|
62
|
+
console.log(`Link failed!:${err}`);
|
|
63
|
+
}))
|
|
64
|
+
```
|
|
65
|
+
### Notification
|
|
66
|
+
To enable notification feature, you'll need to integrate a notification module first, here we take [react-native-notifications](https://www.npmjs.com/package/react-native-notifications) for example, which can help to get device token and notification payload.
|
|
67
|
+
|
|
68
|
+
#### Register notification
|
|
69
|
+
Through react-native-notifications registerRemoteNotifications(), post user agreement, notification will be enabled for your app.
|
|
70
|
+
Call registerRemoteNotificationsRegistered() to get a device token.
|
|
71
|
+
Then pass token to moxo function ```registerNotification()``` will register notification to Moxo server.
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
Notifications.registerRemoteNotifications();
|
|
75
|
+
Notifications.events().registerRemoteNotificationsRegistered((event: Registered) => {
|
|
76
|
+
console.log("Device Token Received", event.deviceToken);
|
|
77
|
+
moxo.registerNotification(event.deviceToken).catch((err=>{
|
|
78
|
+
alertErr("Register notification failed", err);
|
|
79
|
+
}));
|
|
80
|
+
});
|
|
81
|
+
Notifications.events().registerRemoteNotificationsRegistrationFailed((event: RegistrationError) => {
|
|
82
|
+
console.error(event);
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Handle notification
|
|
87
|
+
For example, once notification received, and user tapped notification, react-native-notifications function registerNotificationOpened will be triggered with notification payload data. Then pass payload to moxo function ```parseNotification()``` like below:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
Notifications.events().registerNotificationOpened((notification: Notification, completion: () => void, action?: NotificationActionResponse) => {
|
|
91
|
+
console.log("Notification opened by device user", notification.payload);
|
|
92
|
+
if (action != undefined) {
|
|
93
|
+
console.log(`Notification opened with an action identifier: ${action.identifier} and response text: ${action.text}`);
|
|
94
|
+
}
|
|
95
|
+
moxo.parseNotification(notification.payload).then((result=>{
|
|
96
|
+
console.log(`Moxo notificaiton parse success: ${result}`);
|
|
97
|
+
completion();
|
|
98
|
+
})).catch(err => {
|
|
99
|
+
alertErr('Notification parse failed',err)
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
If is a Moxo notification, then callback of the ```parseNotification()``` would be triggered with info parameter. Usually info contains 'chat_id' or 'meet_id', depends one which kind of notification you received.
|
|
105
|
+
To do more, you can invoke function openChat(chat_id) to open target chat directly.
|
|
106
|
+
|
|
107
|
+
#### Sample notification payload
|
|
108
|
+
|
|
109
|
+
##### iOS
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"aps": {
|
|
114
|
+
"alert": {
|
|
115
|
+
"body": "cheng4: hi",
|
|
116
|
+
"action_loc_key": "BCA"
|
|
117
|
+
},
|
|
118
|
+
"sound": "default"
|
|
119
|
+
},
|
|
120
|
+
"request": {
|
|
121
|
+
"object": {
|
|
122
|
+
"board": {
|
|
123
|
+
"id": "CBPErkesrtOeFfURA6gusJAD",
|
|
124
|
+
"feeds": [{
|
|
125
|
+
"sequence": 191
|
|
126
|
+
}]
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"id": "359",
|
|
131
|
+
"moxtra": "",
|
|
132
|
+
"category": "message",
|
|
133
|
+
"board_id": "CBPErkesrtOeFfURA6gusJAD",
|
|
134
|
+
"moxtra": ""
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
##### Android
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
[
|
|
142
|
+
{
|
|
143
|
+
"count": "7",
|
|
144
|
+
"sound": "default",
|
|
145
|
+
"title": "rm1 Zhang",
|
|
146
|
+
"message": "rm1 Zhang: 1",
|
|
147
|
+
"additionalData": {
|
|
148
|
+
"feed_sequence": "3234",
|
|
149
|
+
"action_loc_key": "BCA",
|
|
150
|
+
"board_feed_unread_count": "3",
|
|
151
|
+
"moxtra": "",
|
|
152
|
+
"user_id": "CUxceIGfpXcHBna163lfFMD0",
|
|
153
|
+
"arg1": "rm1 Zhang",
|
|
154
|
+
"arg2": "1",
|
|
155
|
+
"arg3": "",
|
|
156
|
+
"loc_key": "BCM",
|
|
157
|
+
"request": {
|
|
158
|
+
"object": {
|
|
159
|
+
"board": {
|
|
160
|
+
"id": "CBPErkesrtOeFfURA6gusJAD",
|
|
161
|
+
"feeds": [{
|
|
162
|
+
"sequence": 3234
|
|
163
|
+
}]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"board_id": "CBPErkesrtOeFfURA6gusJAD",
|
|
168
|
+
"coldstart": false,
|
|
169
|
+
"board_name": "rm1 Zhang",
|
|
170
|
+
"foreground": true
|
|
171
|
+
}
|
|
172
|
+
}]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## License
|
|
176
|
+
|
|
177
|
+
ISC
|
|
178
|
+
|
|
179
|
+
---
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
// Buildscript is evaluated before everything else so we can't use getExtOrDefault
|
|
3
|
+
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['MoxoModule_kotlinVersion']
|
|
4
|
+
|
|
5
|
+
repositories {
|
|
6
|
+
google()
|
|
7
|
+
mavenCentral()
|
|
8
|
+
maven() {
|
|
9
|
+
url "https://maven.moxtra.com/nexus/content/groups/mep_public/"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
dependencies {
|
|
14
|
+
classpath 'com.android.tools.build:gradle:3.5.3'
|
|
15
|
+
// noinspection DifferentKotlinGradleVersion
|
|
16
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
rootProject.allprojects {
|
|
21
|
+
repositories {
|
|
22
|
+
google()
|
|
23
|
+
mavenCentral()
|
|
24
|
+
jcenter()
|
|
25
|
+
maven() {
|
|
26
|
+
url "https://maven.moxtra.com/nexus/content/groups/mep_public/"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
def isNewArchitectureEnabled() {
|
|
32
|
+
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
apply plugin: 'com.android.library'
|
|
36
|
+
apply plugin: 'kotlin-android'
|
|
37
|
+
|
|
38
|
+
if (isNewArchitectureEnabled()) {
|
|
39
|
+
apply plugin: 'com.facebook.react'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def getExtOrDefault(name) {
|
|
43
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['MoxoModule_' + name]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
def getExtOrIntegerDefault(name) {
|
|
47
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['MoxoModule_' + name]).toInteger()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
android {
|
|
51
|
+
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
|
52
|
+
|
|
53
|
+
defaultConfig {
|
|
54
|
+
minSdkVersion getExtOrIntegerDefault('minSdkVersion')
|
|
55
|
+
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
|
|
56
|
+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
57
|
+
}
|
|
58
|
+
buildTypes {
|
|
59
|
+
release {
|
|
60
|
+
minifyEnabled false
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
lintOptions {
|
|
65
|
+
disable 'GradleCompatible'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
compileOptions {
|
|
69
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
70
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
repositories {
|
|
76
|
+
mavenCentral()
|
|
77
|
+
google()
|
|
78
|
+
|
|
79
|
+
def found = false
|
|
80
|
+
def defaultDir = null
|
|
81
|
+
def androidSourcesName = 'React Native sources'
|
|
82
|
+
|
|
83
|
+
if (rootProject.ext.has('reactNativeAndroidRoot')) {
|
|
84
|
+
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
|
|
85
|
+
} else {
|
|
86
|
+
defaultDir = new File(
|
|
87
|
+
projectDir,
|
|
88
|
+
'/../../../node_modules/react-native/android'
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (defaultDir.exists()) {
|
|
93
|
+
maven {
|
|
94
|
+
url defaultDir.toString()
|
|
95
|
+
name androidSourcesName
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
|
|
99
|
+
found = true
|
|
100
|
+
} else {
|
|
101
|
+
def parentDir = rootProject.projectDir
|
|
102
|
+
|
|
103
|
+
1.upto(5, {
|
|
104
|
+
if (found) return true
|
|
105
|
+
parentDir = parentDir.parentFile
|
|
106
|
+
|
|
107
|
+
def androidSourcesDir = new File(
|
|
108
|
+
parentDir,
|
|
109
|
+
'node_modules/react-native'
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def androidPrebuiltBinaryDir = new File(
|
|
113
|
+
parentDir,
|
|
114
|
+
'node_modules/react-native/android'
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
if (androidPrebuiltBinaryDir.exists()) {
|
|
118
|
+
maven {
|
|
119
|
+
url androidPrebuiltBinaryDir.toString()
|
|
120
|
+
name androidSourcesName
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
|
|
124
|
+
found = true
|
|
125
|
+
} else if (androidSourcesDir.exists()) {
|
|
126
|
+
maven {
|
|
127
|
+
url androidSourcesDir.toString()
|
|
128
|
+
name androidSourcesName
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
|
|
132
|
+
found = true
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!found) {
|
|
138
|
+
throw new GradleException(
|
|
139
|
+
"${project.name}: unable to locate React Native android sources. " +
|
|
140
|
+
"Ensure you have you installed React Native as a dependency in your project and try again."
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
def kotlin_version = getExtOrDefault('kotlinVersion')
|
|
146
|
+
|
|
147
|
+
dependencies {
|
|
148
|
+
//noinspection GradleDynamicVersion
|
|
149
|
+
implementation "com.facebook.react:react-native:+"
|
|
150
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
151
|
+
implementation "com.moxtra:mep-sdk:8.9.5"
|
|
152
|
+
// From node_modules
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (isNewArchitectureEnabled()) {
|
|
156
|
+
react {
|
|
157
|
+
jsRootDir = file("../src/")
|
|
158
|
+
libraryName = "MoxoModule"
|
|
159
|
+
codegenJavaPackageName = "com.moxomodule"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
package com.moxomodule
|
|
2
|
+
|
|
3
|
+
import android.app.Application
|
|
4
|
+
import android.content.Intent
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import com.facebook.react.bridge.*
|
|
7
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
8
|
+
import com.moxtra.mepsdk.MEPClient
|
|
9
|
+
import com.moxtra.mepsdk.MEPClientDelegate
|
|
10
|
+
import com.moxtra.sdk.LinkConfig
|
|
11
|
+
import com.moxtra.sdk.common.ApiCallback
|
|
12
|
+
import org.json.JSONException
|
|
13
|
+
import org.json.JSONObject
|
|
14
|
+
|
|
15
|
+
class MoxoModuleModule(reactContext: ReactApplicationContext) :
|
|
16
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
17
|
+
|
|
18
|
+
private val TAG: String = "MoxoModuleModule"
|
|
19
|
+
|
|
20
|
+
private var mReactContext = reactContext
|
|
21
|
+
|
|
22
|
+
private val UNREAD_MSG_EVENT = "onUnreadMessageCountUpdated"
|
|
23
|
+
|
|
24
|
+
override fun getName(): String {
|
|
25
|
+
return NAME
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@ReactMethod
|
|
29
|
+
fun setup(domain: String?, options: String?) {
|
|
30
|
+
Log.d(TAG, "setup called with domain: $domain, options: $options")
|
|
31
|
+
var linkConfig: LinkConfig? = null
|
|
32
|
+
try {
|
|
33
|
+
if (domain != null) {
|
|
34
|
+
if (options != null && options is String) {
|
|
35
|
+
linkConfig = LinkConfig()
|
|
36
|
+
val jsonObject = JSONObject(options)
|
|
37
|
+
val certOrgName: String? = jsonObject.getString("certOrgName")
|
|
38
|
+
val certPublicKey: String? = jsonObject.getString("certPublicKey")
|
|
39
|
+
val ignoreBadCert: Boolean = jsonObject.getBoolean("ignoreBadCert")
|
|
40
|
+
linkConfig.setCertOrganization(certOrgName)
|
|
41
|
+
linkConfig.setCertPublicKey(certPublicKey)
|
|
42
|
+
linkConfig.setIgnoreBadCert(ignoreBadCert)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} catch (e: JSONException) {
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
mReactContext.runOnUiQueueThread {
|
|
50
|
+
MEPClient.initialize(mReactContext?.applicationContext as Application)
|
|
51
|
+
MEPClient.setupDomain(domain, linkConfig)
|
|
52
|
+
|
|
53
|
+
//setup callbacks
|
|
54
|
+
onUnreadMessageCountUpdated()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@ReactMethod
|
|
59
|
+
fun link(token: String?, promise: Promise?) {
|
|
60
|
+
Log.d(TAG, "link called with token: $token")
|
|
61
|
+
if (token == null || token.isEmpty()) {
|
|
62
|
+
promise?.reject("-1", "token is empty or null")
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
mReactContext.runOnUiQueueThread {
|
|
66
|
+
MEPClient.linkWithAccessToken(token, object : ApiCallback<Void?> {
|
|
67
|
+
override fun onCompleted(rlt: Void?) {
|
|
68
|
+
Log.d(
|
|
69
|
+
TAG,
|
|
70
|
+
"initWithAccessToken successful..."
|
|
71
|
+
)
|
|
72
|
+
promise?.resolve(true)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
override fun onError(errorCode: Int, errorMsg: String) {
|
|
76
|
+
Log.d(
|
|
77
|
+
TAG,
|
|
78
|
+
"initWithAccessToken failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
79
|
+
)
|
|
80
|
+
promise?.reject(
|
|
81
|
+
errorCode.toString(),
|
|
82
|
+
"initWithAccessToken failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@ReactMethod
|
|
91
|
+
fun showMEPWindow() {
|
|
92
|
+
Log.d(TAG, "showMEPWindow called...")
|
|
93
|
+
if (MEPClient.isLinked()) {
|
|
94
|
+
Log.d(TAG, "MEP is linked and showMEPWindow...")
|
|
95
|
+
MEPClient.showMEPWindow(mReactContext?.baseContext)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@ReactMethod
|
|
100
|
+
fun hideMEPWindow() {
|
|
101
|
+
Log.d(TAG, "hideMEPWindow called...")
|
|
102
|
+
if (MEPClient.isLinked()) {
|
|
103
|
+
Log.d(TAG, "MEP is linked and hideMEPWindow...")
|
|
104
|
+
MEPClient.destroyMEPWindow()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@ReactMethod
|
|
109
|
+
fun openChat(chatId: String?, feedSequence: Double?, promise: Promise?) {
|
|
110
|
+
Log.d(TAG, "openChat called...")
|
|
111
|
+
if (!MEPClient.isLinked()) {
|
|
112
|
+
promise?.reject("-1", "Not linked")
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
if (chatId?.isEmpty() == false) {
|
|
116
|
+
MEPClient.openChat(chatId, feedSequence?.toLong() ?: 0, object : ApiCallback<Void?> {
|
|
117
|
+
override fun onCompleted(rult: Void?) {
|
|
118
|
+
Log.d(TAG, "openChat successful...")
|
|
119
|
+
promise?.resolve(true)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
override fun onError(errorCode: Int, errorMsg: String) {
|
|
123
|
+
promise?.reject(
|
|
124
|
+
errorCode.toString(),
|
|
125
|
+
"openChat failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
} else {
|
|
130
|
+
promise?.reject("-1", "Invalid parameter")
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@ReactMethod
|
|
135
|
+
fun openRelation(options: ReadableMap?, promise: Promise?) {
|
|
136
|
+
Log.d(TAG, "openRelation called...")
|
|
137
|
+
if (!MEPClient.isLinked()) {
|
|
138
|
+
promise?.reject("-1", "Not linked")
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
val uniqueId: String? = options?.getString("uniqueId")
|
|
142
|
+
val email: String? = options?.getString("email")
|
|
143
|
+
val callback: ApiCallback<Void?> = object : ApiCallback<Void?> {
|
|
144
|
+
override fun onCompleted(rult: Void?) {
|
|
145
|
+
Log.d(TAG, "openRelationChat successful...")
|
|
146
|
+
promise?.resolve(true)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
override fun onError(errorCode: Int, errorMsg: String) {
|
|
150
|
+
promise?.reject(
|
|
151
|
+
errorCode.toString(),
|
|
152
|
+
"openRelationChat failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (uniqueId?.isEmpty() == false) {
|
|
157
|
+
MEPClient.openRelationChat(uniqueId, callback)
|
|
158
|
+
} else if (email?.isEmpty() == false) {
|
|
159
|
+
MEPClient.openRelationChatWithEmail(email, callback)
|
|
160
|
+
} else {
|
|
161
|
+
promise?.reject("-1", "Invalid parameter")
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private fun onUnreadMessageCountUpdated() {
|
|
166
|
+
Log.d(TAG, "onUnreadMessageCountUpdated called...")
|
|
167
|
+
val listener: MEPClientDelegate.OnUnreadMessageListener =
|
|
168
|
+
MEPClientDelegate.OnUnreadMessageListener { unreadCount ->
|
|
169
|
+
Log.d(TAG, "onUnreadMessageCountUpdated, count is $unreadCount")
|
|
170
|
+
sendEvent(mReactContext, UNREAD_MSG_EVENT, unreadCount)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
MEPClient.getClientDelegate().setOnUnreadMessageListener(listener)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private fun sendEvent(reactContext: ReactContext, eventName: String, params: Int?) {
|
|
177
|
+
reactContext
|
|
178
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
179
|
+
.emit(eventName, params)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@ReactMethod
|
|
183
|
+
fun addListener(eventName: String) {
|
|
184
|
+
Log.d(TAG, "addListener called...")
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@ReactMethod
|
|
188
|
+
fun removeListener(eventName: String) {
|
|
189
|
+
Log.d(TAG, "removeListener called...")
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@ReactMethod
|
|
193
|
+
fun registerNotification(deviceToken: String?) {
|
|
194
|
+
Log.d(
|
|
195
|
+
TAG,
|
|
196
|
+
"registerNotification called and token is " + (if (deviceToken == null) "null" else "not null")
|
|
197
|
+
)
|
|
198
|
+
if (deviceToken != null) {
|
|
199
|
+
MEPClient.registerNotification(deviceToken, object : ApiCallback<Void> {
|
|
200
|
+
override fun onCompleted(rlt: Void?) {
|
|
201
|
+
Log.d(TAG, "registerNotification called and completed...")
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
override fun onError(errorCode: Int, errorMsg: String?) {
|
|
205
|
+
Log.w(TAG, "registerNotification called but failed with $errorCode and $errorMsg ...")
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@ReactMethod
|
|
212
|
+
fun parseNotification(payload: ReadableMap?, promise: Promise?) {
|
|
213
|
+
Log.d(
|
|
214
|
+
TAG,
|
|
215
|
+
"parseNotification called and payload is " + (payload ?: "null")
|
|
216
|
+
)
|
|
217
|
+
if (payload == null) {
|
|
218
|
+
promise?.reject("-1", "payload data is null or empty")
|
|
219
|
+
return
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
var intent = map2Intent(payload)
|
|
223
|
+
if (MEPClient.isMEPNotification(intent)) {
|
|
224
|
+
MEPClient.parseRemoteNotification(
|
|
225
|
+
intent,
|
|
226
|
+
object : ApiCallback<Map<String, String>> {
|
|
227
|
+
override fun onCompleted(rlt: Map<String, String>) {
|
|
228
|
+
var jsonObject = JSONObject()
|
|
229
|
+
var keys = rlt.keys
|
|
230
|
+
for (key in keys) {
|
|
231
|
+
when (key) {
|
|
232
|
+
"chat_id", "feed_sequence", "session_id" -> jsonObject.put(key, rlt.getValue(key))
|
|
233
|
+
"meet_id" -> {
|
|
234
|
+
var meetId = rlt.getValue(key)
|
|
235
|
+
jsonObject.put("session_id", meetId)
|
|
236
|
+
}
|
|
237
|
+
else -> continue
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
promise?.resolve(jsonObject.toString())
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
override fun onError(errorCode: Int, errorMsg: String?) {
|
|
244
|
+
promise?.reject(
|
|
245
|
+
errorCode.toString(),
|
|
246
|
+
"parseRemoteNotification failed, errCode:$errorCode, errMsg:$errorMsg"
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
})
|
|
250
|
+
} else {
|
|
251
|
+
promise?.reject("-1", "It is not moxo payload!")
|
|
252
|
+
}
|
|
253
|
+
} catch (e: JSONException) {
|
|
254
|
+
e.printStackTrace()
|
|
255
|
+
promise?.reject("-1", "Invalid parameter: Not fcm payload")
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
private fun json2Intent(jsonObject: JSONObject?): Intent {
|
|
260
|
+
var intent = Intent()
|
|
261
|
+
var keys = jsonObject?.keys();
|
|
262
|
+
while (keys?.hasNext() == true) {
|
|
263
|
+
var key = keys.next()
|
|
264
|
+
intent.putExtra(key, jsonObject?.getString(key))
|
|
265
|
+
}
|
|
266
|
+
return intent
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private fun map2Intent(readableMap: ReadableMap?): Intent {
|
|
270
|
+
var intent = Intent()
|
|
271
|
+
var mapValues = readableMap?.entryIterator;
|
|
272
|
+
while (mapValues?.hasNext() == true) {
|
|
273
|
+
var mapEntry = mapValues.next()
|
|
274
|
+
when (mapEntry.value) {
|
|
275
|
+
is Double -> intent.putExtra(mapEntry.key, mapEntry.value as Double)
|
|
276
|
+
is String -> intent.putExtra(mapEntry.key, mapEntry.value as String)
|
|
277
|
+
is Map<*, *> -> intent.putExtra(mapEntry.key, mapEntry.value as String)
|
|
278
|
+
is ArrayList<*> -> intent.putExtra(mapEntry.key, mapEntry.value as ArrayList<*>)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return intent
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
companion object {
|
|
285
|
+
const val NAME = "MoxoModule"
|
|
286
|
+
}
|
|
287
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.moxomodule
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MoxoModulePackage : ReactPackage {
|
|
10
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
11
|
+
return listOf(MoxoModuleModule(reactContext))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
15
|
+
return emptyList()
|
|
16
|
+
}
|
|
17
|
+
}
|