react-native-nami-sdk 3.0.17 → 3.0.18

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.
@@ -129,7 +129,7 @@ jobs:
129
129
  - name: Get expected build number
130
130
  run: |
131
131
  pip3 install requests
132
- pip3 install pydantic
132
+ pip3 install pydantic==1.10.11
133
133
  pip3 install cryptography
134
134
  pip3 install PyJWT
135
135
  echo "1.0" > $RUNNER_TEMP/.current_version
@@ -249,7 +249,7 @@ jobs:
249
249
  - name: Get expected build number
250
250
  run: |
251
251
  pip3 install requests
252
- pip3 install pydantic
252
+ pip3 install pydantic==1.10.11
253
253
  pip3 install cryptography
254
254
  pip3 install PyJWT
255
255
  echo "1.0" > $RUNNER_TEMP/.current_version
@@ -129,7 +129,7 @@ jobs:
129
129
  - name: Get expected build number
130
130
  run: |
131
131
  pip3 install requests
132
- pip3 install pydantic
132
+ pip3 install pydantic==1.10.11
133
133
  pip3 install cryptography
134
134
  pip3 install PyJWT
135
135
  echo "1.0" > $RUNNER_TEMP/.current_version
@@ -249,7 +249,7 @@ jobs:
249
249
  - name: Get expected build number
250
250
  run: |
251
251
  pip3 install requests
252
- pip3 install pydantic
252
+ pip3 install pydantic==1.10.11
253
253
  pip3 install cryptography
254
254
  pip3 install PyJWT
255
255
  echo "1.0" > $RUNNER_TEMP/.current_version
@@ -84,7 +84,7 @@ dependencies {
84
84
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
85
85
 
86
86
  implementation 'com.github.jeziellago:compose-markdown:0.3.0'
87
- implementation "com.namiml:sdk-android:3.0.19"
87
+ implementation "com.namiml:sdk-android:3.0.22"
88
88
 
89
89
  implementation 'com.facebook.react:react-native:+' // From node_modules
90
90
  coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
@@ -115,7 +115,7 @@ class NamiBridgeModule(reactContext: ReactApplicationContext) :
115
115
  } else {
116
116
  Arguments.createArray()
117
117
  }
118
- val settingsList = mutableListOf("extendedClientInfo:react-native:3.0.17")
118
+ val settingsList = mutableListOf("extendedClientInfo:react-native:3.0.18")
119
119
  namiCommandsReact?.toArrayList()?.filterIsInstance<String>()?.let { commandsFromReact ->
120
120
  settingsList.addAll(commandsFromReact)
121
121
  }
@@ -2,6 +2,7 @@ package com.nami.reactlibrary
2
2
 
3
3
  import android.app.Activity
4
4
  import android.content.Intent
5
+ import android.net.Uri
5
6
  import android.util.Log
6
7
  import com.facebook.react.bridge.*
7
8
  import com.facebook.react.modules.core.DeviceEventManagerModule
@@ -48,7 +49,7 @@ class NamiCampaignManagerBridgeModule(reactContext: ReactApplicationContext) :
48
49
  }
49
50
 
50
51
  @ReactMethod
