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.
Files changed (106) hide show
  1. package/.prettierrc +4 -0
  2. package/README.md +9 -9
  3. package/android/README.md +3 -2
  4. package/android/build.gradle +27 -19
  5. package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  6. package/android/gradlew +0 -0
  7. package/android/src/main/AndroidManifest.xml +1 -1
  8. package/android/src/main/java/com/namiml/reactnative/Constants.kt +3 -0
  9. package/android/src/main/java/com/namiml/reactnative/NamiBridgeModule.kt +97 -0
  10. package/android/src/main/java/com/namiml/reactnative/NamiBridgePackage.java +140 -0
  11. package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiCampaignManagerBridge.kt +25 -32
  12. package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiCustomerManagerBridge.kt +14 -6
  13. package/android/src/main/java/com/{nami/reactlibrary/NamiEntitlementManagerBridgeModule.kt → namiml/reactnative/NamiEntitlementManagerBridge.kt} +18 -8
  14. package/android/src/main/java/com/namiml/reactnative/NamiFlowManagerBridge.kt +79 -0
  15. package/android/src/main/java/com/namiml/reactnative/NamiPaywallManagerBridgeModule.kt +197 -0
  16. package/android/src/main/java/com/namiml/reactnative/NamiPurchaseManagerBridge.kt +107 -0
  17. package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiUtil.kt +61 -23
  18. package/{index.d.ts → dist/index.d.ts} +0 -2
  19. package/dist/specs/NativeNami.d.ts +16 -0
  20. package/dist/specs/NativeNamiCampaignManager.d.ts +82 -0
  21. package/dist/specs/NativeNamiCustomerManager.d.ts +29 -0
  22. package/dist/specs/NativeNamiEntitlementManager.d.ts +45 -0
  23. package/dist/specs/NativeNamiFlowManager.d.ts +10 -0
  24. package/dist/specs/NativeNamiPaywallManager.d.ts +72 -0
  25. package/dist/specs/NativeNamiPurchaseManager.d.ts +27 -0
  26. package/dist/src/Nami.d.ts +6 -0
  27. package/dist/src/NamiCampaignManager.d.ts +29 -0
  28. package/{src → dist/src}/NamiCustomerManager.d.ts +11 -13
  29. package/dist/src/NamiEntitlementManager.d.ts +13 -0
  30. package/dist/src/NamiFlowManager.d.ts +13 -0
  31. package/dist/src/NamiPaywallManager.d.ts +30 -0
  32. package/dist/src/NamiPurchaseManager.d.ts +16 -0
  33. package/dist/src/transformers.d.ts +3 -0
  34. package/{src → dist/src}/types.d.ts +36 -6
  35. package/dist/src/version.d.ts +5 -0
  36. package/index.ts +0 -2
  37. package/ios/Nami.m +9 -87
  38. package/ios/Nami.swift +89 -0
  39. package/ios/NamiCampaignManagerBridge.m +3 -3
  40. package/ios/NamiCampaignManagerBridge.swift +47 -61
  41. package/ios/NamiCustomerManager.m +2 -2
  42. package/ios/NamiCustomerManager.swift +11 -3
  43. package/ios/NamiEntitlementManagerBridge.m +2 -3
  44. package/ios/NamiEntitlementManagerBridge.swift +47 -39
  45. package/ios/NamiFlowManagerBridge.m +4 -2
  46. package/ios/NamiFlowManagerBridge.swift +27 -6
  47. package/ios/NamiPaywallManagerBridge.m +3 -3
  48. package/ios/NamiPaywallManagerBridge.swift +24 -6
  49. package/ios/NamiPurchaseManagerBridge.m +3 -4
  50. package/ios/NamiPurchaseManagerBridge.swift +14 -15
  51. package/ios/RNNami-Bridging-Header.h +1 -3
  52. package/package.json +20 -8
  53. package/react-native-config.js +9 -0
  54. package/react-native-nami-sdk.podspec +17 -3
  55. package/scripts/generate-version.ts +18 -0
  56. package/specs/NativeNami.ts +17 -0
  57. package/specs/NativeNamiCampaignManager.ts +94 -0
  58. package/specs/NativeNamiCustomerManager.ts +37 -0
  59. package/specs/NativeNamiEntitlementManager.ts +54 -0
  60. package/specs/NativeNamiFlowManager.ts +13 -0
  61. package/specs/NativeNamiPaywallManager.ts +86 -0
  62. package/specs/NativeNamiPurchaseManager.ts +32 -0
  63. package/src/Nami.ts +31 -18
  64. package/src/NamiCampaignManager.ts +57 -53
  65. package/src/NamiCustomerManager.ts +55 -81
  66. package/src/NamiEntitlementManager.ts +49 -36
  67. package/src/NamiFlowManager.ts +42 -44
  68. package/src/NamiPaywallManager.ts +84 -139
  69. package/src/NamiPurchaseManager.ts +66 -70
  70. package/src/transformers.ts +21 -0
  71. package/src/types.ts +40 -7
  72. package/src/version.ts +5 -0
  73. package/tsconfig.json +24 -22
  74. package/.eslintignore +0 -3
  75. package/.eslintrc.js +0 -52
  76. package/.github/workflows/CI.yaml +0 -341
  77. package/.github/workflows/app_prod.yaml +0 -387
  78. package/.github/workflows/app_stg.yaml +0 -398
  79. package/.github/workflows/build.yml +0 -70
  80. package/.pre-commit-config.yaml +0 -24
  81. package/.prettierrc.js +0 -7
  82. package/android/src/main/java/com/nami/reactlibrary/Constants.kt +0 -3
  83. package/android/src/main/java/com/nami/reactlibrary/NamiBridgeModule.kt +0 -141
  84. package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +0 -51
  85. package/android/src/main/java/com/nami/reactlibrary/NamiFlowManagerBridge.kt +0 -60
  86. package/android/src/main/java/com/nami/reactlibrary/NamiMLManagerBridgeModule.kt +0 -58
  87. package/android/src/main/java/com/nami/reactlibrary/NamiManagerBridge.kt +0 -26
  88. package/android/src/main/java/com/nami/reactlibrary/NamiPaywallManagerBridgeModule.kt +0 -258
  89. package/android/src/main/java/com/nami/reactlibrary/NamiPurchaseManagerBridge.kt +0 -108
  90. package/build-utils/get_version_code.py +0 -140
  91. package/build-utils/preflight.py +0 -46
  92. package/ios/NamiMLManagerBridge.m +0 -93
  93. package/ios/NamiManager.m +0 -18
  94. package/ios/NamiManager.swift +0 -30
  95. package/ios/RNNami.h +0 -10
  96. package/ios/RNNami.m +0 -13
  97. package/src/Nami.d.ts +0 -8
  98. package/src/NamiCampaignManager.d.ts +0 -18
  99. package/src/NamiEntitlementManager.d.ts +0 -15
  100. package/src/NamiFlowManager.d.ts +0 -32
  101. package/src/NamiMLManager.d.ts +0 -7
  102. package/src/NamiMLManager.ts +0 -13
  103. package/src/NamiManager.d.ts +0 -5
  104. package/src/NamiManager.ts +0 -14
  105. package/src/NamiPaywallManager.d.ts +0 -34
  106. package/src/NamiPurchaseManager.d.ts +0 -20
