react-native-nami-sdk 2.0.5 → 3.0.8

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 +6 -50
  6. package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +1 -0
  7. package/android/src/main/java/com/nami/reactlibrary/NamiCampaignManagerBridge.kt +133 -0
  8. package/android/src/main/java/com/nami/reactlibrary/NamiCustomerManagerBridge.kt +88 -19
  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 +36 -147
  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 +107 -0
  22. package/ios/NamiCustomerManager.m +18 -23
  23. package/ios/NamiCustomerManager.swift +122 -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 +84 -8
  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 +54 -0
  43. package/src/NamiCampaignManager.js +43 -0
  44. package/src/NamiCustomerManager.d.ts +39 -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 +57 -0
  51. package/src/NamiPaywallManager.js +28 -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
@@ -0,0 +1,203 @@
1
+ name: Generate Test React STG
2
+ on:
3
+ workflow_dispatch:
4
+ inputs:
5
+ ref:
6
+ default: develop
7
+ description: "Git Tag, Branch or SHA to build"
8
+ required: true
9
+ secrets:
10
+ BUILD_USER_PAT:
11
+ required: true
12
+
13
+ pull_request:
14
+ types:
15
+ - closed
16
+ branches:
17
+ - develop
18
+ secrets:
19
+ BUILD_USER_PAT:
20
+ required: true
21
+
22
+ jobs:
23
+ build-android:
24
+ name: Generate Play Store STG
25
+ permissions:
26
+ actions: write
27
+ contents: write
28
+ id-token: write
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - uses: actions/setup-node@v3
32
+ with:
33
+ node-version: "16"
34
+
35
+ - name: 'Checkout ${{ inputs.ref }}'
36
+ uses: actions/checkout@v2
37
+ with:
38
+ path: source
39
+ ref: '${{ inputs.ref }}'
40
+
41
+ - name: Install Google API python client
42
+ run: |
43
+ pip install google-api-python-client
44
+
45
+ - name: Get new version code
46
+ run: |
47
+ echo $GOOGLE_PLAY_SERVICE_ACCOUNT > $RUNNER_TEMP/.service_account
48
+ python3 build-utils/get_version_code.py $RUNNER_TEMP/.service_account com.namiml.stg.testreactnative internal --quiet >> $RUNNER_TEMP/.new_version_code
49
+ rm -f .service_account
50
+ env:
51
+ GOOGLE_PLAY_SERVICE_ACCOUNT: '${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT }}'
52
+ working-directory: source
53
+
54
+ - name: Update version code
55
+ working-directory: source/examples/Basic/android/app
56
+ run: |
57
+ NEW_VERSION_CODE=`cat $RUNNER_TEMP/.new_version_code`
58
+ echo $NEW_VERSION_CODE
59
+ sed -i "s/versionCode 1/versionCode $NEW_VERSION_CODE/" build.gradle
60
+
61
+ - name: Create the Keystore
62
+ run: |
63
+ # import keystore from secrets
64
+ echo $KEYSTORE_BASE64 | base64 -d > $RUNNER_TEMP/my_production.keystore
65
+ env:
66
+ KEYSTORE_BASE64: '${{ secrets.KEY_STORE_BASE64 }}'
67
+
68
+ - name: Install test app dependencies
69
+ run: |
70
+ yarn install
71
+ working-directory: source/examples/Basic
72
+
73
+ - name: Build Android App Bundle
74
+ run: |
75
+ ./gradlew clean bundleStagingRelease
76
+ working-directory: source/examples/Basic/android
77
+
78
+ - name: Sign Android App Bundle
79
+ run: |
80
+ jarsigner -keystore $RUNNER_TEMP/my_production.keystore -storepass '${{ secrets.KEY_STORE_PASSWORD }}' -keypass '${{ secrets.KEY_PASSWORD }}' -sigalg SHA256withRSA -digestalg SHA-256 -signedjar build/outputs/bundle/stagingRelease/app-staging-release-signed.aab build/outputs/bundle/stagingRelease/app-staging-release.aab '${{ secrets.KEY_ALIAS }}'
81
+ working-directory: source/examples/Basic/android/app
82
+
83
+ - name: Uploading to test track
84
+ uses: r0adkll/upload-google-play@v1.0.17
85
+ with:
86
+ packageName: 'com.namiml.stg.testreactnative'
87
+ releaseFiles: source/examples/Basic/android/app/build/outputs/bundle/stagingRelease/app-staging-release-signed.aab
88
+ serviceAccountJsonPlainText: '${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT }}'
89
+ status: completed
90
+ track: internal
91
+ build-ios:
92
+ name: Generate Apple STG
93
+ permissions:
94
+ actions: write
95
+ contents: write
96
+ id-token: write
97
+ runs-on: macos-12
98
+ timeout-minutes: 40
99
+ steps:
100
+ - uses: actions/setup-node@v3
101
+ with:
102
+ node-version: "16"
103
+
104
+ - name: "Checkout ${{ inputs.ref }}"
105
+ uses: actions/checkout@v2
106
+ with:
107
+ path: source
108
+ ref: "${{ inputs.ref }}"
109
+
110
+ - name: Checkout appstoreconnect-build-tools
111
+ uses: actions/checkout@v2
112
+ with:
113
+ path: appstoreconnect-build-tools
114
+ ref: main
115
+ repository: namiml/appstoreconnect-build-tools
116
+
117
+ - name: Set up Python
118
+ uses: actions/setup-python@v1
119
+ with:
120
+ python-version: "3.10"
121
+
122
+ - name: Get expected build number
123
+ run: |
124
+ pip3 install requests
125
+ pip3 install pydantic
126
+ pip3 install cryptography
127
+ pip3 install PyJWT
128
+ echo "1.0" > $RUNNER_TEMP/.current_version
129
+ export CURRENT_VERSION=`cat $RUNNER_TEMP/.current_version`
130
+ python3 get_next_build.py com.namiml.stg.testreactnative --prerelease --version=$CURRENT_VERSION > $RUNNER_TEMP/.next_build_number
131
+ working-directory: appstoreconnect-build-tools
132
+ env:
133
+ APPSTORE_API_KEY_ID: "${{ secrets.APPSTORE_API_KEY_ID }}"
134
+ APPSTORE_API_PRIVATE_KEY: "${{ secrets.APPSTORE_API_PRIVATE_KEY }}"
135
+ APPSTORE_ISSUER_ID: "${{ secrets.APPSTORE_ISSUER_ID }}"
136
+
137
+ - name: Install Apple Certificate
138
+ uses: apple-actions/import-codesign-certs@v1
139
+ with:
140
+ p12-file-base64: "${{ secrets.IOS_P12_BASE64 }}"
141
+ p12-password: "${{ secrets.IOS_CERTIFICATE_PASSWORD }}"
142
+
143
+ - name: Install the provisioning profile
144
+ run: |
145
+ PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
146
+ echo -n "$PROVISIONING_CERTIFICATE_BASE64" | base64 --decode --output $PP_PATH
147
+ mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
148
+ cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
149
+ env:
150
+ PROVISIONING_CERTIFICATE_BASE64: "${{ secrets.IOS_MOBILE_PROVISION_BASE64_TEST_REACT_STG }}"
151
+
152
+ - name: Store App Store Private Key
153
+ run: |
154
+ mkdir ~/.private_keys
155
+ echo '${{ secrets.APPSTORE_API_PRIVATE_KEY }}' > ~/.private_keys/AuthKey_'${{ secrets.APPSTORE_API_KEY_ID }}'.p8
156
+
157
+ - name: Update ExportOptions.plist
158
+ run: |
159
+ sed -i '' -e "s/APPSTORE_TEAM_ID/${{ secrets.APPSTORE_TEAM_ID }}/" ExportOptions.plist
160
+ sed -i '' -e "s/APPSTORE_PROVISIONING_PROFILE_UUID/${{ secrets.APPSTORE_PROV_PROFILE_UUID_TEST_REACT_STG }}/g" ExportOptions.plist
161
+ working-directory: source/examples/Basic/ios
162
+
163
+ - name: Adjust version & build number
164
+ run: |-
165
+ export CURRENT_VERSION=`cat $RUNNER_TEMP/.current_version`
166
+ export BUILD_NUMBER=`cat $RUNNER_TEMP/.next_build_number`
167
+ sed -i '' -e "s/CURRENT_PROJECT_VERSION = 1/CURRENT_PROJECT_VERSION = $BUILD_NUMBER/" ios/Basic.xcodeproj/project.pbxproj
168
+ sed -i '' -e "s/MARKETING_VERSION = 1.0/MARKETING_VERSION = $CURRENT_VERSION/" ios/Basic.xcodeproj/project.pbxproj
169
+ sed -i '' -e "s/<string>1<\/string>/<string>$BUILD_NUMBER<\/string>/" ios/Basic/Info.plist
170
+ working-directory: source/examples/Basic
171
+
172
+ - name: Install test app dependencies
173
+ run: |
174
+ yarn install
175
+ working-directory: source/examples/Basic
176
+
177
+ - name: Install test iOS dependencies
178
+ run: |
179
+ pod install
180
+ working-directory: source/examples/Basic/ios
181
+
182
+ - name: Build resolve Swift dependencies
183
+ run: |
184
+ xcodebuild -resolvePackageDependencies -workspace ios/Basic.xcworkspace -scheme Basic -configuration Release
185
+ working-directory: source/examples/Basic
186
+
187
+ - name: Build xArchive
188
+ run: |
189
+ xcodebuild -workspace ios/Basic.xcworkspace -scheme Basic -configuration Release DEVELOPMENT_TEAM='${{ secrets.APPSTORE_TEAM_ID }}' -sdk 'iphoneos' -destination 'generic/platform=iOS' -archivePath build-output/app-stg.xcarchive PROVISIONING_PROFILE='${{ secrets.APPSTORE_PROV_PROFILE_UUID_TEST_REACT_STG }}' clean archive CODE_SIGN_IDENTITY='${{ secrets.CODE_SIGNING_IDENTITY }}'
190
+ working-directory: source/examples/Basic
191
+
192
+ - name: Export IPA
193
+ run: |
194
+ xcodebuild -exportArchive -archivePath build-output/app-stg.xcarchive -exportPath build-output/ios-stg -exportOptionsPlist ios/ExportOptions.plist
195
+ working-directory: source/examples/Basic
196
+
197
+ - name: Upload app to TestFlight
198
+ run: |
199
+ xcrun altool --upload-app --type ios --file build-output/ios-stg/Basic.ipa --apiKey $APPSTORE_API_KEY_ID --apiIssuer $APPSTORE_ISSUER_ID
200
+ working-directory: source/examples/Basic
201
+ env:
202
+ APPSTORE_API_KEY_ID: "${{ secrets.APPSTORE_API_KEY_ID }}"
203
+ APPSTORE_ISSUER_ID: "${{ secrets.APPSTORE_ISSUER_ID }}"
@@ -16,7 +16,7 @@ repos:
16
16
  - id: trailing-whitespace
