react-native-nami-sdk 2.0.5 → 3.0.9

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.
Files changed (56) hide show
  1. package/.github/workflows/app_stg.yaml +203 -0
  2. package/.pre-commit-config.yaml +1 -1
  3. package/android/build.gradle +24 -13
  4. package/android/gradle/wrapper/gradle-wrapper.properties +5 -1
  5. package/android/src/main/java/com/nami/reactlibrary/NamiBridgeModule.kt +7 -51
  6. package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +1 -0
  7. package/android/src/main/java/com/nami/reactlibrary/NamiCampaignManagerBridge.kt +136 -0
  8. package/android/src/main/java/com/nami/reactlibrary/NamiCustomerManagerBridge.kt +97 -18
  9. package/android/src/main/java/com/nami/reactlibrary/NamiEmitter.kt +24 -24
  10. package/android/src/main/java/com/nami/reactlibrary/NamiEntitlementManagerBridgeModule.kt +30 -129
  11. package/android/src/main/java/com/nami/reactlibrary/NamiPaywallManagerBridgeModule.kt +133 -149
  12. package/android/src/main/java/com/nami/reactlibrary/NamiPurchaseManagerBridge.kt +36 -38
  13. package/android/src/main/java/com/nami/reactlibrary/NamiUtil.kt +50 -180
  14. package/build-utils/get_version_code.py +140 -0
  15. package/index.d.ts +20 -0
  16. package/index.js +7 -6
  17. package/ios/Nami.m +9 -63
  18. package/ios/NamiBridgeUtil.h +4 -6
  19. package/ios/NamiBridgeUtil.m +16 -78
  20. package/ios/NamiCampaignManagerBridge.m +26 -0
  21. package/ios/NamiCampaignManagerBridge.swift +112 -0
  22. package/ios/NamiCustomerManager.m +22 -23
  23. package/ios/NamiCustomerManager.swift +132 -0
  24. package/ios/NamiEmitter.m +55 -65
  25. package/ios/NamiEntitlementManagerBridge.m +7 -107
  26. package/ios/NamiEntitlementManagerBridge.swift +74 -0
  27. package/ios/NamiMLManagerBridge.m +2 -2
  28. package/ios/NamiPaywallManagerBridge.m +22 -94
  29. package/ios/NamiPaywallManagerBridge.swift +93 -0
  30. package/ios/NamiPurchaseManagerBridge.m +38 -69
  31. package/ios/NamiPurchaseManagerBridge.swift +174 -0
  32. package/ios/Podfile +2 -2
  33. package/ios/RNNami-Bridging-Header.h +5 -0
  34. package/ios/RNNami.h +0 -1
  35. package/ios/RNNami.m +1 -1
  36. package/ios/RNNami.xcodeproj/project.pbxproj +83 -11
  37. package/ios/RNNami.xcodeproj/xcshareddata/xcschemes/RNNami.xcscheme +67 -0
  38. package/package.json +1 -1
  39. package/react-native-nami-sdk.podspec +3 -3
  40. package/src/Nami.d.ts +112 -0
  41. package/src/Nami.js +10 -0
  42. package/src/NamiCampaignManager.d.ts +57 -0
  43. package/src/NamiCampaignManager.js +54 -0
  44. package/src/NamiCustomerManager.d.ts +41 -0
  45. package/src/NamiCustomerManager.js +43 -0
  46. package/src/NamiEntitlementManager.d.ts +24 -0
  47. package/src/NamiEntitlementManager.js +23 -0
  48. package/src/NamiMLManager.d.ts +5 -0
  49. package/src/NamiMLManager.js +7 -0
  50. package/src/NamiPaywallManager.d.ts +82 -0
  51. package/src/NamiPaywallManager.js +37 -0
  52. package/src/NamiPurchaseManager.d.ts +57 -0
  53. package/src/NamiPurchaseManager.js +37 -0
  54. package/src/types.ts +36 -0
  55. package/android/src/main/java/com/nami/reactlibrary/NamiAnalyticsEmitter.kt +0 -121
  56. package/ios/NamiAnalyticsEmitter.m +0 -146
@@ -3,34 +3,147 @@ package com.nami.reactlibrary
3
3
  import android.app.Activity
4
4
  import android.content.Intent
5
5
  import android.util.Log
