react-native-nami-sdk 3.3.0-beta.8 → 3.3.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/.prettierrc +4 -0
- package/README.md +9 -9
- package/android/README.md +3 -2
- package/android/build.gradle +27 -19
- package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/android/gradlew +0 -0
- package/android/src/main/AndroidManifest.xml +1 -1
- package/android/src/main/java/com/namiml/reactnative/Constants.kt +3 -0
- package/android/src/main/java/com/namiml/reactnative/NamiBridgeModule.kt +97 -0
- package/android/src/main/java/com/namiml/reactnative/NamiBridgePackage.java +140 -0
- package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiCampaignManagerBridge.kt +25 -32
- package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiCustomerManagerBridge.kt +14 -6
- package/android/src/main/java/com/{nami/reactlibrary/NamiEntitlementManagerBridgeModule.kt → namiml/reactnative/NamiEntitlementManagerBridge.kt} +18 -8
- package/android/src/main/java/com/namiml/reactnative/NamiFlowManagerBridge.kt +79 -0
- package/android/src/main/java/com/namiml/reactnative/NamiPaywallManagerBridgeModule.kt +197 -0
- package/android/src/main/java/com/namiml/reactnative/NamiPurchaseManagerBridge.kt +107 -0
- package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiUtil.kt +61 -23
- package/{index.d.ts → dist/index.d.ts} +0 -2
- package/dist/specs/NativeNami.d.ts +16 -0
- package/dist/specs/NativeNamiCampaignManager.d.ts +82 -0
- package/dist/specs/NativeNamiCustomerManager.d.ts +29 -0
- package/dist/specs/NativeNamiEntitlementManager.d.ts +45 -0
- package/dist/specs/NativeNamiFlowManager.d.ts +10 -0
- package/dist/specs/NativeNamiPaywallManager.d.ts +72 -0
- package/dist/specs/NativeNamiPurchaseManager.d.ts +27 -0
- package/dist/src/Nami.d.ts +6 -0
- package/dist/src/NamiCampaignManager.d.ts +29 -0
- package/{src → dist/src}/NamiCustomerManager.d.ts +11 -13
- package/dist/src/NamiEntitlementManager.d.ts +13 -0
- package/dist/src/NamiFlowManager.d.ts +13 -0
- package/dist/src/NamiPaywallManager.d.ts +30 -0
- package/dist/src/NamiPurchaseManager.d.ts +16 -0
- package/dist/src/transformers.d.ts +3 -0
- package/{src → dist/src}/types.d.ts +36 -6
- package/dist/src/version.d.ts +5 -0
- package/index.ts +0 -2
- package/ios/Nami.m +9 -87
- package/ios/Nami.swift +89 -0
- package/ios/NamiCampaignManagerBridge.m +3 -3
- package/ios/NamiCampaignManagerBridge.swift +47 -61
- package/ios/NamiCustomerManager.m +2 -2
- package/ios/NamiCustomerManager.swift +11 -3
- package/ios/NamiEntitlementManagerBridge.m +2 -3
- package/ios/NamiEntitlementManagerBridge.swift +47 -39
- package/ios/NamiFlowManagerBridge.m +4 -2
- package/ios/NamiFlowManagerBridge.swift +27 -6
- package/ios/NamiPaywallManagerBridge.m +3 -3
- package/ios/NamiPaywallManagerBridge.swift +24 -6
- package/ios/NamiPurchaseManagerBridge.m +3 -4
- package/ios/NamiPurchaseManagerBridge.swift +14 -15
- package/ios/RNNami-Bridging-Header.h +1 -3
- package/package.json +20 -8
- package/react-native-config.js +9 -0
- package/react-native-nami-sdk.podspec +17 -3
- package/scripts/generate-version.ts +18 -0
- package/specs/NativeNami.ts +17 -0
- package/specs/NativeNamiCampaignManager.ts +94 -0
- package/specs/NativeNamiCustomerManager.ts +37 -0
- package/specs/NativeNamiEntitlementManager.ts +54 -0
- package/specs/NativeNamiFlowManager.ts +13 -0
- package/specs/NativeNamiPaywallManager.ts +86 -0
- package/specs/NativeNamiPurchaseManager.ts +32 -0
- package/src/Nami.ts +31 -18
- package/src/NamiCampaignManager.ts +57 -53
- package/src/NamiCustomerManager.ts +55 -81
- package/src/NamiEntitlementManager.ts +49 -36
- package/src/NamiFlowManager.ts +42 -44
- package/src/NamiPaywallManager.ts +84 -139
- package/src/NamiPurchaseManager.ts +66 -70
- package/src/transformers.ts +21 -0
- package/src/types.ts +40 -7
- package/src/version.ts +5 -0
- package/tsconfig.json +24 -22
- package/.eslintignore +0 -3
- package/.eslintrc.js +0 -52
- package/.github/workflows/CI.yaml +0 -341
- package/.github/workflows/app_prod.yaml +0 -387
- package/.github/workflows/app_stg.yaml +0 -398
- package/.github/workflows/build.yml +0 -70
- package/.pre-commit-config.yaml +0 -24
- package/.prettierrc.js +0 -7
- package/android/src/main/java/com/nami/reactlibrary/Constants.kt +0 -3
- package/android/src/main/java/com/nami/reactlibrary/NamiBridgeModule.kt +0 -141
- package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +0 -51
- package/android/src/main/java/com/nami/reactlibrary/NamiFlowManagerBridge.kt +0 -60
- package/android/src/main/java/com/nami/reactlibrary/NamiMLManagerBridgeModule.kt +0 -58
- package/android/src/main/java/com/nami/reactlibrary/NamiManagerBridge.kt +0 -26
- package/android/src/main/java/com/nami/reactlibrary/NamiPaywallManagerBridgeModule.kt +0 -258
- package/android/src/main/java/com/nami/reactlibrary/NamiPurchaseManagerBridge.kt +0 -108
- package/build-utils/get_version_code.py +0 -140
- package/build-utils/preflight.py +0 -46
- package/ios/NamiMLManagerBridge.m +0 -93
- package/ios/NamiManager.m +0 -18
- package/ios/NamiManager.swift +0 -30
- package/ios/RNNami.h +0 -10
- package/ios/RNNami.m +0 -13
- package/src/Nami.d.ts +0 -8
- package/src/NamiCampaignManager.d.ts +0 -18
- package/src/NamiEntitlementManager.d.ts +0 -15
- package/src/NamiFlowManager.d.ts +0 -32
- package/src/NamiMLManager.d.ts +0 -7
- package/src/NamiMLManager.ts +0 -13
- package/src/NamiManager.d.ts +0 -5
- package/src/NamiManager.ts +0 -14
- package/src/NamiPaywallManager.d.ts +0 -34
- package/src/NamiPurchaseManager.d.ts +0 -20
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.namiml.reactnative
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.*
|
|
4
4
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
5
5
|
import com.namiml.entitlement.NamiEntitlementManager
|
|
6
|
-
|
|
7
|
-
import com.facebook.react.
|
|
6
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
7
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
@ReactModule(name = NamiEntitlementManagerBridgeModule.NAME)
|
|
10
|
+
class NamiEntitlementManagerBridgeModule internal constructor(
|
|
11
|
+
reactContext: ReactApplicationContext
|
|
12
|
+
) : ReactContextBaseJavaModule(reactContext), TurboModule {
|
|
13
|
+
|
|
14
|
+
companion object {
|
|
15
|
+
const val NAME = "RNNamiEntitlementManager"
|
|
16
|
+
}
|
|
11
17
|
|
|
12
18
|
override fun getName(): String {
|
|
13
|
-
return
|
|
19
|
+
return NAME
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
@ReactMethod
|
|
@@ -32,7 +38,7 @@ class NamiEntitlementManagerBridgeModule(reactContext: ReactApplicationContext)
|
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
@ReactMethod
|
|
35
|
-
fun refresh(
|
|
41
|
+
fun refresh() {
|
|
36
42
|
NamiEntitlementManager.refresh { activeNativeEntitlements ->
|
|
37
43
|
val resultArray: WritableArray = WritableNativeArray()
|
|
38
44
|
if (activeNativeEntitlements != null) {
|
|
@@ -42,7 +48,9 @@ class NamiEntitlementManagerBridgeModule(reactContext: ReactApplicationContext)
|
|
|
42
48
|
}
|
|
43
49
|
}
|
|
44
50
|
}
|
|
45
|
-
|
|
51
|
+
reactApplicationContext
|
|
52
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
53
|
+
.emit("EntitlementsChanged", resultArray)
|
|
46
54
|
}
|
|
47
55
|
}
|
|
48
56
|
|
|
@@ -68,9 +76,11 @@ class NamiEntitlementManagerBridgeModule(reactContext: ReactApplicationContext)
|
|
|
68
76
|
|
|
69
77
|
@ReactMethod
|
|
70
78
|
fun addListener(eventName: String?) {
|
|
79
|
+
// Required for React Native event emitter support
|
|
71
80
|
}
|
|
72
81
|
|
|
73
82
|
@ReactMethod
|
|
74
83
|
fun removeListeners(count: Int?) {
|
|
84
|
+
// Required for React Native event emitter support
|
|
75
85
|
}
|
|
76
86
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
package com.namiml.reactnative
|
|
2
|
+
|
|
3
|
+
import android.os.Handler
|
|
4
|
+
import android.os.Looper
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import com.facebook.react.bridge.*
|
|
7
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
8
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
9
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule
|
|
10
|
+
import com.namiml.flow.NamiFlowManager
|
|
11
|
+
|
|
12
|
+
@ReactModule(name = NamiFlowManagerBridgeModule.NAME)
|
|
13
|
+
class NamiFlowManagerBridgeModule internal constructor(
|
|
14
|
+
reactContext: ReactApplicationContext
|
|
15
|
+
) : ReactContextBaseJavaModule(reactContext), TurboModule {
|
|
16
|
+
|
|
17
|
+
companion object {
|
|
18
|
+
const val NAME = "RNNamiFlowManager"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override fun getName(): String {
|
|
22
|
+
return NAME
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@ReactMethod
|
|
26
|
+
fun registerStepHandoff() {
|
|
27
|
+
NamiFlowManager.registerStepHandoff { handoffTag, handoffData ->
|
|
28
|
+
val payload = Arguments.createMap().apply {
|
|
29
|
+
putString("handoffTag", handoffTag)
|
|
30
|
+
if (handoffData != null) {
|
|
31
|
+
try {
|
|
32
|
+
val map = Arguments.makeNativeMap(handoffData)
|
|
33
|
+
putMap("handoffData", map)
|
|
34
|
+
} catch (e: Exception) {
|
|
35
|
+
Log.d(NAME, "Failed to convert handoffData to NativeMap: ${e.localizedMessage}")
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
sendEvent("Handoff", payload)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@ReactMethod
|
|
44
|
+
fun registerEventHandler() {
|
|
45
|
+
NamiFlowManager.registerEventHandler { data ->
|
|
46
|
+
val payload = Arguments.makeNativeMap(data)
|
|
47
|
+
sendEvent("FlowEvent", payload)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@ReactMethod
|
|
52
|
+
fun resume() {
|
|
53
|
+
Handler(Looper.getMainLooper()).postDelayed({
|
|
54
|
+
NamiFlowManager.resume()
|
|
55
|
+
}, 100L)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@ReactMethod
|
|
59
|
+
fun finish() {
|
|
60
|
+
Handler(Looper.getMainLooper()).postDelayed({
|
|
61
|
+
NamiFlowManager.finish()
|
|
62
|
+
}, 100L)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@ReactMethod
|
|
66
|
+
fun isFlowOpen(promise: Promise) {
|
|
67
|
+
promise.resolve(NamiFlowManager.isFlowOpen())
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private fun sendEvent(eventName: String, params: WritableMap?) {
|
|
71
|
+
reactApplicationContext
|
|
72
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
73
|
+
.emit(eventName, params)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Required for RN EventEmitter support
|
|
77
|
+
@ReactMethod fun addListener(eventName: String?) {}
|
|
78
|
+
@ReactMethod fun removeListeners(count: Int?) {}
|
|
79
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
package com.namiml.reactnative
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.util.Log
|
|
5
|
+
import com.facebook.react.bridge.*
|
|
6
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
7
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
8
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule
|
|
9
|
+
import com.namiml.paywall.NamiPaywallManager
|
|
10
|
+
import com.namiml.paywall.NamiSKU
|
|
11
|
+
import com.namiml.paywall.model.NamiPurchaseSuccess
|
|
12
|
+
|
|
13
|
+
@ReactModule(name = NamiPaywallManagerBridgeModule.NAME)
|
|
14
|
+
class NamiPaywallManagerBridgeModule internal constructor(
|
|
15
|
+
reactContext: ReactApplicationContext
|
|
16
|
+
) : ReactContextBaseJavaModule(reactContext), TurboModule {
|
|
17
|
+
|
|
18
|
+
companion object {
|
|
19
|
+
const val NAME = "RNNamiPaywallManager"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override fun getName(): String = NAME
|
|
23
|
+
|
|
24
|
+
private var latestPaywallActivity: Activity? = null
|
|
25
|
+
|
|
26
|
+
@ReactMethod
|
|
27
|
+
fun buySkuComplete(dict: ReadableMap) {
|
|
28
|
+
val product = dict.getMap("product")
|
|
29
|
+
val productId = product?.getString("id")
|
|
30
|
+
val skuRefId = product?.getString("skuId")
|
|
31
|
+
val typeString = product?.getString("type")
|
|
32
|
+
val storeType = dict.getString("storeType") ?: "GooglePlay"
|
|
33
|
+
var purchaseSuccess: NamiPurchaseSuccess? = null
|
|
34
|
+
|
|
35
|
+
if (productId != null && skuRefId != null) {
|
|
36
|
+
val namiSku = NamiSKU.create(
|
|
37
|
+
skuRefId = skuRefId,
|
|
38
|
+
skuId = productId,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
when (storeType) {
|
|
42
|
+
"GooglePlay" -> {
|
|
43
|
+
val purchaseToken = dict.getString("purchaseToken")
|
|
44
|
+
val orderId = dict.getString("orderId")
|
|
45
|
+
if (purchaseToken != null && orderId != null) {
|
|
46
|
+
purchaseSuccess = NamiPurchaseSuccess.GooglePlay(
|
|
47
|
+
product = namiSku,
|
|
48
|
+
orderId = orderId,
|
|
49
|
+
purchaseToken = purchaseToken,
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
"Amazon" -> {
|
|
54
|
+
val receiptId = dict.getString("receiptId")
|
|
55
|
+
val localizedPrice = dict.getString("localizedPrice")
|
|
56
|
+
val userId = dict.getString("userId")
|
|
57
|
+
val marketplace = dict.getString("marketplace")
|
|
58
|
+
if (receiptId != null && localizedPrice != null && userId != null && marketplace != null) {
|
|
59
|
+
purchaseSuccess = NamiPurchaseSuccess.Amazon(
|
|
60
|
+
product = namiSku,
|
|
61
|
+
receiptId = receiptId,
|
|
62
|
+
localizedPrice = localizedPrice,
|
|
63
|
+
userId = userId,
|
|
64
|
+
marketplace = marketplace,
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (purchaseSuccess != null) {
|
|
71
|
+
val activity = latestPaywallActivity ?: currentActivity
|
|
72
|
+
if (activity != null) {
|
|
73
|
+
NamiPaywallManager.buySkuComplete(activity, purchaseSuccess)
|
|
74
|
+
} else {
|
|
75
|
+
Log.w(NAME, "No activity available to complete purchase.")
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
Log.d(NAME, "Unable to create a valid NamiPurchaseSuccess object. Purchase not completed.")
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@ReactMethod
|
|
84
|
+
fun registerCloseHandler() {
|
|
85
|
+
NamiPaywallManager.registerCloseHandler { activity ->
|
|
86
|
+
latestPaywallActivity = activity
|
|
87
|
+
val map = Arguments.createMap().apply {
|
|
88
|
+
putBoolean("paywallCloseRequested", true)
|
|
89
|
+
}
|
|
90
|
+
emitEvent("PaywallCloseRequested", map)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@ReactMethod
|
|
95
|
+
fun dismiss(promise: Promise) {
|
|
96
|
+
latestPaywallActivity?.let {
|
|
97
|
+
NamiPaywallManager.dismiss(it) { result -> promise.resolve(result) }
|
|
98
|
+
} ?: promise.resolve(false)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@ReactMethod
|
|
102
|
+
fun registerBuySkuHandler() {
|
|
103
|
+
NamiPaywallManager.registerBuySkuHandler { activity, sku ->
|
|
104
|
+
latestPaywallActivity = activity
|
|
105
|
+
try {
|
|
106
|
+
val dictionary = sku.toSkuDict()
|
|
107
|
+
emitEvent("RegisterBuySKU", dictionary)
|
|
108
|
+
} catch (e: Exception) {
|
|
109
|
+
Log.e(NAME, "Failed to convert SKU: ${e.localizedMessage}")
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@ReactMethod
|
|
115
|
+
fun registerSignInHandler() {
|
|
116
|
+
NamiPaywallManager.registerSignInHandler { activity ->
|
|
117
|
+
latestPaywallActivity = activity
|
|
118
|
+
val map = Arguments.createMap().apply {
|
|
119
|
+
putBoolean("paywallSignInRequested", true)
|
|
120
|
+
}
|
|
121
|
+
emitEvent("PaywallSignInRequested", map)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@ReactMethod
|
|
126
|
+
fun registerRestoreHandler() {
|
|
127
|
+
NamiPaywallManager.registerRestoreHandler { activity ->
|
|
128
|
+
latestPaywallActivity = activity
|
|
129
|
+
val map = Arguments.createMap().apply {
|
|
130
|
+
putBoolean("paywallRestoreRequested", true)
|
|
131
|
+
}
|
|
132
|
+
emitEvent("PaywallRestoreRequested", map)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@ReactMethod
|
|
137
|
+
fun registerDeeplinkActionHandler() {
|
|
138
|
+
NamiPaywallManager.registerDeepLinkHandler { activity, url ->
|
|
139
|
+
latestPaywallActivity = activity
|
|
140
|
+
emitEvent("PaywallDeeplinkAction", url)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@ReactMethod
|
|
145
|
+
fun show() {
|
|
146
|
+
// No-op on Android
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@ReactMethod
|
|
150
|
+
fun hide() {
|
|
151
|
+
// No-op on Android
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@ReactMethod
|
|
155
|
+
fun isHidden(promise: Promise) {
|
|
156
|
+
promise.resolve(false)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@ReactMethod
|
|
160
|
+
fun isPaywallOpen(promise: Promise) {
|
|
161
|
+
promise.resolve(NamiPaywallManager.isPaywallOpen())
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@ReactMethod
|
|
165
|
+
fun buySkuCancel() {
|
|
166
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
167
|
+
latestPaywallActivity?.let {
|
|
168
|
+
NamiPaywallManager.buySkuCancel(it)
|
|
169
|
+
} ?: currentActivity?.let {
|
|
170
|
+
NamiPaywallManager.buySkuCancel(it)
|
|
171
|
+
} ?: NamiPaywallManager.buySkuCancel()
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@ReactMethod
|
|
176
|
+
fun setProductDetails(productDetails: String, allowOffers: Boolean) {
|
|
177
|
+
NamiPaywallManager.setProductDetails(productDetails, allowOffers)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@ReactMethod
|
|
181
|
+
fun setAppSuppliedVideoDetails(url: String, name: String?) {
|
|
182
|
+
NamiPaywallManager.setAppSuppliedVideoDetails(url, name)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@ReactMethod
|
|
186
|
+
fun allowUserInteraction(allowed: Boolean) {
|
|
187
|
+
NamiPaywallManager.allowPaywallInteraction(allow = allowed)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@ReactMethod fun addListener(eventName: String?) {}
|
|
191
|
+
@ReactMethod fun removeListeners(count: Int?) {}
|
|
192
|
+
|
|
193
|
+
private fun emitEvent(name: String, payload: Any?) {
|
|
194
|
+
val emitter = reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
195
|
+
emitter.emit(name, payload)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
package com.namiml.reactnative
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.*
|
|
5
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
6
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
7
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule
|
|
8
|
+
import com.namiml.billing.NamiPurchaseManager
|
|
9
|
+
|
|
10
|
+
@ReactModule(name = NamiPurchaseManagerBridgeModule.NAME)
|
|
11
|
+
class NamiPurchaseManagerBridgeModule internal constructor(
|
|
12
|
+
private val reactContext: ReactApplicationContext
|
|
13
|
+
) : ReactContextBaseJavaModule(reactContext), TurboModule {
|
|
14
|
+
|
|
15
|
+
companion object {
|
|
16
|
+
const val NAME = "RNNamiPurchaseManager"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun getName(): String = NAME
|
|
20
|
+
|
|
21
|
+
@ReactMethod
|
|
22
|
+
fun purchases(resultsCallback: Callback) {
|
|
23
|
+
reactContext.runOnUiQueueThread {
|
|
24
|
+
val purchases = NamiPurchaseManager.allPurchases()
|
|
25
|
+
val resultArray = WritableNativeArray()
|
|
26
|
+
|
|
27
|
+
purchases.forEach { purchase ->
|
|
28
|
+
try {
|
|
29
|
+
resultArray.pushMap(purchase.toPurchaseDict())
|
|
30
|
+
} catch (e: Exception) {
|
|
31
|
+
Log.e(NAME, "Error converting purchase to map", e)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
resultsCallback.invoke(resultArray)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@ReactMethod
|
|
40
|
+
fun skuPurchased(skuID: String, promise: Promise) {
|
|
41
|
+
val isPurchased = NamiPurchaseManager.isSKUIDPurchased(skuID)
|
|
42
|
+
promise.resolve(isPurchased)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@ReactMethod
|
|
46
|
+
fun anySkuPurchased(skuIDs: ReadableArray, promise: Promise) {
|
|
47
|
+
reactContext.runOnUiQueueThread {
|
|
48
|
+
val checkArray = mutableListOf<String>()
|
|
49
|
+
|
|
50
|
+
for (i in 0 until skuIDs.size()) {
|
|
51
|
+
if (skuIDs.getType(i) == ReadableType.String) {
|
|
52
|
+
skuIDs.getString(i)?.takeIf { it.isNotBlank() }?.let { checkArray.add(it) }
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
val anyPurchased = NamiPurchaseManager.anySKUIDPurchased(checkArray)
|
|
57
|
+
promise.resolve(anyPurchased)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@ReactMethod
|
|
62
|
+
fun restorePurchases(resultsCallback: Callback) {
|
|
63
|
+
Log.w(NAME, "Restore Purchases called on Android platform; no-op.")
|
|
64
|
+
|
|
65
|
+
val resultMap = WritableNativeMap().apply {
|
|
66
|
+
putBoolean("success", false)
|
|
67
|
+
putString(
|
|
68
|
+
"error",
|
|
69
|
+
"Google Play or Amazon Appstore on Android devices do not provide a restore purchases API."
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
resultsCallback.invoke(resultMap)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@ReactMethod
|
|
77
|
+
fun registerPurchasesChangedHandler() {
|
|
78
|
+
NamiPurchaseManager.registerPurchasesChangedHandler { purchases, purchaseState, error ->
|
|
79
|
+
val resultPurchases = WritableNativeArray().apply {
|
|
80
|
+
purchases.forEach {
|
|
81
|
+
try {
|
|
82
|
+
pushMap(it.toPurchaseDict())
|
|
83
|
+
} catch (e: Exception) {
|
|
84
|
+
Log.e(NAME, "Failed to map purchase", e)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
val payload = Arguments.createMap().apply {
|
|
90
|
+
putArray("purchases", resultPurchases)
|
|
91
|
+
putString("purchaseState", purchaseState.toString())
|
|
92
|
+
putString("error", error)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
emitEvent("PurchasesChanged", payload)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private fun emitEvent(eventName: String, payload: WritableMap) {
|
|
100
|
+
reactContext
|
|
101
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
102
|
+
.emit(eventName, payload)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@ReactMethod fun addListener(eventName: String?) {}
|
|
106
|
+
@ReactMethod fun removeListeners(count: Int?) {}
|
|
107
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.namiml.reactnative
|
|
2
2
|
|
|
3
3
|
import android.util.Log
|
|
4
4
|
import com.facebook.react.bridge.Arguments
|
|
@@ -15,6 +15,41 @@ import java.text.SimpleDateFormat
|
|
|
15
15
|
import java.util.Date
|
|
16
16
|
import java.util.Locale
|
|
17
17
|
import java.util.TimeZone
|
|
18
|
+
import com.namiml.paywall.model.NamiPaywallAction
|
|
19
|
+
|
|
20
|
+
fun NamiPaywallAction.toRNActionString(): String {
|
|
21
|
+
return when (this) {
|
|
22
|
+
NamiPaywallAction.NAMI_BUY_SKU -> "BUY_SKU"
|
|
23
|
+
NamiPaywallAction.NAMI_SELECT_SKU -> "SELECT_SKU"
|
|
24
|
+
NamiPaywallAction.NAMI_RESTORE_PURCHASES -> "RESTORE_PURCHASES"
|
|
25
|
+
NamiPaywallAction.NAMI_SHOW_PAYWALL -> "SHOW_PAYWALL"
|
|
26
|
+
NamiPaywallAction.NAMI_CLOSE_PAYWALL -> "CLOSE_PAYWALL"
|
|
27
|
+
NamiPaywallAction.NAMI_SIGN_IN -> "SIGN_IN"
|
|
28
|
+
NamiPaywallAction.NAMI_PURCHASE_SELECTED_SKU -> "PURCHASE_SELECTED_SKU"
|
|
29
|
+
NamiPaywallAction.NAMI_PURCHASE_SUCCESS -> "PURCHASE_SUCCESS"
|
|
30
|
+
NamiPaywallAction.NAMI_PURCHASE_FAILED -> "PURCHASE_FAILED"
|
|
31
|
+
NamiPaywallAction.NAMI_PURCHASE_CANCELLED -> "PURCHASE_CANCELLED"
|
|
32
|
+
NamiPaywallAction.NAMI_PURCHASE_PENDING -> "PURCHASE_PENDING"
|
|
33
|
+
NamiPaywallAction.NAMI_PURCHASE_UNKNOWN -> "PURCHASE_UNKNOWN"
|
|
34
|
+
NamiPaywallAction.NAMI_DEEP_LINK -> "DEEPLINK"
|
|
35
|
+
NamiPaywallAction.NAMI_TOGGLE_CHANGE -> "TOGGLE_CHANGE"
|
|
36
|
+
NamiPaywallAction.NAMI_PAGE_CHANGE -> "PAGE_CHANGE"
|
|
37
|
+
NamiPaywallAction.NAMI_SLIDE_CHANGE -> "SLIDE_CHANGE"
|
|
38
|
+
NamiPaywallAction.NAMI_COLLAPSIBLE_DRAWER_OPEN -> "COLLAPSIBLE_DRAWER_OPEN"
|
|
39
|
+
NamiPaywallAction.NAMI_COLLAPSIBLE_DRAWER_CLOSE -> "COLLAPSIBLE_DRAWER_CLOSE"
|
|
40
|
+
NamiPaywallAction.NAMI_VIDEO_STARTED -> "VIDEO_STARTED"
|
|
41
|
+
NamiPaywallAction.NAMI_VIDEO_PAUSED -> "VIDEO_PAUSED"
|
|
42
|
+
NamiPaywallAction.NAMI_VIDEO_RESUMED -> "VIDEO_RESUMED"
|
|
43
|
+
NamiPaywallAction.NAMI_VIDEO_ENDED -> "VIDEO_ENDED"
|
|
44
|
+
NamiPaywallAction.NAMI_VIDEO_CHANGED -> "VIDEO_CHANGED"
|
|
45
|
+
NamiPaywallAction.NAMI_VIDEO_MUTED -> "VIDEO_MUTED"
|
|
46
|
+
NamiPaywallAction.NAMI_VIDEO_UNMUTED -> "VIDEO_UNMUTED"
|
|
47
|
+
else -> {
|
|
48
|
+
Log.w("NamiUtil", "Unhandled NamiPaywallAction: $this. This might indicate a new enum value added in the SDK.")
|
|
49
|
+
"UNKNOWN"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
18
53
|
|
|
19
54
|
fun List<*>.toWritableArray(): WritableArray {
|
|
20
55
|
val convertedArray = Arguments.createArray()
|
|
@@ -74,47 +109,50 @@ fun Map<*, *>.toWritableMap(): WritableMap {
|
|
|
74
109
|
}
|
|
75
110
|
|
|
76
111
|
fun NamiSKU.toSkuDict(): WritableMap {
|
|
77
|
-
val productDict =
|
|
112
|
+
val productDict = WritableNativeMap()
|
|
78
113
|
|
|
79
|
-
productDict.putString("skuId", this.skuId)
|
|
80
114
|
productDict.putString("id", this.id)
|
|
81
|
-
productDict.putString("
|
|
115
|
+
productDict.putString("skuId", this.skuId)
|
|
116
|
+
productDict.putString("name", this.name ?: "")
|
|
117
|
+
productDict.putString("type", this.type?.toString() ?: "unknown")
|
|
82
118
|
|
|
83
|
-
|
|
84
|
-
productDict.putString("promoId",
|
|
119
|
+
this.promoId?.let {
|
|
120
|
+
productDict.putString("promoId", it)
|
|
85
121
|
}
|
|
86
122
|
|
|
87
|
-
|
|
88
|
-
productDict.putString("promoToken",
|
|
123
|
+
this.promoOfferToken?.let {
|
|
124
|
+
productDict.putString("promoToken", it)
|
|
89
125
|
}
|
|
90
126
|
|
|
91
127
|
return productDict
|
|
92
128
|
}
|
|
93
129
|
|
|
94
|
-
// Really needs to be a NamiPurchase, when exists...
|
|
95
130
|
fun NamiPurchase.toPurchaseDict(): WritableMap {
|
|
96
131
|
val purchaseMap = WritableNativeMap()
|
|
97
132
|
|
|
98
|
-
|
|
99
|
-
purchaseMap.putString("
|
|
133
|
+
purchaseMap.putString("skuId", skuId)
|
|
134
|
+
purchaseMap.putString("transactionIdentifier", transactionIdentifier.orEmpty())
|
|
100
135
|
|
|
101
|
-
|
|
102
|
-
|
|
136
|
+
purchaseSource?.let {
|
|
137
|
+
purchaseMap.putString("purchaseSource", it.toString())
|
|
138
|
+
}
|
|
103
139
|
|
|
104
|
-
|
|
105
|
-
|
|
140
|
+
namiSku?.let { sku ->
|
|
141
|
+
val skuMap = WritableNativeMap()
|
|
142
|
+
skuMap.putString("id", sku.id)
|
|
143
|
+
skuMap.putString("skuId", sku.skuId)
|
|
144
|
+
skuMap.putString("name", sku.name ?: "")
|
|
145
|
+
skuMap.putString("type", sku.type?.toString() ?: "unknown") // match NamiSKUType
|
|
146
|
+
skuMap.putString("promoId", sku.promoId)
|
|
147
|
+
skuMap.putString("promoToken", sku.promoOfferToken)
|
|
148
|
+
purchaseMap.putMap("sku", skuMap)
|
|
149
|
+
}
|
|
106
150
|
|
|
107
151
|
expires?.let {
|
|
108
|
-
purchaseMap.
|
|
109
|
-
}
|
|
110
|
-
val initiatedTimestamp = purchaseInitiatedTimestamp
|
|
111
|
-
val purchaseInitiatedDate = Date(initiatedTimestamp)
|
|
112
|
-
purchaseInitiatedDate.let {
|
|
113
|
-
purchaseMap.putString("purchaseInitiatedTimestamp", it.toJavascriptDate())
|
|
152
|
+
purchaseMap.putDouble("expires", it.time.toDouble())
|
|
114
153
|
}
|
|
115
154
|
|
|
116
|
-
|
|
117
|
-
purchaseMap.putMap("platformMetadata", WritableNativeMap())
|
|
155
|
+
purchaseMap.putDouble("purchaseInitiatedTimestamp", purchaseInitiatedTimestamp.toDouble())
|
|
118
156
|
|
|
119
157
|
return purchaseMap
|
|
120
158
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export { Nami } from './src/Nami';
|
|
2
|
-
export { NamiMLManager } from './src/NamiMLManager';
|
|
3
2
|
export { NamiCampaignManager } from './src/NamiCampaignManager';
|
|
4
3
|
export { NamiCustomerManager } from './src/NamiCustomerManager';
|
|
5
4
|
export { NamiEntitlementManager } from './src/NamiEntitlementManager';
|
|
6
|
-
export { NamiManager } from './src/NamiManager';
|
|
7
5
|
export { NamiPurchaseManager } from './src/NamiPurchaseManager';
|
|
8
6
|
export { NamiPaywallManager } from './src/NamiPaywallManager';
|
|
9
7
|
export { NamiFlowManager } from './src/NamiFlowManager';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
export interface Spec extends TurboModule {
|
|
3
|
+
configure(config: {
|
|
4
|
+
appPlatformID: string;
|
|
5
|
+
logLevel: string;
|
|
6
|
+
namiCommands?: string[];
|
|
7
|
+
namiLanguageCode?: string;
|
|
8
|
+
initialConfig?: string;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
success: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
sdkConfigured(): Promise<boolean>;
|
|
13
|
+
sdkVersion(): Promise<string>;
|
|
14
|
+
}
|
|
15
|
+
declare const _default: Spec;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
export interface Spec extends TurboModule {
|
|
3
|
+
launch(label: string | null, withUrl: string | null, context: {
|
|
4
|
+
productGroups?: string[];
|
|
5
|
+
customAttributes?: {
|
|
6
|
+
[key: string]: string;
|
|
7
|
+
};
|
|
8
|
+
customObject?: {
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
} | null, completion: (successAction: boolean, error: number | null) => void, paywallCompletion: (event: {
|
|
12
|
+
campaignId?: string;
|
|
13
|
+
campaignName?: string;
|
|
14
|
+
campaignType?: string;
|
|
15
|
+
campaignLabel?: string;
|
|
16
|
+
campaignUrl?: string;
|
|
17
|
+
paywallId?: string;
|
|
18
|
+
paywallName?: string;
|
|
19
|
+
segmentId?: string;
|
|
20
|
+
externalSegmentId?: string;
|
|
21
|
+
action: string;
|
|
22
|
+
sku?: {
|
|
23
|
+
id?: string;
|
|
24
|
+
name?: string;
|
|
25
|
+
skuId?: string;
|
|
26
|
+
type?: string;
|
|
27
|
+
promoId?: string;
|
|
28
|
+
promoToken?: string;
|
|
29
|
+
};
|
|
30
|
+
purchaseError?: string;
|
|
31
|
+
purchases?: Array<{
|
|
32
|
+
sku?: {
|
|
33
|
+
id: string;
|
|
34
|
+
skuId: string;
|
|
35
|
+
name: string;
|
|
36
|
+
type: string;
|
|
37
|
+
};
|
|
38
|
+
skuId: string;
|
|
39
|
+
transactionIdentifier?: string;
|
|
40
|
+
purchaseToken?: string;
|
|
41
|
+
expires?: number;
|
|
42
|
+
purchaseInitiatedTimestamp: number;
|
|
43
|
+
purchaseSource?: 'CAMPAIGN' | 'MARKETPLACE' | 'UNKNOWN';
|
|
44
|
+
}>;
|
|
45
|
+
deeplinkUrl?: string;
|
|
46
|
+
componentChange?: {
|
|
47
|
+
id?: string;
|
|
48
|
+
name?: string;
|
|
49
|
+
};
|
|
50
|
+
videoMetadata?: {
|
|
51
|
+
id?: string;
|
|
52
|
+
name?: string;
|
|
53
|
+
url?: string;
|
|
54
|
+
loopVideo?: boolean;
|
|
55
|
+
muteByDefault?: boolean;
|
|
56
|
+
autoplayVideo?: boolean;
|
|
57
|
+
contentTimecode?: string;
|
|
58
|
+
contentDuration?: string;
|
|
59
|
+
};
|
|
60
|
+
timeSpentOnPaywall?: number;
|
|
61
|
+
}) => void): void;
|
|
62
|
+
allCampaigns(): Promise<{
|
|
63
|
+
id?: string;
|
|
64
|
+
rule?: string;
|
|
65
|
+
segment?: string;
|
|
66
|
+
paywall?: string;
|
|
67
|
+
type: string;
|
|
68
|
+
value?: string;
|
|
69
|
+
}[]>;
|
|
70
|
+
isCampaignAvailable(source?: string): Promise<boolean>;
|
|
71
|
+
refresh(): Promise<{
|
|
72
|
+
id?: string;
|
|
73
|
+
rule?: string;
|
|
74
|
+
segment?: string;
|
|
75
|
+
paywall?: string;
|
|
76
|
+
type: string;
|
|
77
|
+
value?: string;
|
|
78
|
+
}[]>;
|
|
79
|
+
registerAvailableCampaignsHandler(): void;
|
|
80
|
+
}
|
|
81
|
+
declare const _default: Spec;
|
|
82
|
+
export default _default;
|