@amplitude/plugin-engagement-react-native 0.1.1-alpha.3 → 0.1.1-alpha.6

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
@@ -16,8 +16,27 @@ npm install @amplitude/plugin-engagement-react-native
16
16
  npm install @react-native-async-storage/async-storage
17
17
  ```
18
18
 
19
+ Add the source for the `AmplitudeEngagementSwift` pod to your Podfile:
20
+ ```rb
21
+ target '<your appname>' do
22
+ ...
23
+
24
+ pod "AmplitudeEngagementSwift", :git => "https://github.com/amplitude/Amplitude-Engagement-Swift"
25
+
26
+ ...
27
+ end
28
+ ```
29
+
30
+ Re-run `pod install` in the `ios` directory:
31
+ ```sh
32
+ $ cd ios
33
+ $ bundle exec pod install
34
+ ```
35
+
19
36
  ## Usage
20
37
 
38
+ ### Setup code
39
+
21
40
  Setup by adding the plugin and calling “init” as usual:
22
41
 
23
42
  ```
@@ -48,6 +67,14 @@ Linking.addEventListener('url', async ({ url }) => {
48
67
  });
49
68
  ```
50
69
 
70
+ ### Linking setup
71
+ If you don't already have it set up, please follow this guide to enable deep-linking support in your React Native app in addition to adding the above Linking code:
72
+ https://reactnative.dev/docs/linking#enabling-deep-links
73
+
74
+ Then, following the Alpha Onboarding guide to setup the "scheme" for the deep links in your Android and iOS projects.
75
+
76
+ ### Boot
77
+
51
78
  Finally, “boot” with the user’s ID:
52
79
 
53
80
  ```
@@ -74,6 +74,14 @@ def kotlin_version = getExtOrDefault("kotlinVersion")
74
74
  dependencies {
75
75
  implementation "com.facebook.react:react-android"
76
76
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
77
+
78
+ // Amplitude Engagement SDK
79
+ implementation "com.amplitude:amplitude-engagement-android:1.0.8"
80
+
81
+ // Amplitude Analytics SDK (required dependency)
82
+ implementation "com.amplitude:analytics-android:1.+"
83
+
84
+ //implementation files('/Users/jared/workspace/_2-amplitude-gs-mobile-sdk/android/engagement/build/outputs/aar/engagement-debug.aar')
77
85
  }
78
86
 