17
17
  exclude: ^.*\b(\.(js|jsx|tsx).snap)\b$
18
18
  - repo: https://github.com/nicklockwood/SwiftFormat
19
- rev: 0.50.8
19
+ rev: 0.50.8
20
20
  hooks:
21
21
  - id: swiftformat
22
22
  - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
@@ -15,7 +15,7 @@ def safeExtGet(prop, fallback) {
15
15
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
16
16
  }
17
17
  apply plugin: 'com.android.library'
18
- apply plugin: 'maven'
18
+ // apply plugin: 'maven'
19
19
  apply plugin: "kotlin-android"
20
20
  apply plugin: "kotlin-android-extensions"
21
21
  buildscript {
@@ -30,17 +30,17 @@ buildscript {
30
30
  google()
31
31
  }
32
32
  dependencies {
33
- classpath 'com.android.tools.build:gradle:4.2.1'
33
+ classpath 'com.android.tools.build:gradle:7.0.4'
34
34
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
35
35
  }
36
36
  }
37
37
  }
38
38
  android {
39
- compileSdkVersion 31
39
+ compileSdkVersion 33
40
40
  buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION)
41
41
  defaultConfig {
42
- minSdkVersion 26
43
- targetSdkVersion 31
42
+ minSdkVersion 22
43
+ targetSdkVersion 33
44
44
  versionCode 1
45
45
  versionName "1.0"
46
46
  }