6
- import com.facebook.react.bridge.ActivityEventListener
7
- import com.facebook.react.bridge.Arguments
8
- import com.facebook.react.bridge.Callback
9
- import com.facebook.react.bridge.ReactApplicationContext
10
- import com.facebook.react.bridge.ReactContextBaseJavaModule
11
- import com.facebook.react.bridge.ReactMethod
12
- import com.facebook.react.bridge.WritableNativeMap
6
+ import com.android.billingclient.api.Purchase
7
+ import com.facebook.react.bridge.*
13
8
  import com.facebook.react.modules.core.DeviceEventManagerModule
14
- import com.namiml.paywall.NamiPaywallManager
15
- import com.namiml.paywall.PreparePaywallResult
9
+ import com.namiml.paywall.*
10
+ import com.namiml.paywall.model.NamiPurchaseSuccess
11
+ import java.text.SimpleDateFormat
12
+ import java.util.Date
16
13
 
17
14
  class NamiPaywallManagerBridgeModule(reactContext: ReactApplicationContext) :
18
15
  ReactContextBaseJavaModule(reactContext), ActivityEventListener {
19
16
 
20
17
  private var blockRaisePaywall: Boolean = false
21
18
 
22
- init {
23
- NamiPaywallManager.registerApplicationAutoRaisePaywallBlocker {
24
- Log.i(LOG_TAG, "Nami flag for blocking paywall raise is $blockRaisePaywall")
25
- blockRaisePaywall
19
+ override fun getName(): String {
20
+ return "RNNamiPaywallManager"
21
+ }
22
+
23
+ @ReactMethod
24
+ fun buySkuComplete(dict: ReadableMap, storeType: String) {
25
+ var product = dict.getMap("product")
26
+ var name = product?.getString("name")
27
+ var featured = product?.getBoolean("featured")
28
+ var productId = product?.getString("id")
29
+ var skuId = product?.getString("skuId")
30
+ var typeInt = product?.getInt("type")
31
+ var purchaseSourceString = dict.getString("purchaseSource")
32
+ var purchaseDateInt = dict.getInt("purchaseDate")
33
+ var expiresDateInt = dict.getInt("expiresDate")
34
+ val type = when (typeInt) {
35
+ 0 -> {
36
+ NamiSKUType.UNKNOWN
37
+ }
38
+ 1 -> {
39
+ NamiSKUType.SUBSCRIPTION
40
+ }
41
+ 2 -> {
42
+ NamiSKUType.ONE_TIME_PURCHASE
43
+ }
44
+ else -> {
45
+ NamiSKUType.UNKNOWN
46
+ }
47
+ }
48
+
49
+ val purchaseSource = when (purchaseSourceString) {
50
+ "CAMPAIGN" -> {
51
+ NamiPurchaseSource.CAMPAIGN
52
+ }
53
+ "MARKETPLACE" -> {
54
+ NamiPurchaseSource.MARKETPLACE
55
+ }
56
+ "UNKNOWN" -> {
57
+ NamiPurchaseSource.UNKNOWN
58
+ }
59
+ else -> {
60
+ NamiPurchaseSource.UNKNOWN
61
+ }
62
+ }
63
+
64
+ if (name != null && skuId != null && featured != null) {
65
+ val namiSku = NamiSKU(
66
+ skuId = skuId,
67
+ skuDetails = null,
68
+ amazonProduct = null,
69
+ id = productId,
70
+ type = type,
71
+ name = name,
72
+ featured = featured,
73
+ rawDisplayText = null,
74
+ rawSubDisplayText = null,
75
+ entitlements = emptyList(),
76
+ variables = null
77
+ )
78
+ val purchaseDate = Date(purchaseDateInt * 1000L)
79
+ var expiresDate = Date(expiresDateInt * 1000L )
80
+ var purchaseSuccess: NamiPurchaseSuccess? = null;
81
+ if (storeType == "GooglePlay") {
82
+ var purchaseToken = dict.getString("purchaseToken")
83
+ var orderId = dict.getString("orderId")
84
+ if (purchaseToken != null && orderId != null) {
85
+ purchaseSuccess = NamiPurchaseSuccess.GooglePlay(
86
+ product = namiSku,
87
+ expiresDate = expiresDate,
88
+ purchaseDate = purchaseDate,
89
+ purchaseSource = purchaseSource,
90
+ description = null,
91
+ orderId = orderId,
92
+ purchaseToken = purchaseToken,
93
+ )
94
+ }
95
+ } else if (storeType == "Amazon") {
96
+ var receiptId = dict.getString("receiptId")
97
+ var localizedPrice = dict.getString("localizedPrice")
98
+ var userId = dict.getString("userId")
99
+ var marketplace = dict.getString("marketplace")
100
+ if (receiptId != null && localizedPrice != null && userId != null && marketplace != null) {
101
+ purchaseSuccess = NamiPurchaseSuccess.Amazon(
102
+ product = namiSku,
103
+ expiresDate = expiresDate,
104
+ purchaseDate = purchaseDate,
105
+ purchaseSource = purchaseSource,
106
+ description = null,
107
+ receiptId = receiptId,
108
+ localizedPrice = localizedPrice,
109
+ userId = userId,
110
+ marketplace = marketplace,
111
+ )
112
+ }
113
+ }
114
+
115
+ if (purchaseSuccess != null) {
116
+ NamiPaywallManager.buySkuComplete(currentActivity!!, purchaseSuccess)
117
+ }
26
118
  }
27
- reactContext.addActivityEventListener(this)
28
119
  }
29
120
 
30
- override fun getName(): String {
31
- return "NamiPaywallManagerBridge"
121
+
122
+ @ReactMethod
123
+ fun registerCloseHandler(blockDismiss: Boolean) {
124
+ NamiPaywallManager.registerCloseHandler { activity ->
125
+ val resultMap = Arguments.createMap()
126
+ resultMap.putBoolean("blockingPaywallClosed", true)
127
+ reactApplicationContext
128
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
129
+ .emit("BlockingPaywallClosed", resultMap)
130
+ if (!blockDismiss) {
131
+ activity.finish()
132
+ }
133
+ }
134
+ }
135
+
136
+ @ReactMethod
137
+ fun registerBuySkuHandler() {
138
+ NamiPaywallManager.registerBuySkuHandler { activity, sku ->
139
+ val dictionary = sku.toSkuDict()
140
+ reactApplicationContext
141
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
142
+ .emit("RegisterBuySKU", dictionary)
143
+ }
32
144
  }
33
145
 
146
+
34
147
  override fun onActivityResult(
35
148
  activity: Activity?,
36
149
  requestCode: Int,
@@ -64,138 +177,9 @@ class NamiPaywallManagerBridgeModule(reactContext: ReactApplicationContext) :
64
177
  // do nothing
65
178
  }
66
179
 
67
- @ReactMethod
68
- fun raisePaywall() {
69
- reactApplicationContext.runOnUiQueueThread {
70
- raisePaywall(currentActivity, null)
71
- }
72
- }
73
-
74
- @ReactMethod
75
- fun raisePaywallByDeveloperPaywallId(developerPaywallID: String) {
76
- reactApplicationContext.runOnUiQueueThread {
77
- raisePaywall(currentActivity, developerPaywallID)
78
- }
79
- }
180
+ // @ReactMethod
181
+ // fun blockRaisePaywall(blockRaise: Boolean) {
182
+ // blockRaisePaywall = blockRaise
183
+ // }
80
184
 
81
- private fun raisePaywall(activity: Activity?, developerPaywallID: String?) {
82
- if (NamiPaywallManager.canRaisePaywall()) {
83
- Log.d(LOG_TAG, "About to raise Paywall ")
84
- if (activity != null) {
85
- Log.i(LOG_TAG, "Nami Activity to raise paywall is $activity")
86
- if (developerPaywallID == null) {
87
- Log.i(LOG_TAG, "Raising Paywall: ")
88
- NamiPaywallManager.raisePaywall(activity)
89
- } else {
90
- Log.i(LOG_TAG, "Raising Paywall by Id: $developerPaywallID")
91
- NamiPaywallManager.raisePaywall(developerPaywallID, activity)
92
- }
93
- } else {
94
- Log.w(LOG_TAG, "Activity from react getCurrentActivity was null.")
95
- }
96
- } else {
97
- Log.w(LOG_TAG, "Paywall not raised, SDK says paywall cannot be raised at this time.")
98
- }
99
- }
100
-
101
- @ReactMethod
102
- fun canRaisePaywall(successCallback: Callback) {
103
- reactApplicationContext.runOnUiQueueThread {
104
- val canRaiseResult = NamiPaywallManager.canRaisePaywall()
105
- successCallback.invoke(canRaiseResult)
106
- }
107
- }
108
-
109
- @ReactMethod
110
- fun blockRaisePaywall(blockRaise: Boolean) {
111
- blockRaisePaywall = blockRaise
112
- }
113
-
114
- @ReactMethod
115
- fun fetchCustomMetadataForDeveloperID(paywallDeveloperID: String, successCallback: Callback) {
116
- val sendDict = WritableNativeMap()
117
- //TODO: Android SDK needs fetchCustomMetadataForDeveloperID
118
- successCallback(sendDict)
119
- }
120
-
121
- @ReactMethod
122
- fun paywallImpression(developerPaywallID: String) {
123
- // TODO: Android SDK paywall impression call.
124
- }
125
-
126
- @ReactMethod
127
- fun preparePaywallForDisplay(backgroundImageRequired: Boolean, imageFetchTimeout: Double) {
128
- val imageFetchTimeoutConvertedToLong: Long = imageFetchTimeout.toLong()
129
- reactApplicationContext.runOnUiQueueThread {
130
-
131
- NamiPaywallManager.preparePaywallForDisplay(
132
- backgroundImageRequired,
133
- imageFetchTimeoutConvertedToLong
134
- ) { result ->
135
- when (result) {
136
- is PreparePaywallResult.Success -> {
137
- emitPreparePaywallFinished(true, null, null)
138
- }
139
- is PreparePaywallResult.Failure -> {
140
- emitPreparePaywallFinished(false, null, result.error)
141
- }
142
- }
143
- }
144
- }
145
- }
146
-
147
- @ReactMethod
148
- fun preparePaywallForDisplayByDeveloperPaywallId(
149
- developerPaywallID: String,
150
- backgroundImageRequired: Boolean,
151
- imageFetchTimeout: Double
152
- ) {
153
- val imageFetchTimeoutConvertedToLong: Long = imageFetchTimeout.toLong()
154
- reactApplicationContext.runOnUiQueueThread {
155
- NamiPaywallManager.preparePaywallForDisplay(
156
- developerPaywallID,
157
- backgroundImageRequired,
158
- imageFetchTimeoutConvertedToLong
159
- ) { result ->
160
- when (result) {
161
- is PreparePaywallResult.Success -> {
162
- emitPreparePaywallFinished(true, developerPaywallID, null)
163
- }
164
- is PreparePaywallResult.Failure -> {
165
- emitPreparePaywallFinished(false, developerPaywallID, result.error)
166
- }
167
- }
168
- }
169
- }
170
- }
171
-
172
- private fun emitPreparePaywallFinished(
173
- success: Boolean,
174
- developerPaywallID: String?,
175
- error: com.namiml.paywall.PreparePaywallError?
176
- ) {
177
- val prepareContentMap = Arguments.createMap()
178
- prepareContentMap.putBoolean("success", success)
179
-
180
- if (developerPaywallID != null) {
181
- prepareContentMap.putString("developerPaywallID", developerPaywallID)
182
- }
183
-
184
- if (error != null) {
185
- prepareContentMap.putInt("errorCode", error.ordinal)
186
- prepareContentMap.putString("errorMessage", error.toString())
187
- }
188
-
189
- Log.i(
190
- LOG_TAG,
191
- "Emitting preparePaywallForDisplay finished with result " + success + "error: " + error.toString()
192
- )
193
- try {
194
- reactApplicationContext
195
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
196
- .emit("PreparePaywallFinished", prepareContentMap)
197
- } catch (e: Exception) {
198
- Log.e(LOG_TAG, "Caught Exception: " + e.message)
199
- }
200
- }
201
185
  }
@@ -1,22 +1,16 @@
1
1
  package com.nami.reactlibrary
2
2
 
3
3
  import android.util.Log
4
- import com.facebook.react.bridge.Callback
5
- import com.facebook.react.bridge.ReactApplicationContext
6
- import com.facebook.react.bridge.ReactContextBaseJavaModule
7
- import com.facebook.react.bridge.ReactMethod
8
- import com.facebook.react.bridge.ReadableArray
9
- import com.facebook.react.bridge.ReadableType
10
- import com.facebook.react.bridge.WritableArray
11
- import com.facebook.react.bridge.WritableNativeArray
12
- import com.facebook.react.bridge.WritableNativeMap
4
+ import com.facebook.react.bridge.*
5
+ import com.facebook.react.modules.core.DeviceEventManagerModule
13
6
  import com.namiml.billing.NamiPurchaseManager
7
+ import com.namiml.paywall.NamiPaywallManager
14
8
 
15
9
  class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
16
10
  ReactContextBaseJavaModule(reactContext) {
17
11
 
18
12
  override fun getName(): String {
19
- return "NamiPurchaseManagerBridge"
13
+ return "RNNamiPurchaseManager"
20
14
  }
21
15
 
22
16
  @ReactMethod
@@ -26,26 +20,6 @@ class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
26
20
  }
27
21
  }
28
22
 
29
- @ReactMethod
30
- fun buySKU(skuPlatformID: String, developerPaywallID: String, resultsCallback: Callback) {
31
- reactApplicationContext.runOnUiQueueThread {
32
- currentActivity?.let {
33
- NamiPurchaseManager.buySKU(it, skuPlatformID) {
34
-
35
- val result: Boolean
36
- if (NamiPurchaseManager.isSKUIDPurchased(skuPlatformID)) {
37
- result = true
38
- Log.i(LOG_TAG, "Purchase complete, result is PURCHASED.")
39
- } else {
40
- result = false
41
- Log.i(LOG_TAG, "Purchase complete, product not purchased.")
42
- }
43
- resultsCallback.invoke(result)
44
- }
45
- }
46
- }
47
- }
48
-
49
23
  @ReactMethod
50
24
  fun purchases(resultsCallback: Callback) {
51
25
  reactApplicationContext.runOnUiQueueThread {
@@ -63,22 +37,20 @@ class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
63
37
  }
64
38
 
65
39
  @ReactMethod
66
- fun isSKUIDPurchased(skuID: String, resultsCallback: Callback) {
67
- reactApplicationContext.runOnUiQueueThread {
68
- val isPurchased = NamiPurchaseManager.isSKUIDPurchased(skuID)
69
- resultsCallback.invoke(isPurchased)
70
- }
40
+ fun skuPurchased(skuID: String, promise: Promise) {
41
+ val isPurchased = NamiPurchaseManager.isSKUIDPurchased(skuID)
42
+ promise.resolve(isPurchased)
71
43
  }
72
44
 
73
45
  @ReactMethod
74
- fun consumePurchasedSKU(skuRefId: String) {
46
+ fun consumePurchasedSku(skuRefId: String) {
75
47
  reactApplicationContext.runOnUiQueueThread {
76
48
  NamiPurchaseManager.consumePurchasedSKU(skuRefId)
77
49
  }
78
50
  }
79
51
 
80
52
  @ReactMethod
81
- fun anySKUIDPurchased(skuIDs: ReadableArray, resultsCallback: Callback) {
53
+ fun anySkuPurchased(skuIDs: ReadableArray, promise: Promise) {
82
54
  reactApplicationContext.runOnUiQueueThread {
83
55
  val checkArray: MutableList<String> = mutableListOf()
84
56
  for (x in 0 until skuIDs.size()) {
@@ -92,7 +64,7 @@ class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
92
64
 
93
65
  val anyPurchased = NamiPurchaseManager.anySKUIDPurchased(checkArray)
94
66
 
95
- resultsCallback.invoke(anyPurchased)
67
+ promise.resolve(anyPurchased)
96
68
  }
97
69
  }
98
70
 
@@ -109,4 +81,30 @@ class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
109
81
  }
110
82
  resultsCallback.invoke(resultMap)
111
83
  }
84
+
85
+ @ReactMethod
86
+ fun registerPurchasesChangedHandler() {
87
+ NamiPurchaseManager.registerPurchasesChangedHandler{purchases, purchaseState, error ->
88
+ run {
89
+ val resultPurchases: WritableArray = WritableNativeArray()
90
+
91
+ for (purchase in purchases) {
92
+ resultPurchases.pushMap(purchase.toPurchaseDict())
93
+ }
94
+
95
+ val stateString = purchaseState.toString()
96
+
97
+ val payload = Arguments.createMap()
98
+ payload.putArray("purchases", resultPurchases)
99
+ payload.putString("purchaseState", stateString)
100
+ payload.putString("error", error)
101
+
102
+ reactApplicationContext
103
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
104
+ .emit("PurchasesChanged", payload)
105
+
106
+
107
+ }
108
+ }
109
+ }
112
110
  }