79
87
  react {
@@ -1,16 +1,180 @@
1
1
  package com.amplitude.pluginengagementreactnative
2
2
 
3
+ import android.app.Activity
4
+ import android.app.Application
5
+ import android.content.Intent
6
+ import android.os.Bundle
7
+ import android.util.Log
8
+ import androidx.core.net.toUri
9
+ import com.amplitude.android.engagement.AmplitudeEngagement
10
+ import com.amplitude.android.engagement.AmplitudeInitOptions
11
+ import com.amplitude.android.engagement.ui.theme.ThemeMode
12
+ import com.amplitude.core.events.BaseEvent
13
+ import com.facebook.react.bridge.ActivityEventListener
14
+ import com.facebook.react.bridge.Arguments
15
+ import com.facebook.react.bridge.Callback
16
+ import com.facebook.react.bridge.LifecycleEventListener
3
17
  import com.facebook.react.bridge.ReactApplicationContext
18
+ import com.facebook.react.bridge.ReadableMap
19
+ import com.facebook.react.bridge.WritableArray
4
20
  import com.facebook.react.module.annotations.ReactModule
21
+ import kotlinx.coroutines.Dispatchers
22
+ import kotlinx.coroutines.runBlocking
23
+ import java.util.concurrent.ConcurrentHashMap
5
24
 
6
25
  @ReactModule(name = PluginEngagementReactNativeModule.NAME)
7
- class PluginEngagementReactNativeModule(reactContext: ReactApplicationContext) :
26
+ class PluginEngagementReactNativeModule(val reactContext: ReactApplicationContext) :
8
27
  NativePluginEngagementReactNativeSpec(reactContext) {
9
28
 
29
+ private data class InstanceInfo(val apiKey: String, val instance: AmplitudeEngagement)
30
+
31
+ private var instances = ConcurrentHashMap<Double, InstanceInfo>()
32
+ private var _id: Double = 0.0
33
+
10
34
  override fun getName(): String {
11
35
  return NAME
12
36
  }
13
37
 
38
+ override fun newInstance(apiKey: String): Double {
39
+ val existingId = instances.entries.firstOrNull { it.value.apiKey == apiKey }?.key
40
+ if (existingId != null) {
41
+ return existingId
42
+ }
43
+
44
+ return synchronized(this) {
45
+ runBlocking(Dispatchers.Main) {
46
+ val amplitudeEngagement = AmplitudeEngagement(reactContext, apiKey, AmplitudeInitOptions())
47
+
48
+ // The React Native environment seems to have a different activity management lifecycle;
49
+ // so we need to register our own listener to get the current activity.
50
+ amplitudeEngagement.setCurrentActivity(reactContext.currentActivity)
51
+ val lifecycleEventListener: LifecycleEventListener = object : LifecycleEventListener {
52
+ override fun onHostResume() {
53
+ amplitudeEngagement.setCurrentActivity(reactContext.currentActivity)
54
+ }
55
+
56
+ override fun onHostPause() {
57
+ }
58
+
59
+ override fun onHostDestroy() {
60
+ }
61
+ }
62
+
63
+ reactContext.addLifecycleEventListener(lifecycleEventListener)
64
+
65
+ _id++
66
+ val id = _id
67
+ instances[id] = InstanceInfo(
68
+ apiKey,
69
+ amplitudeEngagement
70
+ )
71
+
72
+ id
73
+ }
74
+ }
75
+ }
76
+
77
+ override fun boot(id: Double, userId: String, deviceId: String) {
78
+ val instance = instances[id]?.instance ?: return
79
+
80
+ runBlocking(Dispatchers.Main) {
81
+ Log.d("PluginEngagementReactNativeModule", "boot: $userId, $deviceId")
82
+ instance.boot(userId, deviceId)
83
+ }
84
+ }
85
+
86
+ override fun setThemeMode(id: Double, themeMode: String?) {
87
+ val instance = instances[id]?.instance ?: return
88
+
89
+ runBlocking(Dispatchers.Main) {
90
+ if (themeMode != null) {
91
+ instance.setThemeMode(ThemeMode.valueOf(themeMode))
92
+ }
93
+ }
94
+ }
95
+
96
+ override fun reset(id: Double, key: String, stepIndex: Double) {
97
+ val instance = instances[id]?.instance ?: return
98
+ runBlocking(Dispatchers.Main) {
99
+ instance.reset(key, stepIndex.toInt())
100
+ }
101
+ }
102
+
103
+ override fun list(id: Double): WritableArray {
104
+ val writableArray = Arguments.createArray()
105
+ val instance = instances[id]?.instance ?: return writableArray
106
+ runBlocking(Dispatchers.Main) {
107
+ val guidesAndSurveysList = instance.list()
108
+ guidesAndSurveysList.forEach { guide ->
109
+ Log.d("PluginEngagementReactNativeModule", "list: $guide")
110
+ val map = Arguments.createMap();
111
+ map.putInt("id", guide.id);
112
+ map.putString("title", guide.title);
113
+ map.putString("status", guide.status);
114
+ map.putInt("step", guide.step);
115
+ writableArray.pushMap(map);
116
+ }
117
+ }
118
+ return writableArray
119
+ }
120
+
121
+ override fun show(id: Double, key: String, stepIndex: Double) {
122
+ val instance = instances[id]?.instance ?: return
123
+ runBlocking(Dispatchers.Main) {
124
+ instance.show(key, stepIndex.toInt())
125
+ }
126
+ }
127
+
128
+ override fun screen(id: Double, screenName: String) {
129
+ val instance = instances[id]?.instance ?: return
130
+ runBlocking(Dispatchers.Main) {
131
+ instance.screen(screenName)
132
+ }
133
+ }
134
+
135
+ override fun closeAll(id: Double) {
136
+ val instance = instances[id]?.instance ?: return
137
+ runBlocking(Dispatchers.Main) {
138
+ instance.closeAll()
139
+ }
140
+ }
141
+
142
+ override fun forwardEvent(id: Double, event: ReadableMap) {
143
+ val instance = instances[id]?.instance ?: return
144
+ val baseEvent = BaseEvent()
145
+ baseEvent.eventType = event.getString("event_type") ?: return
146
+ baseEvent.eventId = event.getDouble("event_id").toLong()
147
+ baseEvent.platform = event.getString("platform")
148
+ baseEvent.osName = event.getString("os_name")
149
+ baseEvent.osVersion = event.getString("os_version")
150
+ baseEvent.eventProperties = event.getMap("event_properties")?.toHashMap()
151
+ baseEvent.groupProperties = event.getMap("group_properties")?.toHashMap()
152
+ baseEvent.groups = event.getMap("groups")?.toHashMap()
153
+ baseEvent.userProperties = event.getMap("user_properties")?.toHashMap()
154
+ Log.d("PluginEngagementReactNativeModule", "forwardEvent: $baseEvent")
155
+ runBlocking(Dispatchers.Main) {
156
+ instance.forwardEvent(baseEvent)
157
+ }
158
+ }
159
+
160
+ override fun addCallback(id: Double, key: String, func: Callback) {
161
+ val instance = instances[id]?.instance ?: return
162
+ runBlocking(Dispatchers.Main) {
163
+ instance.addCallback(key) { func.invoke() }
164
+ }
165
+ }
166
+
167
+ override fun handleURL(id: Double, url: String): Boolean {
168
+ val instance = instances[id]?.instance ?: return false
169
+
170
+ val uri = url.toUri()
171
+ val intent = Intent(Intent.ACTION_VIEW, uri)
172
+
173
+ return runBlocking(Dispatchers.Main) {
174
+ instance.handlePreviewLinkIntent(intent)
175
+ }
176
+ }
177
+
14
178
 
15
179
  companion object {
16
180
  const val NAME = "PluginEngagementReactNative"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amplitude/plugin-engagement-react-native",
3
- "version": "0.1.1-alpha.3",
3
+ "version": "0.1.1-alpha.6",
4
4
  "description": "Amplitude Engagement plugin for React Native",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",