@@ -52,7 +52,10 @@ android {
52
52
  abortOnError false
53
53
  }
54
54
  kotlinOptions {
55
- jvmTarget = "1.8"
55
+ jvmTarget = JavaVersion.VERSION_1_8.toString()
56
+ }
57
+ dexOptions {
58
+ javaMaxHeapSize "4g"
56
59
  }
57
60
  }
58
61
  repositories {
@@ -60,6 +63,7 @@ repositories {
60
63
  // ref: https://www.baeldung.com/maven-local-repository
61
64
  mavenLocal()
62
65
  maven { url("https://packages.namiml.com/NamiSDK/Android/") }
66
+ maven { url 'https://jitpack.io' }
63
67
  maven {
64
68
  // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
65
69
  url("$rootDir/../node_modules/react-native/android")
@@ -76,7 +80,8 @@ dependencies {
76
80
  implementation fileTree(dir: 'libs', include: ['*.jar'])
77
81
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
78
82
 
79
- implementation "com.namiml:sdk-android:2.0.2"
83
+ implementation 'com.github.jeziellago:compose-markdown:0.3.0'
84
+ implementation "com.namiml:sdk-android:3.0.8.2"
80
85
 
81
86
  implementation 'com.facebook.react:react-native:+' // From node_modules
82
87
  }
@@ -104,13 +109,19 @@ def configureReactNativePom(def pom) {
104
109
  }
105
110
  }
106
111
  }
112
+
113
+ configurations {
114
+ customConfig.extendsFrom implementation
115
+ }
116
+
107
117
  afterEvaluate { project ->
108
118
  // some Gradle build hooks ref:
109
119
  // https://www.oreilly.com/library/view/gradle-beyond-the/9781449373801/ch03.html
110
120
  task androidJavadoc(type: Javadoc) {
111
121
  source = android.sourceSets.main.java.srcDirs
112
122
  classpath += files(android.bootClasspath)
113
- classpath += files(project.getConfigurations().getByName('compile').asList())
123
+ // classpath += files(project.getConfigurations().getByName('compile').asList())
124
+ // classpath += files(project.getConfigurations().getByName('customConfig').asList())
114
125
  include '**/*.java'
115
126
  }
116
127
  task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) {
@@ -135,10 +146,10 @@ afterEvaluate { project ->
135
146
  }
136
147
  task installArchives(type: Upload) {
137
148
  configuration = configurations.archives
138
- repositories.mavenDeployer {
139
- // Deploy to react-native-event-bridge/maven, ready to publish to npm
140
- repository url: "file://${projectDir}/../android/maven"
141
- configureReactNativePom pom
142
- }
149
+ // repositories.mavenDeployer {
150
+ // // Deploy to react-native-event-bridge/maven, ready to publish to npm
151
+ // repository url: "file://${projectDir}/../android/maven"
152
+ // configureReactNativePom pom
153
+ // }
143
154
  }
144
155
  }
@@ -1,6 +1,10 @@
1
1
  #Wed May 26 17:12:26 EDT 2021
2
2
  distributionBase=GRADLE_USER_HOME
3
- distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
3
+ distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
4
4
  distributionPath=wrapper/dists
5
5
  zipStorePath=wrapper/dists
6
6
  zipStoreBase=GRADLE_USER_HOME
7
+ org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=4096m -XX:+HeapDumpOnOutOfMemoryError
8
+ org.gradle.daemon=true
9
+ org.gradle.parallel=true
10
+ org.gradle.configureondemand=true
@@ -14,7 +14,6 @@ import com.facebook.react.bridge.WritableArray
14
14
  import com.facebook.react.bridge.WritableNativeArray
15
15
  import com.namiml.Nami
16
16
  import com.namiml.NamiConfiguration
17
- import com.namiml.NamiExternalIdentifierType
18
17
  import com.namiml.NamiLanguageCode
19
18
  import com.namiml.NamiLogLevel
20
19
  //import com.namiml.NamiApiResponseHandler
@@ -23,7 +22,7 @@ class NamiBridgeModule(reactContext: ReactApplicationContext) :
23
22
  ReactContextBaseJavaModule(reactContext) {
24
23
 
25
24
  companion object {
26
- private const val CONFIG_MAP_PLATFORM_ID_KEY = "appPlatformID-google"
25
+ private const val CONFIG_MAP_PLATFORM_ID_KEY = "appPlatformID-android"
27
26
  private const val CONFIG_MAP_LOG_LEVEL_KEY = "logLevel"
28
27
  private const val CONFIG_MAP_DEVELOPMENT_MODE_KEY = "developmentMode"
29
28
  private const val CONFIG_MAP_BYPASS_STORE_KEY = "bypassStore"
@@ -37,7 +36,7 @@ class NamiBridgeModule(reactContext: ReactApplicationContext) :
37
36
  }
38
37
 
39
38
  @ReactMethod
40
- fun configure(configDict: ReadableMap) {
39
+ fun configure(configDict: ReadableMap, completion: Callback) {
41
40
 
42
41
  // Need to be sure we have some valid string.
43
42
  val appPlatformID: String = if (configDict.hasKey(CONFIG_MAP_PLATFORM_ID_KEY)) {
@@ -128,7 +127,7 @@ class NamiBridgeModule(reactContext: ReactApplicationContext) :
128
127
  } else {
129
128
  Arguments.createArray()
130
129
  }
131
- val settingsList = mutableListOf("extendedClientInfo:react-native:2.0.5")
130
+ val settingsList = mutableListOf("extendedClientInfo:react-native:3.0.0")
132
131
  namiCommandsReact?.toArrayList()?.filterIsInstance<String>()?.let { commandsFromReact ->
133
132
  settingsList.addAll(commandsFromReact)
134
133
  }
@@ -141,52 +140,9 @@ class NamiBridgeModule(reactContext: ReactApplicationContext) :
141
140
  reactApplicationContext.runOnUiQueueThread {
142
141
  // Configure must be called on main thread
143
142
  Nami.configure(builtConfig)
144
- }
145
- }
146
-
147
- @ReactMethod
148
- fun setExternalIdentifier(externalIdentifier: String, externalIDType: String, completion: Callback) {
149
-
150
- Log.i(LOG_TAG, "Setting external identifier $externalIdentifier of type $externalIDType")
151
-
152
- val useType: NamiExternalIdentifierType = if (externalIDType == "sha256") {
153
- NamiExternalIdentifierType.SHA_256
154
- } else {
155
- NamiExternalIdentifierType.UUID
156
- }
157
-
158
- reactApplicationContext.runOnUiQueueThread {
159
- Nami.setExternalIdentifier(externalIdentifier, useType) { success, error ->
160
- if (error != null) {
161
- completion.invoke(error)
162
- }
163
- completion.invoke(null)
164
- }
165
- }
166
- }
167
-
168
- @ReactMethod
169
- fun getExternalIdentifier(successCallback: Callback) {
170
- reactApplicationContext.runOnUiQueueThread {
171
- val externalIdentifierResult: WritableArray = WritableNativeArray()
172
- Nami.getExternalIdentifier()?.let { externalIdentifier ->
173
- Log.i(LOG_TAG, "getting external identifier, found $externalIdentifier")
174
- externalIdentifierResult.pushString(externalIdentifier)
175
- }
176
- successCallback.invoke(externalIdentifierResult)
177
- }
178
- }
179
-
180
- @ReactMethod
181
- fun clearExternalIdentifier(completion: Callback) {
182
- Log.i(LOG_TAG, "Clearing external identifier.")
183
- reactApplicationContext.runOnUiQueueThread {
184
- Nami.clearExternalIdentifier() { success, error ->
185
- if (error != null) {
186
- completion.invoke(error)
187
- }
188
- completion.invoke(null)
189
- }
143
+ val resultMap = Arguments.createMap()
144
+ resultMap.putBoolean("success", true)
145
+ completion.invoke(resultMap)
190
146
  }
191
147
  }
192
148
  }
@@ -25,6 +25,7 @@ public class NamiBridgePackage implements ReactPackage {
25
25
  moduleList.add(new NamiEntitlementManagerBridgeModule(reactContext));
26
26
  moduleList.add(new NamiMLManagerBridgeModule(reactContext));
27
27
  moduleList.add(new NamiCustomerManagerBridgeModule(reactContext));
28
+ moduleList.add(new NamiCampaignManagerBridgeModule(reactContext));
28
29
  moduleList.add(new NamiEmitter(reactContext));
29
30
 
30
31
  return moduleList;
@@ -0,0 +1,133 @@
1
+ package com.nami.reactlibrary
2
+
3
+ import android.content.Intent
4
+ import android.util.Log
5
+ import com.facebook.react.bridge.*
6
+ import com.facebook.react.modules.core.DeviceEventManagerModule
7
+ import com.namiml.campaign.NamiCampaign
8
+ import com.namiml.campaign.NamiCampaignManager
9
+ import com.namiml.paywall.NamiSKU
10
+ import com.namiml.paywall.model.NamiPaywallAction
11
+ import android.app.Activity
12
+ import com.namiml.billing.NamiPurchase
13
+ import com.namiml.billing.NamiPurchaseState
14
+ import com.namiml.campaign.LaunchCampaignResult
15
+
16
+ class NamiCampaignManagerBridgeModule(reactContext: ReactApplicationContext) :
17
+ ReactContextBaseJavaModule(reactContext), ActivityEventListener {
18
+
19
+ override fun getName(): String {
20
+ return "RNNamiCampaignManager"
21
+ }
22
+
23
+ private fun campaignToReadableMap(campaign: NamiCampaign): ReadableMap {
24
+ val readableMap = Arguments.createMap()
25
+ readableMap.putString("segment", campaign.segment)
26
+ readableMap.putString("paywall", campaign.paywall)
27
+ readableMap.putString("value", campaign.value)
28
+ readableMap.putString("type", campaign.type.toString().lowercase())
29
+ return readableMap
30
+ }
31
+
32
+ @ReactMethod
33
+ fun launch(label: String?, resultCallback: Callback, actionCallback: Callback) {
34
+ reactApplicationContext.runOnUiQueueThread {
35
+ if (label != null) {
36
+ NamiCampaignManager.launch(currentActivity!!, label,
37
+ paywallActionCallback = { action, sku, purchaseError, purchases ->
38
+ handlePaywallCallback(action, sku, purchaseError, purchases, actionCallback)
39
+ }
40
+ ) { result -> handleResult(result, resultCallback) }
41
+ } else {
42
+ NamiCampaignManager.launch(currentActivity!!,
43
+ paywallActionCallback = { action, sku,purchaseError, purchases ->
44
+ handlePaywallCallback(action, sku, purchaseError, purchases, actionCallback)
45
+ }
46
+ ) { result -> handleResult(result, resultCallback) }
47
+ }
48
+ }
49
+ }
50
+
51
+ private fun handlePaywallCallback(action: NamiPaywallAction, sku: NamiSKU?, purchaseError: String?, purchases: List<NamiPurchase>?, actionCallback: Callback){
52
+ val actionString = action.toString()
53
+ val skuString = sku?.skuId.orEmpty()
54
+ val purchasesArray: WritableArray = WritableNativeArray()
55
+ if (purchases != null) {
56
+ for (purchase in purchases) {
57
+ purchasesArray.pushMap(purchase.toPurchaseDict())
58
+ }
59
+ }
60
+ val resultMap = Arguments.createMap()
61
+ resultMap.putString("action", actionString)
62
+ resultMap.putString("skuId", skuString)
63
+ resultMap.putString("purchaseError", purchaseError)
64
+ resultMap.putArray("purchases", purchasesArray)
65
+ reactApplicationContext
66
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
67
+ .emit("ResultCampaign", resultMap)
68
+ }
69
+
70
+ private fun handleResult(result: LaunchCampaignResult, resultCallback: Callback) {
71
+ val resultMap = Arguments.createMap()
72
+ when (result) {
73
+ is LaunchCampaignResult.Success -> {
74
+ resultCallback.invoke(true)
75
+ }
76
+ is LaunchCampaignResult.Failure -> {
77
+ resultCallback.invoke(false, "${result.error}")
78
+ }
79
+ }
80
+ }
81
+
82
+ override fun onActivityResult(
83
+ activity: Activity?,
84
+ requestCode: Int,
85
+ resultCode: Int,
86
+ intent: Intent?
87
+ ) {
88
+ Log.d(LOG_TAG, "Nami Activity result listener activated, code is $requestCode")
89
+ }
90
+
91
+ override fun onNewIntent(intent: Intent?) {
92
+ // do nothing
93
+ }
94
+
95
+ @ReactMethod
96
+ fun allCampaigns(promise: Promise){
97
+ val campaigns = NamiCampaignManager.allCampaigns()
98
+ val array = WritableNativeArray()
99
+ campaigns.forEach { campaign ->
100
+ array.pushMap(campaignToReadableMap(campaign))
101
+ }
102
+ promise.resolve(array)
103
+ }
104
+
105
+ @ReactMethod
106
+ fun isCampaignAvailable(label: String?, promise: Promise){
107
+ val isCampaignAvailable: Boolean
108
+ if (label != null) {
109
+ isCampaignAvailable = NamiCampaignManager.isCampaignAvailable(label)
110
+ } else {
111
+ isCampaignAvailable = NamiCampaignManager.isCampaignAvailable()
112
+ }
113
+ promise.resolve(isCampaignAvailable)
114
+ }
115
+
116
+ @ReactMethod
117
+ fun refresh(){
118
+ NamiCampaignManager.refresh() { }
119
+ }
120
+
121
+ @ReactMethod
122
+ fun registerAvailableCampaignsHandler() {
123
+ NamiCampaignManager.registerAvailableCampaignsHandler { availableCampaigns ->
124
+ val array = WritableNativeArray()
125
+ availableCampaigns.forEach { campaign ->
126
+ array.pushMap(campaignToReadableMap(campaign))
127
+ }
128
+ reactApplicationContext
129
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
130
+ .emit("AvailableCampaignsChanged", array)
131
+ }
132
+ }
133
+ }
@@ -1,42 +1,111 @@
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
4
+ import com.facebook.react.bridge.*
8
5
  import com.facebook.react.modules.core.DeviceEventManagerModule
6
+ import com.namiml.campaign.NamiCampaignManager
9
7
  import com.namiml.customer.CustomerJourneyState
10
8
  import com.namiml.customer.NamiCustomerManager
11
9
 
10
+
12
11
  class NamiCustomerManagerBridgeModule(reactContext: ReactApplicationContext) :
13
12
  ReactContextBaseJavaModule(reactContext) {
14
13
 
15
14
  override fun getName(): String {
16
- return "NamiCustomerManagerBridge"
15
+ return "RNNamiCustomerManager"
17
16
  }
18
17
 
19
- init {
20
- NamiCustomerManager.registerCustomerJourneyChangedListener { customerJourneyState ->
21
- emitCustomerJourneyChanged(customerJourneyState)
22
- }
18
+ private fun journeyStateToReadableMap(journeyState: CustomerJourneyState): ReadableMap {
19
+ val readableMap = Arguments.createMap()
20
+ readableMap.putBoolean("formerSubscriber", journeyState.formerSubscriber)
21
+ readableMap.putBoolean("inGracePeriodl", journeyState.inGracePeriod)
22
+ readableMap.putBoolean("inTrialPeriod", journeyState.inTrialPeriod)
23
+ readableMap.putBoolean("inIntroOfferPeriod", journeyState.inIntroOfferPeriod)
24
+ readableMap.putBoolean("isCancelled", journeyState.isCancelled)
25
+ readableMap.putBoolean("inPause", journeyState.inPause)
26
+ readableMap.putBoolean("inAccountHold", journeyState.inAccountHold)
27
+ return readableMap
28
+ }
29
+ @ReactMethod
30
+ fun setCustomerAttribute(key: String, value: String){
31
+ NamiCustomerManager.setCustomerAttribute(key, value)
32
+ }
33
+
34
+ @ReactMethod
35
+ fun getCustomerAttribute(key: String, promise: Promise){
36
+ val customerAttribute = NamiCustomerManager.getCustomerAttribute(key)
37
+ promise.resolve(customerAttribute)
38
+ }
39
+
40
+ @ReactMethod
41
+ fun clearCustomerAttribute(key: String){
42
+ NamiCustomerManager.clearCustomerAttribute(key)
43
+ }
44
+
45
+ @ReactMethod
46
+ fun clearAllCustomerAttributes(){
47
+ NamiCustomerManager.clearAllCustomerAttributes()
48
+ }
49
+
50
+ @ReactMethod
51
+ fun journeyState(promise: Promise){
52
+ val journeyState = NamiCustomerManager.journeyState()
53
+ if (journeyState != null) {
54
+ val handledJourneyState = journeyStateToReadableMap(journeyState)
55
+ promise.resolve(handledJourneyState)
56
+ } else {
57
+ promise.resolve(null)
58
+ }
59
+ }
60
+
61
+ @ReactMethod
62
+ fun isLoggedIn(promise: Promise){
63
+ val isLoggedIn = NamiCustomerManager.isLoggedIn()
64
+ promise.resolve(isLoggedIn)
65
+ }
66
+
67
+ @ReactMethod
68
+ fun loggedInId(promise: Promise){
69
+ val id = NamiCustomerManager.loggedInId()
70
+ promise.resolve(id)
71
+ }
72
+
73
+ @ReactMethod
74
+ fun deviceId(promise: Promise){
75
+ val id = NamiCustomerManager.deviceId()
76
+ promise.resolve(id)
23
77
  }
24
78
 
25
- private fun emitCustomerJourneyChanged(customerJourneyState: CustomerJourneyState) {
26
- Log.i(LOG_TAG, "Emitting CustomerJourneyState changed")
27
- try {
79
+ @ReactMethod
80
+ fun login(customerId: String){
81
+ NamiCustomerManager.login(customerId)
82
+ }
83
+
84
+ @ReactMethod
85
+ fun logout() {
86
+ NamiCustomerManager.logout()
87
+ }
88
+
89
+ @ReactMethod
90
+ fun registerJourneyStateHandler() {
91
+ NamiCustomerManager.registerJourneyStateHandler { journeyState ->
92
+ val handledJourneyState = journeyStateToReadableMap(journeyState)
28
93
  reactApplicationContext
29
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
30
- .emit("CustomerJourneyStateChanged", customerJourneyState.toDict())
31
- } catch (e: Exception) {
32
- Log.e(LOG_TAG, "Caught Exception: " + e.message)
94
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
95
+ .emit("JourneyStateChanged", handledJourneyState)
33
96
  }
34
97
  }
35
98
 
36
99
  @ReactMethod
37
- fun currentCustomerJourneyState(resultsCallback: Callback) {
38
- reactApplicationContext.runOnUiQueueThread {
39
- resultsCallback.invoke(NamiCustomerManager.currentCustomerJourneyState().toDict())
100
+ fun registerAccountStateHandler() {
101
+ NamiCustomerManager.registerAccountStateHandler { action, success, error ->
102
+ val body = Arguments.createMap()
103
+ body.putString("action", action.toString())
104
+ body.putBoolean("success", success)
105
+ body.putString("error", error.toString())
106
+ reactApplicationContext
107
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
108
+ .emit("AccountStateChanged", body)
40
109
  }
41
110
  }
42
111
  }