@@ -1,16 +1,22 @@
1
- package com.nami.reactlibrary
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
- // import com.namiml.entitlement.NamiEntitlementSetter
7
- import com.facebook.react.bridge.Callback
6
+ import com.facebook.react.module.annotations.ReactModule
7
+ import com.facebook.react.turbomodule.core.interfaces.TurboModule
8
8
 
9
- class NamiEntitlementManagerBridgeModule(reactContext: ReactApplicationContext) :
10
- ReactContextBaseJavaModule(reactContext) {
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 "RNNamiEntitlementManager"
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(callback: Callback) {
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
- callback.invoke(resultArray)
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.nami.reactlibrary
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 = Arguments.createMap()
112
+ val productDict = WritableNativeMap()
78
113
 
79
- productDict.putString("skuId", this.skuId)
80
114
  productDict.putString("id", this.id)
81
- productDict.putString("type", this.type.toString())
115
+ productDict.putString("skuId", this.skuId)
116
+ productDict.putString("name", this.name ?: "")
117
+ productDict.putString("type", this.type?.toString() ?: "unknown")
82
118
 
83
- if (this.promoId != null) {
84
- productDict.putString("promoId", this.promoId)
119
+ this.promoId?.let {
120
+ productDict.putString("promoId", it)
85
121
  }
86
122
 
87
- if (this.promoOfferToken != null) {
88
- productDict.putString("promoToken", this.promoOfferToken)
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
- val purchaseSource = purchaseSource.toString()
99
- purchaseMap.putString("purchaseSource", purchaseSource)
133
+ purchaseMap.putString("skuId", skuId)
134
+ purchaseMap.putString("transactionIdentifier", transactionIdentifier.orEmpty())
100
135
 
101
- val skuDict = namiSku?.toSkuDict()
102
- purchaseMap.putMap("sku", skuDict)
136
+ purchaseSource?.let {
137
+ purchaseMap.putString("purchaseSource", it.toString())
138
+ }
103
139
 
104
- purchaseMap.putString("transactionIdentifier", transactionIdentifier.orEmpty())
105
- purchaseMap.putString("skuId", skuId)
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.putString("expires", it.toJavascriptDate())
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
- // TODO: map kotlin dictionary into arbitrary map?
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;