51
- fun launch(label: String?, context: ReadableMap?, resultCallback: Callback, actionCallback: Callback) {
52
+ fun launch(label: String?, withUrl: String?, context: ReadableMap?, resultCallback: Callback, actionCallback: Callback) {
52
53
  var theActivity: Activity? = null
53
54
  if (reactApplicationContext.hasCurrentActivity()) {
54
55
  theActivity = reactApplicationContext.getCurrentActivity()
@@ -124,6 +125,8 @@ class NamiCampaignManagerBridgeModule(reactContext: ReactApplicationContext) :
124
125
  actionCallback)
125
126
  }
126
127
 
128
+ val uriObject: Uri? = if (withUrl != null) Uri.parse(withUrl) else null
129
+
127
130
  if (label != null) {
128
131
  NamiCampaignManager.launch(
129
132
  theActivity,
@@ -131,6 +134,13 @@ class NamiCampaignManagerBridgeModule(reactContext: ReactApplicationContext) :
131
134
  paywallActionCallback = paywallActionCallback,
132
135
  paywallLaunchContext,
133
136
  ) { result -> handleResult(result, resultCallback) }
137
+ } else if (withUrl != null) {
138
+ NamiCampaignManager.launch(
139
+ theActivity,
140
+ paywallActionCallback = paywallActionCallback,
141
+ context = paywallLaunchContext,
142
+ uri = uriObject,
143
+ ) { result -> handleResult(result, resultCallback) }
134
144
  } else {
135
145
  NamiCampaignManager.launch(
136
146
  theActivity,
@@ -241,12 +251,11 @@ class NamiCampaignManagerBridgeModule(reactContext: ReactApplicationContext) :
241
251
  }
242
252
 
243
253
  @ReactMethod
244
- fun isCampaignAvailable(label: String?, promise: Promise) {
245
- val isCampaignAvailable: Boolean
246
- if (label != null) {
247
- isCampaignAvailable = NamiCampaignManager.isCampaignAvailable(label)
248
- } else {
249
- isCampaignAvailable = NamiCampaignManager.isCampaignAvailable()
254
+ fun isCampaignAvailable(campaignSource: String?, promise: Promise) {
255
+ val isCampaignAvailable = when {
256
+ campaignSource == null -> NamiCampaignManager.isCampaignAvailable()
257
+ Uri.parse(campaignSource)?.scheme != null -> NamiCampaignManager.isCampaignAvailable(Uri.parse(campaignSource))
258
+ else -> NamiCampaignManager.isCampaignAvailable(campaignSource)
250
259
  }
251
260
  promise.resolve(isCampaignAvailable)
252
261
  }
@@ -209,6 +209,29 @@ class NamiPaywallManagerBridgeModule(reactContext: ReactApplicationContext) :
209
209
  }
210
210
  }
211
211
 
212
+ @ReactMethod
213
+ fun registerSignInHandler() {
214
+ NamiPaywallManager.registerSignInHandler { activity ->
215
+ latestPaywallActivity = activity
216
+ val map = Arguments.createMap().apply {
217
+ putBoolean("paywallSignInRequested", true)
218
+ }
219
+ reactApplicationContext
220
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
221
+ .emit("PaywallSignInRequested", map)
222
+ }
223
+ }
224
+
225
+ @ReactMethod
226
+ fun show() {
227
+ // Do nothing on Android side
228
+ }
229
+
230
+ @ReactMethod
231
+ fun hide() {
232
+ // Do nothing on Android side
233
+ }
234
+
212
235
  @ReactMethod
213
236
  fun addListener(eventName: String?) {
214
237
  }
package/ios/Nami.m CHANGED
@@ -52,7 +52,7 @@ RCT_EXPORT_METHOD(configure: (NSDictionary *)configDict completion: (RCTResponse
52
52
  }
53
53
 
54
54
  // Start commands with header iformation for Nami to let them know this is a React client.
55
- NSMutableArray *namiCommandStrings = [NSMutableArray arrayWithArray:@[@"extendedClientInfo:react-native:3.0.17"]];
55
+ NSMutableArray *namiCommandStrings = [NSMutableArray arrayWithArray:@[@"extendedClientInfo:react-native:3.0.18"]];
56
56
 
57
57
  // Add additional namiCommands app may have sent in.
58
58
  NSObject *appCommandStrings = configDict[@"namiCommands"];
@@ -9,11 +9,11 @@
9
9
 
10
10
  @interface RCT_EXTERN_MODULE(RNNamiCampaignManager, NSObject)
11
11
 
12
- RCT_EXTERN_METHOD(launch:(nullable NSString *)label context:(nullable NSDictionary *)context completion:(RCTResponseSenderBlock)callback paywallCompletion:(RCTResponseSenderBlock)cpaywallCallback)
12
+ RCT_EXTERN_METHOD(launch:(nullable NSString *)label withUrl:(nullable NSString *)withUrl context:(nullable NSDictionary *)context completion:(RCTResponseSenderBlock)callback paywallCompletion:(RCTResponseSenderBlock)paywallCallback);
13
13
 
14
14
  RCT_EXTERN_METHOD(allCampaigns:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
15
15
 
16
- RCT_EXTERN_METHOD(isCampaignAvailable:(nullable NSString *)label resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
16
+ RCT_EXTERN_METHOD(isCampaignAvailable:(nullable NSString *)campaignSource resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
17
17
 
18
18
  RCT_EXTERN_METHOD(refresh)
19
19
 
@@ -7,6 +7,7 @@
7
7
 
8
8
  import Foundation
9
9
  import NamiApple
10
+ import os
10
11
  import React
11
12
 
12
13
  @objc(RNNamiCampaignManager)
@@ -34,12 +35,102 @@ class RNNamiCampaignManager: RCTEventEmitter {
34
35
  return NSDictionary(dictionary: dictionary.compactMapValues { $0 })
35
36
  }
36
37
 
37
- @objc(launch:context:completion:paywallCompletion:)
38
- func launch(label: String?, context: NSDictionary?, callback: @escaping RCTResponseSenderBlock, paywallCallback _: @escaping RCTResponseSenderBlock) {
38
+ func isURL(string: String) -> Bool {
39
+ if let url = URL(string: string), url.scheme != nil, url.host != nil {
40
+ return true
41
+ }
42
+ return false
43
+ }
44
+
45
+ func handlePaywallAction(
46
+ campaignId: String?,
47
+ campaignName: String?,
48
+ campaignType: String?,
49
+ campaignLabel: String?,
50
+ campaignUrl: String?,
51
+ paywallId: String?,
52
+ paywallName: String?,
53
+ segmentId: String?,
54
+ externalSegmentId: String?,
55
+ action: NamiApple.NamiPaywallAction,
56
+ sku: NamiApple.NamiSKU?,
57
+ purchaseError: Error?,
58
+ purchases: [NamiApple.NamiPurchase],
59
+ deeplinkUrl: String?
60
+ ) {
61
+ let actionString: String
62
+ switch action {
63
+ case .show_paywall:
64
+ actionString = "SHOW_PAYWALL"
65
+ case .close_paywall:
66
+ actionString = "CLOSE_PAYWALL"
67
+ case .restore_purchases:
68
+ actionString = "RESTORE_PURCHASES"
69
+ case .sign_in:
70
+ actionString = "SIGN_IN"
71
+ case .buy_sku:
72
+ actionString = "BUY_SKU"
73
+ case .select_sku:
74
+ actionString = "SELECT_SKU"
75
+ case .purchase_selected_sku:
76
+ actionString = "PURCHASE_SELECTED_SKU"
77
+ case .purchase_success:
78
+ actionString = "PURCHASE_SUCCESS"
79
+ case .purchase_deferred:
80
+ actionString = "PURCHASE_DEFERRED"
81
+ case .purchase_failed:
82
+ actionString = "PURCHASE_FAILED"
83
+ case .purchase_cancelled:
84
+ actionString = "PURCHASE_CANCELLED"
85
+ case .purchase_unknown:
86
+ actionString = "PURCHASE_UNKNOWN"
87
+ case .deeplink:
88
+ actionString = "DEEPLINK"
89
+ @unknown default:
90
+ actionString = "PURCHASE_UNKNOWN"
91
+ }
92
+ let skuId = sku?.skuId
93
+ let errorSting = purchaseError?.localizedDescription
94
+
95
+ let dictionaries = purchases.map { purchase in RNNamiPurchaseManager.purchaseToPurchaseDict(purchase) }
96
+
97
+ let payload: [String: Any?] = [
98
+ "campaignId": campaignId,
99
+ "campaignName": campaignName,
100
+ "campaignType": campaignType,
101
+ "campaignLabel": campaignLabel,
102
+ "campaignUrl": campaignUrl,
103
+ "paywallId": paywallId,
104
+ "paywallName": paywallName,
105
+ "segmentId": segmentId,
106
+ "externalSegmentId": externalSegmentId,
107
+ "action": actionString,
108
+ "skuId": skuId,
109
+ "purchaseError": errorSting,
110
+ "purchases": dictionaries,
111
+ "deeplinkUrl": deeplinkUrl,
112
+ ]
113
+
114
+ RNNamiCampaignManager.shared?.sendEvent(withName: "ResultCampaign", body: payload)
115
+ }
116
+
117
+ func handleLaunch(callback: @escaping RCTResponseSenderBlock, success: Bool, error: Error?) {
118
+ callback([success, error?._code as Any])
119
+ }
120
+
121
+ @objc(launch:withUrl:context:completion:paywallCompletion:)
122
+ func launch(
123
+ label: String?,
124
+ withUrl: String?,
125
+ context: NSDictionary?,
126
+ callback: @escaping RCTResponseSenderBlock,
127
+ paywallCallback _: @escaping RCTResponseSenderBlock
128
+ ) {
39
129
  var paywallLaunchContext: PaywallLaunchContext?
40
130
 
41
131
  var productGroups: [String]?
42
132
  var customAttributes: [String: Any]?
133
+
43
134
  if let context = context {
44
135
  if let contextProductGroups = context["productGroups"] as? [String] {
45
136
  productGroups = contextProductGroups
@@ -53,62 +144,54 @@ class RNNamiCampaignManager: RCTEventEmitter {
53
144
  paywallLaunchContext = PaywallLaunchContext(productGroups: productGroups, customAttributes: customAttributes)
54
145
  }
55
146
 
56
- NamiCampaignManager.launch(label: label, context: paywallLaunchContext, launchHandler: { success, error in
57
- callback([success, error?._code as Any])
58
- }, paywallActionHandler: { campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl in
59
- let actionString: String
60
- switch action {
61
- case .show_paywall:
62
- actionString = "SHOW_PAYWALL"
63
- case .close_paywall:
64
- actionString = "CLOSE_PAYWALL"
65
- case .restore_purchases:
66
- actionString = "RESTORE_PURCHASES"
67
- case .sign_in:
68
- actionString = "SIGN_IN"
69
- case .buy_sku:
70
- actionString = "BUY_SKU"
71
- case .select_sku:
72
- actionString = "SELECT_SKU"
73
- case .purchase_selected_sku:
74
- actionString = "PURCHASE_SELECTED_SKU"
75
- case .purchase_success:
76
- actionString = "PURCHASE_SUCCESS"
77
- case .purchase_deferred:
78
- actionString = "PURCHASE_DEFERRED"
79
- case .purchase_failed:
80
- actionString = "PURCHASE_FAILED"
81
- case .purchase_cancelled:
82
- actionString = "PURCHASE_CANCELLED"
83
- case .purchase_unknown:
84
- actionString = "PURCHASE_UNKNOWN"
85
- case .deeplink:
86
- actionString = "DEEPLINK"
87
- @unknown default:
88
- actionString = "PURCHASE_UNKNOWN"
147
+ var launchMethod: (() -> Void)?
148
+
149
+ if let urlString = withUrl, let urlObject = URL(string: urlString) {
150
+ launchMethod = {
151
+ NamiCampaignManager.launch(url: urlObject, context: paywallLaunchContext,
152
+ launchHandler: { success, error in
153
+ self.handleLaunch(
154
+ callback: callback,
155
+ success: success,
156
+ error: error
157
+ )
158
+ },
159
+ paywallActionHandler: { campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl in
160
+ self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
161
+ })
162
+ }
163
+ } else if let label = label {
164
+ launchMethod = {
165
+ NamiCampaignManager.launch(label: label, context: paywallLaunchContext,
166
+ launchHandler: { success, error in
167
+ self.handleLaunch(
168
+ callback: callback,
169
+ success: success,
170
+ error: error
171
+ )
172
+ },
173
+ paywallActionHandler: { campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl in
174
+ self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
175
+ })
89
176
  }
90
- let skuId = sku?.skuId
91
- let errorSting = purchaseError?.localizedDescription
92
-
93
- let dictionaries = purchases.map { purchase in RNNamiPurchaseManager.purchaseToPurchaseDict(purchase) }
94
- let payload: [String: Any?] = [
95
- "campaignId": campaignId,
96
- "campaignName": campaignName,
97
- "campaignType": campaignType,
98
- "campaignLabel": campaignLabel,
99
- "campaignUrl": campaignUrl,
100
- "paywallId": paywallId,
101
- "paywallName": paywallName,
102
- "segmentId": segmentId,
103
- "externalSegmentId": externalSegmentId,
104
- "action": actionString,
105
- "skuId": skuId,
106
- "purchaseError": errorSting,
107
- "purchases": dictionaries,
108
- "deeplinkUrl": deeplinkUrl,
109
- ]
110
- RNNamiCampaignManager.shared?.sendEvent(withName: "ResultCampaign", body: payload)
111
- })
177
+ } else {
178
+ print("Neither URL nor label provided calling default launch.")
179
+ launchMethod = {
180
+ NamiCampaignManager.launch(context: paywallLaunchContext,
181
+ launchHandler: { success, error in
182
+ self.handleLaunch(
183
+ callback: callback,
184
+ success: success,
185
+ error: error
186
+ )
187
+ },
188
+ paywallActionHandler: { campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl in
189
+ self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
190
+ })
191
+ }
192
+ }
193
+
194
+ launchMethod?()
112
195
  }
113
196
 
114
197
  @objc(allCampaigns:rejecter:)
@@ -119,10 +202,20 @@ class RNNamiCampaignManager: RCTEventEmitter {
119
202
  }
120
203
 
121
204
  @objc(isCampaignAvailable:resolver:rejecter:)
122
- func isCampaignAvailable(label: String?, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
123
- let isCampaignAvailable: Bool
124
- if let label = label {
125
- isCampaignAvailable = NamiCampaignManager.isCampaignAvailable(label: label)
205
+ func isCampaignAvailable(
206
+ campaignSource: String?,
207
+ resolve: @escaping RCTPromiseResolveBlock,
208
+ reject _: @escaping RCTPromiseRejectBlock
209
+ ) {
210
+ var isCampaignAvailable: Bool
211
+ if let source = campaignSource {
212
+ if isURL(string: source), let url = URL(string: source) {
213
+ print("campaignSource is a URL: \(source)")
214
+ isCampaignAvailable = NamiCampaignManager.isCampaignAvailable(url: url)
215
+ } else {
216
+ print("campaignSource is a string: \(source)")
217
+ isCampaignAvailable = NamiCampaignManager.isCampaignAvailable(label: source)
218
+ }
126
219
  } else {
127
220
  isCampaignAvailable = NamiCampaignManager.isCampaignAvailable()
128
221
  }
@@ -33,9 +33,9 @@ RCT_EXTERN_METHOD(loggedInId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromis
33
33
 
34
34
  RCT_EXTERN_METHOD(deviceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
35
35
 
36
- RCT_EXTERN_METHOD(login:(NSString *)customerId completion:(RCTResponseSenderBlock)callback)
36
+ RCT_EXTERN_METHOD(login:(NSString *)customerId)
37
37
 
38
- RCT_EXTERN_METHOD(logout:(RCTResponseSenderBlock)callback)
38
+ RCT_EXTERN_METHOD(logout)
39
39
 
40
40
  RCT_EXTERN_METHOD(registerJourneyStateHandler)
41
41
 
@@ -70,7 +70,7 @@ class RNNamiCustomerManager: RCTEventEmitter {
70
70
  func setAnonymousMode(anonymousMode: Bool) {
71
71
  NamiCustomerManager.setAnonymousMode(anonymousMode)
72
72
  }
73
-
73
+
74
74
  @objc(inAnonymousMode:rejecter:)
75
75
  func inAnonymousMode(resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
76
76
  let inAnonymousMode: Bool = NamiCustomerManager.inAnonymousMode()
@@ -105,18 +105,14 @@ class RNNamiCustomerManager: RCTEventEmitter {
105
105
  resolve(id)
106
106
  }
107
107
 
108
- @objc(login:completion:)
109
- func login(customerId: String, callback: @escaping RCTResponseSenderBlock) {
110
- NamiCustomerManager.login(withId: customerId, loginCompleteHandler: { success, error in
111
- callback([success, error?._code as Any])
112
- })
108
+ @objc(login:)
109
+ func login(customerId: String) {
110
+ NamiCustomerManager.login(withId: customerId)
113
111
  }
114
112
 
115
- @objc(logout:)
116
- func logout(callback: @escaping RCTResponseSenderBlock) {
117
- NamiCustomerManager.logout(logoutCompleteHandler: { success, error in
118
- callback([success, error?._code as Any])
119
- })
113
+ @objc(logout)
114
+ func logout() {
115
+ NamiCustomerManager.logout()
120
116
  }
121
117
 
122
118
  @objc(registerJourneyStateHandler)
@@ -2,8 +2,7 @@
2
2
  // NamiPaywallManager.m
3
3
  // namiReactNative
4
4
  //
5
- // Created by Kendall Gelner on 11/22/19.
6
- // Copyright © 2019 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2023 Nami ML Inc. All rights reserved.
7
6
  //
8
7
 
9
8
  #import <Foundation/Foundation.h>
@@ -22,8 +21,14 @@ RCT_EXTERN_METHOD(registerBuySkuHandler)
22
21
 
23
22
  RCT_EXTERN_METHOD(registerCloseHandler)
24
23
 
24
+ RCT_EXTERN_METHOD(registerSignInHandler)
25
+
25
26
  RCT_EXTERN_METHOD(dismiss:(BOOL)animated)
26
27
 
28
+ RCT_EXTERN_METHOD(show)
29
+
30
+ RCT_EXTERN_METHOD(hide)
31
+
27
32
  + (BOOL)requiresMainQueueSetup {
28
33
  return YES;
29
34
  }
@@ -19,7 +19,7 @@ class RNNamiPaywallManager: RCTEventEmitter {
19
19
  }
20
20
 
21
21
  override func supportedEvents() -> [String]! {
22
- return ["RegisterBuySKU", "PaywallCloseRequested"]
22
+ return ["RegisterBuySKU", "PaywallCloseRequested", "PaywallSignInRequested"]
23
23
  }
24
24
 
25
25
  @objc(buySkuComplete:)
@@ -95,8 +95,30 @@ class RNNamiPaywallManager: RCTEventEmitter {
95
95
  }
96
96
  }
97
97
 
98
+ @objc(registerSignInHandler)
99
+ func registerSignInHandler() {
100
+ NamiPaywallManager.registerSignInHandler { _ in
101
+ let dictionary = NSDictionary(dictionary: ["PaywallSignInRequested": true].compactMapValues { $0 })
102
+ RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallSignInRequested", body: dictionary)
103
+ }
104
+ }
105
+
98
106
  @objc(dismiss:)
99
107
  func dismiss(animated: Bool) {
100
108
  NamiPaywallManager.dismiss(animated: animated) {}
101
109
  }
110
+
111
+ @objc(show)
112
+ func show() {
113
+ DispatchQueue.main.async {
114
+ NamiPaywallManager.show()
115
+ }
116
+ }
117
+
118
+ @objc(hide)
119
+ func hide() {
120
+ DispatchQueue.main.async {
121
+ NamiPaywallManager.hide()
122
+ }
123
+ }
102
124
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nami-sdk",
3
- "version": "3.0.17",
3
+ "version": "3.0.18",
4
4
  "description": "React Native Module for Nami - Easy subscriptions & in-app purchases, with powerful built-in paywalls and A/B testing.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -20,7 +20,7 @@ Pod::Spec.new do |s|
20
20
  s.source_files = "ios/**/*.{h,m,swift}"
21
21
  s.requires_arc = true
22
22
 
23
- s.dependency 'Nami', '3.0.20'
23
+ s.dependency 'Nami', '3.0.23'
24
24
  s.dependency 'React'
25
25
 
26
26
  end
package/src/Nami.d.ts CHANGED
@@ -1,112 +1,112 @@
1
1
  export const Nami: {
2
2
  configure: (
3
3
  config: NamiConfiguration,
4
- resultCallback?: (resultObject: { success: boolean }) => void
4
+ resultCallback?: (resultObject: {success: boolean}) => void,
5
5
  ) => void;
6
6
  };
7
7
 
8
8
  export type NamiConfiguration = {
9
- "appPlatformID-apple": string;
10
- "appPlatformID-android": string;
9
+ 'appPlatformID-apple': string;
10
+ 'appPlatformID-android': string;
11
11
  logLevel: string;
12
12
  namiLanguageCode?: NamiLanguageCodes;
13
13
  initialConfig?: string;
14
14
  };
15
15
 
16
16
  export type NamiLanguageCodes =
17
- | "af"
18
- | "ar"
19
- | "ar-dz"
20
- | "ast"
21
- | "az"
22
- | "bg"
23
- | "be"
24
- | "bn"
25
- | "br"
26
- | "bs"
27
- | "ca"
28
- | "cs"
29
- | "cy"
30
- | "da"
31
- | "de"
32
- | "dsb"
33
- | "el"
34
- | "en"
35
- | "en-au"
36
- | "en-gb"
37
- | "eo"
38
- | "es"
39
- | "es-ar"
40
- | "es-co"
41
- | "es-mx"
42
- | "es-ni"
43
- | "es-ve"
44
- | "et"
45
- | "eu"
46
- | "fa"
47
- | "fi"
48
- | "fr"
49
- | "fy"
50
- | "ga"
51
- | "gd"
52
- | "gl"
53
- | "he"
54
- | "hi"
55
- | "hr"
56
- | "hsb"
57
- | "hu"
58
- | "hy"
59
- | "ia"
60
- | "id"
61
- | "ig"
62
- | "io"
63
- | "is"
64
- | "it"
65
- | "ja"
66
- | "ka"
67
- | "kab"
68
- | "kk"
69
- | "km"
70
- | "kn"
71
- | "ko"
72
- | "ky"
73
- | "lb"
74
- | "lt"
75
- | "lv"
76
- | "mk"
77
- | "ml"
78
- | "mn"
79
- | "mr"
80
- | "my"
81
- | "nb"
82
- | "ne"
83
- | "nl"
84
- | "nn"
85
- | "os"
86
- | "pa"
87
- | "pl"
88
- | "pt"
89
- | "pt-br"
90
- | "ro"
91
- | "ru"
92
- | "sk"
93
- | "sl"
94
- | "sq"
95
- | "sr"
96
- | "sr-latn"
97
- | "sv"
98
- | "sw"
99
- | "ta"
100
- | "te"
101
- | "tg"
102
- | "th"
103
- | "tk"
104
- | "tr"
105
- | "tt"
106
- | "udm"
107
- | "uk"
108
- | "ur"
109
- | "uz"
110
- | "vi"
111
- | "zh-hans"
112
- | "zh-hant";
17
+ | 'af'
18
+ | 'ar'
19
+ | 'ar-dz'
20
+ | 'ast'
21
+ | 'az'
22
+ | 'bg'
23
+ | 'be'
24
+ | 'bn'
25
+ | 'br'
26
+ | 'bs'
27
+ | 'ca'
28
+ | 'cs'
29
+ | 'cy'
30
+ | 'da'
31
+ | 'de'
32
+ | 'dsb'
33
+ | 'el'
34
+ | 'en'
35
+ | 'en-au'
36
+ | 'en-gb'
37
+ | 'eo'
38
+ | 'es'
39
+ | 'es-ar'
40
+ | 'es-co'
41
+ | 'es-mx'
42
+ | 'es-ni'
43
+ | 'es-ve'
44
+ | 'et'
45
+ | 'eu'
46
+ | 'fa'
47
+ | 'fi'
48
+ | 'fr'
49
+ | 'fy'
50
+ | 'ga'
51
+ | 'gd'
52
+ | 'gl'
53
+ | 'he'
54
+ | 'hi'
55
+ | 'hr'
56
+ | 'hsb'
57
+ | 'hu'
58
+ | 'hy'
59
+ | 'ia'
60
+ | 'id'
61
+ | 'ig'
62
+ | 'io'
63
+ | 'is'
64
+ | 'it'
65
+ | 'ja'
66
+ | 'ka'
67
+ | 'kab'
68
+ | 'kk'
69
+ | 'km'
70
+ | 'kn'
71
+ | 'ko'
72
+ | 'ky'
73
+ | 'lb'
74
+ | 'lt'
75
+ | 'lv'
76
+ | 'mk'
77
+ | 'ml'
78
+ | 'mn'
79
+ | 'mr'
80
+ | 'my'
81
+ | 'nb'
82
+ | 'ne'
83
+ | 'nl'
84
+ | 'nn'
85
+ | 'os'
86
+ | 'pa'
87
+ | 'pl'
88
+ | 'pt'
89
+ | 'pt-br'
90
+ | 'ro'
91
+ | 'ru'
92
+ | 'sk'
93
+ | 'sl'
94
+ | 'sq'
95
+ | 'sr'
96
+ | 'sr-latn'
97
+ | 'sv'
98
+ | 'sw'
99
+ | 'ta'
100
+ | 'te'
101
+ | 'tg'
102
+ | 'th'
103
+ | 'tk'
104
+ | 'tr'
105
+ | 'tt'
106
+ | 'udm'
107
+ | 'uk'
108
+ | 'ur'
109
+ | 'uz'
110
+ | 'vi'
111
+ | 'zh-hans'
112
+ | 'zh-hant';
package/src/Nami.js CHANGED
@@ -1,6 +1,6 @@
1
- import { NativeModules } from "react-native";
1
+ import {NativeModules} from 'react-native';
2
2
 
3
- export const { NamiBridge } = NativeModules;
3
+ export const {NamiBridge} = NativeModules;
4
4
 
5
5
  export const Nami = {
6
6
  ...NamiBridge,
@@ -1,12 +1,13 @@
1
- import {EmitterSubscription} from 'react-native';
2
- import {NamiPurchase} from './NamiPurchaseManager';
3
- import {NamiPaywallAction} from './NamiPaywallManager';
1
+ import { EmitterSubscription } from "react-native";
2
+ import { NamiPurchase } from "./NamiPurchaseManager";
3
+ import { NamiPaywallAction } from "./NamiPaywallManager";
4
4
 
5
5
  export const NamiCampaignManager: {
6
6
  allCampaigns: () => Promise<Array<NamiCampaign>>;
7
- isCampaignAvailable: (label?: string) => boolean;
7
+ isCampaignAvailable(campaignSource: string | null): Promise<boolean>;
8
8
  launch: (
9
9
  label?: string,
10
+ withUrl?: string,
10
11
  context?: PaywallLaunchContext,
11
12
  resultCallback?: (success: boolean, error?: LaunchCampaignError) => void,
12
13
  actionCallback?: (
@@ -23,13 +24,13 @@ export const NamiCampaignManager: {
23
24
  deeplinkUrl?: string,
24
25
  skuId?: string,
25
26
  purchaseError?: string,
26
- purchases?: NamiPurchase[],
27
- ) => void,
27
+ purchases?: NamiPurchase[]
28
+ ) => void
28
29
  ) => void;
29
30
  refresh: () => void;
30
31
  registerAvailableCampaignsHandler: (
31
- callback: (availableCampaigns: NamiCampaign[]) => void,
32
- ) => EmitterSubscription['remove'];
32
+ callback: (availableCampaigns: NamiCampaign[]) => void
33
+ ) => EmitterSubscription["remove"];
33
34
  };
34
35
 
35
36
  export type NamiCampaign = {
@@ -42,10 +43,10 @@ export type NamiCampaign = {
42
43
  };
43
44
 
44
45
  export enum NamiCampaignRule {
45
- DEFAULT = 'default',
46
- LABEL = 'label',
47
- UNKNOWN = 'unknown',
48
- URL = 'url',
46
+ DEFAULT = "default",
47
+ LABEL = "label",
48
+ UNKNOWN = "unknown",
49
+ URL = "url",
49
50
  }
50
51
 
51
52
  export enum LaunchCampaignError {
@@ -57,8 +58,8 @@ export enum LaunchCampaignError {
57
58
  }
58
59
 
59
60
  export enum LaunchCampaignResultAction {
60
- FAILURE = 'FAILURE',
61
- SUCCESS = 'SUCCESS',
61
+ FAILURE = "FAILURE",
62
+ SUCCESS = "SUCCESS",
62
63
  }
63
64
 
64
65
  export type FailureResultObject = {
@@ -1,17 +1,17 @@
1
- import {NativeModules, NativeEventEmitter} from 'react-native';
1
+ import { NativeModules, NativeEventEmitter } from "react-native";
2
2
 
3
- export const {RNNamiCampaignManager} = NativeModules;
3
+ export const { RNNamiCampaignManager } = NativeModules;
4
4
 
5
5
  export const NamiCampaignManager = {
6
6
  launchSubscription: undefined,
7
7
  emitter: new NativeEventEmitter(RNNamiCampaignManager),
8
8
  ...RNNamiCampaignManager,
9
- launch(label, context, resultCallback, actionCallback) {
9
+ launch(label, withUrl, context, resultCallback, actionCallback) {
10
10
  this.launchSubscription?.remove();
11
11
  this.launchSubscription = this.emitter.addListener(
12
- 'ResultCampaign',
13
- body => {
14
- body.action = body.action.startsWith('NAMI_')
12
+ "ResultCampaign",
13
+ (body) => {
14
+ body.action = body.action.startsWith("NAMI_")
15
15
  ? body.action.substring(5, body.action.length)
16
16
  : body.action;
17
17
 
@@ -45,25 +45,26 @@ export const NamiCampaignManager = {
45
45
  segmentId,
46
46
  externalSegmentId,
47
47
  paywallName,
48
- deeplinkUrl,
48
+ deeplinkUrl
49
49
  );
50
- },
50
+ }
51
51
  );
52
52
 
53
53
  RNNamiCampaignManager.launch(
54
- label ?? null,
54
+ label,
55
+ withUrl ?? null,
55
56
  context ?? null,
56
57
  resultCallback ?? (() => {}),
57
- actionCallback ?? (() => {}),
58
+ actionCallback ?? (() => {})
58
59
  );
59
60
  },
60
- isCampaignAvailable: label => {
61
- return RNNamiCampaignManager.isCampaignAvailable(label ?? null);
61
+ isCampaignAvailable: (campaignSource) => {
62
+ return RNNamiCampaignManager.isCampaignAvailable(campaignSource ?? null);
62
63
  },
63
64
  registerAvailableCampaignsHandler(callback) {
64
65
  const subscription = this.emitter.addListener(
65
- 'AvailableCampaignsChanged',
66
- callback,
66
+ "AvailableCampaignsChanged",
67
+ callback
67
68
  );
68
69
  RNNamiCampaignManager.registerAvailableCampaignsHandler();
69
70
  return subscription.remove;
@@ -1,4 +1,4 @@
1
- import { EmitterSubscription } from "react-native";
1
+ import { EmitterSubscription } from 'react-native';
2
2
 
3
3
  export const NamiCustomerManager: {
4
4
  setCustomerAttribute: (key: string, value: string) => void;
@@ -9,21 +9,18 @@ export const NamiCustomerManager: {
9
9
  isLoggedIn: () => Promise<boolean>;
10
10
  loggedInId: () => Promise<string | undefined>;
11
11
  deviceId: () => Promise<string>;
12
- login: (
13
- customerId: string,
14
- callback?: (success: boolean, error?: number) => void
15
- ) => void;
16
- logout: (callback?: (success: boolean, error?: number) => void) => void;
12
+ login: (customerId: string) => void;
13
+ logout: () => void;
17
14
  registerJourneyStateHandler: (
18
- callback: (journeyState: CustomerJourneyState) => void
19
- ) => EmitterSubscription["remove"];
15
+ callback: (journeyState: CustomerJourneyState) => void,
16
+ ) => EmitterSubscription['remove'];
20
17
  registerAccountStateHandler: (
21
18
  callback: (
22
19
  action: AccountStateAction,
23
20
  success: boolean,
24
- error?: number
25
- ) => void
26
- ) => EmitterSubscription["remove"];
21
+ error?: number,
22
+ ) => void,
23
+ ) => EmitterSubscription['remove'];
27
24
  clearCustomerDataPlatformId: () => void;
28
25
  setCustomerDataPlatformId: (platformId: string) => void;
29
26
  setAnonymousMode: (anonymousMode: boolean) => void;
@@ -40,4 +37,16 @@ export type CustomerJourneyState = {
40
37
  inAccountHold: boolean;
41
38
  };
42
39
 
43
- export type AccountStateAction = "login" | "logout" | "advertising_id_set" | "vendor_id_set" | "customer_data_platform_id_set" | "nami_device_id_set" | "advertising_id_cleared" | "vendor_id_cleared" | "customer_data_platform_id_cleared" | "nami_device_id_cleared" | "anonymous_mode_on" | "anonymous_mode_off";
40
+ export type AccountStateAction =
41
+ | 'login'
42
+ | 'logout'
43
+ | 'advertising_id_set'
44
+ | 'vendor_id_set'
45
+ | 'customer_data_platform_id_set'
46
+ | 'nami_device_id_set'
47
+ | 'advertising_id_cleared'
48
+ | 'vendor_id_cleared'
49
+ | 'customer_data_platform_id_cleared'
50
+ | 'nami_device_id_cleared'
51
+ | 'anonymous_mode_on'
52
+ | 'anonymous_mode_off';
@@ -1,41 +1,33 @@
1
- import { NativeModules, NativeEventEmitter, Platform } from "react-native";
1
+ import { NativeModules, NativeEventEmitter } from 'react-native';
2
2
 
3
3
  export const { RNNamiCustomerManager } = NativeModules;
4
4
 
5
5
  export const NamiCustomerManager = {
6
6
  emitter: new NativeEventEmitter(RNNamiCustomerManager),
7
7
  ...RNNamiCustomerManager,
8
- login: (customerId, callback) => {
9
- if (Platform.OS === "ios" || Platform.isTVOS) {
10
- RNNamiCustomerManager.login(customerId, callback ?? (() => {}));
11
- } else {
12
- RNNamiCustomerManager.login(customerId);
13
- }
8
+ login: customerId => {
9
+ RNNamiCustomerManager.login(customerId);
14
10
  },
15
- logout: (callback) => {
16
- if (Platform.OS === "ios" || Platform.isTVOS) {
17
- RNNamiCustomerManager.logout(callback ?? (() => {}));
18
- } else {
19
- RNNamiCustomerManager.logout();
20
- }
11
+ logout: () => {
12
+ RNNamiCustomerManager.logout();
21
13
  },
22
14
  registerJourneyStateHandler(callback) {
23
15
  const subscription = this.emitter.addListener(
24
- "JourneyStateChanged",
25
- callback
16
+ 'JourneyStateChanged',
17
+ callback,
26
18
  );
27
19
  RNNamiCustomerManager.registerJourneyStateHandler();
28
20
  return subscription.remove;
29
21
  },
30
22
  registerAccountStateHandler(callback) {
31
23
  const subscription = this.emitter.addListener(
32
- "AccountStateChanged",
33
- (body) => {
24
+ 'AccountStateChanged',
25
+ body => {
34
26
  var action = body.action.toLowerCase();
35
27
  var error = body.error;
36
28
  var success = body.success;
37
29
  callback(action, success, error);
38
- }
30
+ },
39
31
  );
40
32
  RNNamiCustomerManager.registerAccountStateHandler();
41
33
  return subscription.remove;
@@ -12,6 +12,9 @@ export const NamiPaywallManager: {
12
12
  callback: (sku: NamiSKU) => void
13
13
  ) => EmitterSubscription["remove"];
14
14
  registerCloseHandler: (callback: () => void) => EmitterSubscription["remove"];
15
+ registerSignInHandler: (callback: () => void) => EmitterSubscription["remove"];
16
+ show: () => void;
17
+ hide: () => void;
15
18
  };
16
19
 
17
20
  export type NamiPurchaseSuccessApple = {
@@ -36,7 +36,24 @@ export const NamiPaywallManager = {
36
36
  RNNamiPaywallManager.registerCloseHandler();
37
37
  return subscription.remove;
38
38
  },
39
+ registerSignInHandler(callback) {
40
+ var subscription;
41
+ subscription = this.paywallEmitter.addListener(
42
+ "PaywallSignInRequested",
43
+ (body) => {
44
+ callback(body);
45
+ }
46
+ );
47
+ RNNamiPaywallManager.registerSignInHandler();
48
+ return subscription.remove;
49
+ },
39
50
  dismiss(animated) {
40
51
  RNNamiPaywallManager.dismiss(animated ?? true);
41
52
  },
53
+ show: () => {
54
+ RNNamiPaywallManager.show();
55
+ },
56
+ logout: () => {
57
+ RNNamiPaywallManager.hide();
58
+ },
42
59
  };