react-native-sdk-pianoio 0.3.2 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -212
- package/android/build.gradle +29 -42
- package/android/gradle.properties +33 -14
- package/android/src/main/java/com/sdkpianoio/ComposerPianoImpl.kt +366 -0
- package/android/src/main/java/com/sdkpianoio/SdkPianoioModule.kt +281 -507
- package/android/src/main/java/com/sdkpianoio/TokenService.kt +139 -0
- package/android/test.sh +494 -0
- package/ios/ComposerPianoImpl.swift +128 -225
- package/ios/MyComposerDelegate.swift +142 -109
- package/ios/SdkPianoio.swift +69 -143
- package/ios/SdkPianoioBridge.m +18 -46
- package/ios/TokenService.swift +219 -0
- package/lib/commonjs/NativeSdkPianoio.ts +34 -10
- package/lib/commonjs/PianoComposer.js +69 -51
- package/lib/commonjs/PianoComposer.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/NativeSdkPianoio.ts +34 -10
- package/lib/module/PianoComposer.js +70 -51
- package/lib/module/PianoComposer.js.map +1 -1
- package/lib/module/index.js +0 -14
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/NativeSdkPianoio.d.ts +27 -9
- package/lib/typescript/commonjs/src/NativeSdkPianoio.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/PianoComposer.d.ts +45 -18
- package/lib/typescript/commonjs/src/PianoComposer.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/NativeSdkPianoio.d.ts +27 -9
- package/lib/typescript/module/src/NativeSdkPianoio.d.ts.map +1 -1
- package/lib/typescript/module/src/PianoComposer.d.ts +45 -18
- package/lib/typescript/module/src/PianoComposer.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +4 -1
- package/src/NativeSdkPianoio.ts +34 -10
- package/src/PianoComposer.tsx +76 -59
- package/src/index.tsx +0 -14
- package/android/src/main/AndroidManifestNew.xml +0 -2
- package/ios/services/TokenService.swift +0 -70
@@ -1,559 +1,333 @@
|
|
1
1
|
package com.sdkpianoio
|
2
2
|
|
3
|
-
import androidx.
|
3
|
+
import androidx.activity.ComponentActivity
|
4
|
+
import androidx.activity.result.ActivityResultLauncher
|
5
|
+
import com.facebook.react.bridge.Arguments
|
6
|
+
import com.facebook.react.bridge.Promise
|
4
7
|
import com.facebook.react.bridge.ReactApplicationContext
|
5
8
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
6
9
|
import com.facebook.react.bridge.ReactMethod
|
7
|
-
import com.facebook.react.bridge.Promise
|
8
10
|
import com.facebook.react.bridge.ReadableArray
|
11
|
+
import com.facebook.react.bridge.ReadableMap
|
12
|
+
import com.facebook.react.bridge.WritableMap
|
9
13
|
import com.facebook.react.module.annotations.ReactModule
|
10
|
-
|
11
|
-
import io.piano.android.
|
12
|
-
import io.piano.android.
|
13
|
-
import io.piano.android.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
// importa altri listener se ti servono
|
22
|
-
|
14
|
+
import io.piano.android.id.PianoIdAuthResultContract
|
15
|
+
import io.piano.android.id.PianoIdClient
|
16
|
+
import io.piano.android.id.models.PianoIdAuthFailureResult
|
17
|
+
import io.piano.android.id.models.PianoIdAuthSuccessResult
|
18
|
+
|
19
|
+
/**
|
20
|
+
* SdkPianoioModule - React Native module for the Piano.io SDK
|
21
|
+
*
|
22
|
+
* This module serves as the bridge between JavaScript and the native Android implementation.
|
23
|
+
*/
|
23
24
|
@ReactModule(name = SdkPianoioModule.NAME)
|
24
|
-
class SdkPianoioModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
25
|
+
class SdkPianoioModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
26
|
+
|
27
|
+
private var composerImpl: ComposerPianoImpl? = null
|
28
|
+
private var isInitialized: Boolean = false
|
29
|
+
private var signInPromise: Promise? = null
|
30
|
+
|
31
|
+
private lateinit var authResultLauncher: ActivityResultLauncher<PianoIdClient.SignInContext>
|
32
|
+
|
33
|
+
init {
|
34
|
+
// The ActivityResultLauncher must be registered in the init block or onCreate.
|
35
|
+
// We need to ensure we have a ComponentActivity to access the registry.
|
36
|
+
val activity = reactContext.currentActivity
|
37
|
+
if (activity is ComponentActivity) {
|
38
|
+
authResultLauncher = activity.activityResultRegistry.register(
|
39
|
+
"piano-id-login",
|
40
|
+
PianoIdAuthResultContract()
|
41
|
+
) { result ->
|
42
|
+
val promise = signInPromise
|
43
|
+
signInPromise = null // Clean up promise immediately
|
44
|
+
when (result) {
|
45
|
+
is PianoIdAuthSuccessResult -> {
|
46
|
+
val token = result.token
|
47
|
+
composerImpl?.tokenService?.setToken(token)
|
48
|
+
val user = composerImpl?.tokenService?.getCurrentUser()
|
49
|
+
if (user != null) {
|
50
|
+
val resultMap = Arguments.createMap().apply {
|
51
|
+
putBoolean("success", true)
|
52
|
+
putString("userId", user.id)
|
53
|
+
putString("userEmail", user.email)
|
54
|
+
putString("accessToken", user.accessToken)
|
55
|
+
}
|
56
|
+
promise?.resolve(resultMap)
|
57
|
+
} else {
|
58
|
+
promise?.reject("SIGNIN_ERROR", "Failed to construct user after login.")
|
59
|
+
}
|
60
|
+
}
|
61
|
+
is PianoIdAuthFailureResult -> {
|
62
|
+
val exception = result.exception
|
63
|
+
promise?.reject("SIGNIN_ERROR", exception.message, exception)
|
64
|
+
}
|
65
|
+
null -> {
|
66
|
+
// This handles the case where the user cancels the flow
|
67
|
+
promise?.reject("CANCELLED", "User cancelled the sign-in process.")
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
} else {
|
72
|
+
// This is a fallback, though in a normal RN app, currentActivity should be a ComponentActivity.
|
73
|
+
// You might want to log a warning here.
|
74
|
+
}
|
47
75
|
}
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
private val tags = mutableListOf<String>()
|
52
|
-
private var zoneId: String? = null
|
53
|
-
private var referrer: String? = null
|
54
|
-
private val customVariables = mutableMapOf<String, String>()
|
55
|
-
private var userToken: String? = null
|
56
|
-
private var url: String? = null
|
57
|
-
|
58
|
-
@ReactMethod
|
59
|
-
fun addComposerTag(tag: String, promise: Promise) {
|
60
|
-
try {
|
61
|
-
if (!tags.contains(tag)) {
|
62
|
-
tags.add(tag)
|
63
|
-
}
|
64
|
-
promise.resolve(null)
|
65
|
-
} catch (e: Exception) {
|
66
|
-
promise.reject("TAG_ERROR", "Errore aggiunta tag", e)
|
76
|
+
|
77
|
+
override fun getName(): String {
|
78
|
+
return NAME
|
67
79
|
}
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
|
81
|
+
@ReactMethod
|
82
|
+
fun initialize(aid: String, promise: Promise) {
|
83
|
+
try {
|
84
|
+
if (isInitialized) {
|
85
|
+
promise.resolve(true)
|
86
|
+
return
|
87
|
+
}
|
88
|
+
composerImpl = ComposerPianoImpl()
|
89
|
+
composerImpl?.initializeComposer(reactContext, aid)
|
90
|
+
isInitialized = true
|
91
|
+
promise.resolve(true)
|
92
|
+
} catch (e: Exception) {
|
93
|
+
promise.reject("INIT_ERROR", "Failed to initialize Piano SDK", e)
|
77
94
|
}
|
78
|
-
}
|
79
|
-
promise.resolve(null)
|
80
|
-
} catch (e: Exception) {
|
81
|
-
promise.reject("TAGS_ERROR", "Errore aggiunta tags", e)
|
82
95
|
}
|
83
|
-
}
|
84
96
|
|
85
|
-
|
86
|
-
fun setComposerZoneId(zoneId: String, promise: Promise) {
|
87
|
-
try {
|
88
|
-
this.zoneId = zoneId
|
89
|
-
promise.resolve(null)
|
90
|
-
} catch (e: Exception) {
|
91
|
-
promise.reject("ZONEID_ERROR", "Errore impostazione zoneId", e)
|
92
|
-
}
|
93
|
-
}
|
97
|
+
// MARK: - Composer Configuration Methods
|
94
98
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
@ReactMethod
|
100
|
+
fun addTag(tag: String, promise: Promise) {
|
101
|
+
try {
|
102
|
+
if (!validateInitialization(promise) || !validateParameter(tag, "tag", promise)) return
|
103
|
+
composerImpl?.addTag(tag)
|
104
|
+
promise.resolve(true)
|
105
|
+
} catch (e: Exception) {
|
106
|
+
promise.reject("ADD_TAG_ERROR", "Error adding tag", e)
|
107
|
+
}
|
102
108
|
}
|
103
|
-
}
|
104
109
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
110
|
+
@ReactMethod
|
111
|
+
fun addTags(tagsArray: ReadableArray, promise: Promise) {
|
112
|
+
try {
|
113
|
+
if (!validateInitialization(promise) || !validateArray(tagsArray, "tagsArray", promise)) return
|
114
|
+
val tags = tagsArray.toArrayList().mapNotNull { it?.toString() }
|
115
|
+
composerImpl?.addTags(tags)
|
116
|
+
promise.resolve(true)
|
117
|
+
} catch (e: Exception) {
|
118
|
+
promise.reject("ADD_TAGS_ERROR", "Error adding tags", e)
|
119
|
+
}
|
112
120
|
}
|
113
|
-
}
|
114
121
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
+
@ReactMethod
|
123
|
+
fun setZoneId(zoneId: String, promise: Promise) {
|
124
|
+
try {
|
125
|
+
if (!validateInitialization(promise)) return
|
126
|
+
composerImpl?.setZoneId(zoneId)
|
127
|
+
promise.resolve(true)
|
128
|
+
} catch (e: Exception) {
|
129
|
+
promise.reject("SET_ZONEID_ERROR", "Error setting Zone ID", e)
|
130
|
+
}
|
122
131
|
}
|
123
|
-
}
|
124
132
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
133
|
+
@ReactMethod
|
134
|
+
fun setReferrer(referrer: String, promise: Promise) {
|
135
|
+
try {
|
136
|
+
if (!validateInitialization(promise)) return
|
137
|
+
composerImpl?.setReferrer(referrer)
|
138
|
+
promise.resolve(true)
|
139
|
+
} catch (e: Exception) {
|
140
|
+
promise.reject("SET_REFERRER_ERROR", "Error setting referrer", e)
|
141
|
+
}
|
132
142
|
}
|
133
|
-
}
|
134
143
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
144
|
+
@ReactMethod
|
145
|
+
fun setUrl(url: String, promise: Promise) {
|
146
|
+
try {
|
147
|
+
if (!validateInitialization(promise)) return
|
148
|
+
composerImpl?.setUrl(url)
|
149
|
+
promise.resolve(true)
|
150
|
+
} catch (e: Exception) {
|
151
|
+
promise.reject("SET_URL_ERROR", "Error setting URL", e)
|
152
|
+
}
|
143
153
|
}
|
144
|
-
}
|
145
|
-
|
146
|
-
// Replace your old executeExperience method with this one.
|
147
154
|
|
148
|
-
@ReactMethod
|
149
|
-
fun
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
+
@ReactMethod
|
156
|
+
fun setUserToken(token: String, promise: Promise) {
|
157
|
+
try {
|
158
|
+
if (!validateInitialization(promise)) return
|
159
|
+
composerImpl?.setUserToken(token)
|
160
|
+
promise.resolve(true)
|
161
|
+
} catch (e: Exception) {
|
162
|
+
promise.reject("SET_TOKEN_ERROR", "Error setting user token", e)
|
163
|
+
}
|
155
164
|
}
|
156
165
|
|
157
|
-
|
158
|
-
|
159
|
-
val request = ExperienceRequest.Builder()
|
160
|
-
.debug(true)
|
161
|
-
.tags(tags)
|
162
|
-
.zone(zoneId)
|
163
|
-
.referer(referrer)
|
164
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
165
|
-
.url(url)
|
166
|
-
.userToken(userToken)
|
167
|
-
.build()
|
168
|
-
|
169
|
-
// 3. Create a listener to handle the asynchronous response from the Piano SDK.
|
170
|
-
val listener = ExecuteExperienceListener { events ->
|
171
|
-
// This code runs when the SDK gets a successful response.
|
166
|
+
@ReactMethod
|
167
|
+
fun addCustomVariable(key: String, value: String, promise: Promise) {
|
172
168
|
try {
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
for (event in events) {
|
178
|
-
val eventMap = Arguments.createMap()
|
179
|
-
eventMap.putString("eventType", event.eventType)
|
180
|
-
eventMap.putString("experienceId", event.experienceId)
|
181
|
-
// Add any other event data you need to this map.
|
182
|
-
// For example, for a 'showTemplate' event:
|
183
|
-
// if (event.eventData is ShowTemplateEventParams) {
|
184
|
-
// eventMap.putString("templateUrl", (event.eventData as ShowTemplateEventParams).templateUrl)
|
185
|
-
// }
|
186
|
-
eventsArray.pushMap(eventMap)
|
187
|
-
}
|
188
|
-
|
189
|
-
// 4. Resolve the promise with the array of events.
|
190
|
-
promise.resolve(eventsArray)
|
191
|
-
|
169
|
+
if (!validateInitialization(promise)) return
|
170
|
+
composerImpl?.addCustomVariable(key, value)
|
171
|
+
promise.resolve(true)
|
192
172
|
} catch (e: Exception) {
|
193
|
-
promise.reject("
|
173
|
+
promise.reject("ADD_CUSTOMVAR_ERROR", "Error adding custom variable", e)
|
194
174
|
}
|
195
175
|
}
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
176
|
+
|
177
|
+
@ReactMethod
|
178
|
+
fun setCustomVariables(variables: ReadableMap, promise: Promise) {
|
179
|
+
try {
|
180
|
+
if (!validateInitialization(promise) || !validateMap(variables, "variables", promise)) return
|
181
|
+
val map = mutableMapOf<String, String>()
|
182
|
+
val iterator = variables.keySetIterator()
|
183
|
+
while (iterator.hasNextKey()) {
|
184
|
+
val key = iterator.nextKey()
|
185
|
+
val value = variables.getString(key)
|
186
|
+
if (value != null && value.isNotBlank()) {
|
187
|
+
map[key] = value
|
188
|
+
}
|
189
|
+
}
|
190
|
+
if (map.isEmpty()) {
|
191
|
+
promise.reject("INVALID_PARAMETER", "No valid variables found in the map")
|
192
|
+
return
|
193
|
+
}
|
194
|
+
composerImpl?.setCustomVariables(map)
|
195
|
+
promise.resolve(true)
|
196
|
+
} catch (e: Exception) {
|
197
|
+
promise.reject("SET_CUSTOMVARS_ERROR", "Error setting custom variables", e)
|
198
|
+
}
|
200
199
|
}
|
201
200
|
|
202
|
-
//
|
203
|
-
composer.getExperience(request, listener, errorListener)
|
204
|
-
}
|
205
|
-
|
206
|
-
@ReactMethod
|
207
|
-
fun executeComposer(promise: Promise) {
|
208
|
-
try {
|
209
|
-
val composer = Composer.getInstance()
|
210
|
-
if (composer == null) {
|
211
|
-
promise.reject("NOT_INITIALIZED", "Piano Composer is not initialized.")
|
212
|
-
return
|
213
|
-
}
|
214
|
-
|
215
|
-
// Execute the composer with current state
|
216
|
-
val request = ExperienceRequest.Builder()
|
217
|
-
.debug(true)
|
218
|
-
.tags(tags)
|
219
|
-
.zone(zoneId)
|
220
|
-
.referer(referrer)
|
221
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
222
|
-
.url(url)
|
223
|
-
.userToken(userToken)
|
224
|
-
.build()
|
225
|
-
|
226
|
-
val listener = ExecuteExperienceListener { events ->
|
227
|
-
promise.resolve(true)
|
228
|
-
}
|
201
|
+
// MARK: - Execution Method
|
229
202
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
203
|
+
@ReactMethod
|
204
|
+
fun executeExperience(promise: Promise) {
|
205
|
+
try {
|
206
|
+
if (!validateInitialization(promise)) return
|
207
|
+
composerImpl?.executeComposer(promise)
|
208
|
+
} catch (e: Exception) {
|
209
|
+
promise.reject("EXECUTION_ERROR", "Error executing experience", e)
|
210
|
+
}
|
237
211
|
}
|
238
|
-
}
|
239
212
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
213
|
+
// MARK: - Authentication Methods
|
214
|
+
|
215
|
+
@ReactMethod
|
216
|
+
fun signIn(promise: Promise) {
|
217
|
+
if (signInPromise != null) {
|
218
|
+
promise.reject("IN_PROGRESS", "Another sign-in operation is already in progress.")
|
219
|
+
return
|
220
|
+
}
|
221
|
+
try {
|
222
|
+
if (!validateInitialization(promise)) return
|
223
|
+
this.signInPromise = promise
|
224
|
+
composerImpl?.tokenService?.signIn(authResultLauncher)
|
225
|
+
} catch (e: Exception) {
|
226
|
+
promise.reject("SIGNIN_ERROR", "Error during sign in", e)
|
227
|
+
this.signInPromise = null
|
228
|
+
}
|
256
229
|
}
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
.referer(referrer)
|
273
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
274
|
-
.url(url)
|
275
|
-
.userToken(userToken)
|
276
|
-
.build()
|
277
|
-
|
278
|
-
val listener = ExecuteExperienceListener { events ->
|
279
|
-
promise.resolve(true)
|
280
|
-
}
|
281
|
-
|
282
|
-
val errorListener = Consumer<Exception> { e ->
|
283
|
-
promise.reject("TEMPLATE_ERROR", "Error showing template", e)
|
284
|
-
}
|
285
|
-
|
286
|
-
composer.getExperience(request, listener, errorListener)
|
287
|
-
} catch (e: Exception) {
|
288
|
-
promise.reject("TEMPLATE_ERROR", "Error showing template", e)
|
230
|
+
|
231
|
+
@ReactMethod
|
232
|
+
fun signOut(promise: Promise) {
|
233
|
+
try {
|
234
|
+
if (!validateInitialization(promise)) return
|
235
|
+
composerImpl?.tokenService?.signOut { success ->
|
236
|
+
if (success) {
|
237
|
+
promise.resolve(Arguments.createMap().apply { putBoolean("success", true) })
|
238
|
+
} else {
|
239
|
+
promise.reject("SIGNOUT_ERROR", "Sign out failed")
|
240
|
+
}
|
241
|
+
}
|
242
|
+
} catch (e: Exception) {
|
243
|
+
promise.reject("SIGNOUT_ERROR", "Error during sign out", e)
|
244
|
+
}
|
289
245
|
}
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
val errorListener = Consumer<Exception> { e ->
|
316
|
-
promise.reject("FORM_ERROR", "Error showing form", e)
|
317
|
-
}
|
318
|
-
|
319
|
-
composer.getExperience(request, listener, errorListener)
|
320
|
-
} catch (e: Exception) {
|
321
|
-
promise.reject("FORM_ERROR", "Error showing form", e)
|
246
|
+
|
247
|
+
@ReactMethod
|
248
|
+
fun getCurrentUser(promise: Promise) {
|
249
|
+
try {
|
250
|
+
if (!validateInitialization(promise)) return
|
251
|
+
val user = composerImpl?.tokenService?.getCurrentUser()
|
252
|
+
if (user != null) {
|
253
|
+
val result = Arguments.createMap().apply {
|
254
|
+
putBoolean("success", true)
|
255
|
+
putString("userId", user.id)
|
256
|
+
putString("userEmail", user.email)
|
257
|
+
putString("accessToken", user.accessToken)
|
258
|
+
putBoolean("authenticated", true)
|
259
|
+
}
|
260
|
+
promise.resolve(result)
|
261
|
+
} else {
|
262
|
+
val result = Arguments.createMap().apply {
|
263
|
+
putBoolean("success", true)
|
264
|
+
putBoolean("authenticated", false)
|
265
|
+
}
|
266
|
+
promise.resolve(result)
|
267
|
+
}
|
268
|
+
} catch (e: Exception) {
|
269
|
+
promise.reject("USER_ERROR", "Error getting current user", e)
|
270
|
+
}
|
322
271
|
}
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
val request = ExperienceRequest.Builder()
|
335
|
-
.debug(true)
|
336
|
-
.tags(tags)
|
337
|
-
.zone(zoneId)
|
338
|
-
.referer(referrer)
|
339
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
340
|
-
.url(url)
|
341
|
-
.userToken(userToken)
|
342
|
-
.build()
|
343
|
-
|
344
|
-
val listener = ExecuteExperienceListener { events ->
|
345
|
-
promise.resolve(true)
|
346
|
-
}
|
347
|
-
|
348
|
-
val errorListener = Consumer<Exception> { e ->
|
349
|
-
promise.reject("RECOMMENDATIONS_ERROR", "Error showing recommendations", e)
|
350
|
-
}
|
351
|
-
|
352
|
-
composer.getExperience(request, listener, errorListener)
|
353
|
-
} catch (e: Exception) {
|
354
|
-
promise.reject("RECOMMENDATIONS_ERROR", "Error showing recommendations", e)
|
272
|
+
|
273
|
+
@ReactMethod
|
274
|
+
fun isAuthenticated(promise: Promise) {
|
275
|
+
try {
|
276
|
+
if (!validateInitialization(promise)) return
|
277
|
+
val isAuth = composerImpl?.tokenService?.isAuthenticated() ?: false
|
278
|
+
promise.resolve(Arguments.createMap().apply { putBoolean("authenticated", isAuth) })
|
279
|
+
} catch (e: Exception) {
|
280
|
+
promise.reject("AUTH_ERROR", "Error checking authentication", e)
|
281
|
+
}
|
355
282
|
}
|
356
|
-
}
|
357
|
-
|
358
|
-
@ReactMethod
|
359
|
-
fun nonSite(promise: Promise) {
|
360
|
-
try {
|
361
|
-
val composer = Composer.getInstance()
|
362
|
-
if (composer == null) {
|
363
|
-
promise.reject("NOT_INITIALIZED", "Piano Composer is not initialized.")
|
364
|
-
return
|
365
|
-
}
|
366
|
-
|
367
|
-
val request = ExperienceRequest.Builder()
|
368
|
-
.debug(true)
|
369
|
-
.tags(tags)
|
370
|
-
.zone(zoneId)
|
371
|
-
.referer(referrer)
|
372
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
373
|
-
.url(url)
|
374
|
-
.userToken(userToken)
|
375
|
-
.build()
|
376
283
|
|
377
|
-
|
378
|
-
promise.resolve(true)
|
379
|
-
}
|
284
|
+
// MARK: - Helper and Cleanup Methods
|
380
285
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
286
|
+
@ReactMethod
|
287
|
+
fun clearConfiguration(promise: Promise) {
|
288
|
+
try {
|
289
|
+
if (!validateInitialization(promise)) return
|
290
|
+
composerImpl?.clearTags()
|
291
|
+
composerImpl?.clearCustomVariables()
|
292
|
+
promise.resolve(true)
|
293
|
+
} catch (e: Exception) {
|
294
|
+
promise.reject("CLEAR_ERROR", "Error clearing configurations", e)
|
295
|
+
}
|
388
296
|
}
|
389
|
-
}
|
390
|
-
|
391
|
-
@ReactMethod
|
392
|
-
fun userSegmentTrue(promise: Promise) {
|
393
|
-
try {
|
394
|
-
val composer = Composer.getInstance()
|
395
|
-
if (composer == null) {
|
396
|
-
promise.reject("NOT_INITIALIZED", "Piano Composer is not initialized.")
|
397
|
-
return
|
398
|
-
}
|
399
|
-
|
400
|
-
val request = ExperienceRequest.Builder()
|
401
|
-
.debug(true)
|
402
|
-
.tags(tags)
|
403
|
-
.zone(zoneId)
|
404
|
-
.referer(referrer)
|
405
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
406
|
-
.url(url)
|
407
|
-
.userToken(userToken)
|
408
|
-
.build()
|
409
|
-
|
410
|
-
val listener = ExecuteExperienceListener { events ->
|
411
|
-
promise.resolve(true)
|
412
|
-
}
|
413
|
-
|
414
|
-
val errorListener = Consumer<Exception> { e ->
|
415
|
-
promise.reject("USERSEGMENT_ERROR", "Error executing userSegmentTrue", e)
|
416
|
-
}
|
417
297
|
|
418
|
-
|
419
|
-
|
420
|
-
|
298
|
+
private fun validateInitialization(promise: Promise): Boolean {
|
299
|
+
if (!isInitialized || composerImpl == null) {
|
300
|
+
promise.reject("NOT_INITIALIZED", "Piano SDK not initialized. Call initialize() first.")
|
301
|
+
return false
|
302
|
+
}
|
303
|
+
return true
|
421
304
|
}
|
422
|
-
}
|
423
|
-
|
424
|
-
@ReactMethod
|
425
|
-
fun userSegmentFalse(promise: Promise) {
|
426
|
-
try {
|
427
|
-
val composer = Composer.getInstance()
|
428
|
-
if (composer == null) {
|
429
|
-
promise.reject("NOT_INITIALIZED", "Piano Composer is not initialized.")
|
430
|
-
return
|
431
|
-
}
|
432
|
-
|
433
|
-
val request = ExperienceRequest.Builder()
|
434
|
-
.debug(true)
|
435
|
-
.tags(tags)
|
436
|
-
.zone(zoneId)
|
437
|
-
.referer(referrer)
|
438
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
439
|
-
.url(url)
|
440
|
-
.userToken(userToken)
|
441
|
-
.build()
|
442
|
-
|
443
|
-
val listener = ExecuteExperienceListener { events ->
|
444
|
-
promise.resolve(true)
|
445
|
-
}
|
446
305
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
promise.reject("USERSEGMENT_ERROR", "Error executing userSegmentFalse", e)
|
306
|
+
private fun validateParameter(value: String?, paramName: String, promise: Promise): Boolean {
|
307
|
+
if (value.isNullOrBlank()) {
|
308
|
+
promise.reject("INVALID_PARAMETER", "Parameter '$paramName' cannot be empty")
|
309
|
+
return false
|
310
|
+
}
|
311
|
+
return true
|
454
312
|
}
|
455
|
-
}
|
456
|
-
|
457
|
-
@ReactMethod
|
458
|
-
fun meterActive(promise: Promise) {
|
459
|
-
try {
|
460
|
-
val composer = Composer.getInstance()
|
461
|
-
if (composer == null) {
|
462
|
-
promise.reject("NOT_INITIALIZED", "Piano Composer is not initialized.")
|
463
|
-
return
|
464
|
-
}
|
465
313
|
|
466
|
-
|
467
|
-
.
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
.url(url)
|
473
|
-
.userToken(userToken)
|
474
|
-
.build()
|
475
|
-
|
476
|
-
val listener = ExecuteExperienceListener { events ->
|
477
|
-
promise.resolve(true)
|
478
|
-
}
|
479
|
-
|
480
|
-
val errorListener = Consumer<Exception> { e ->
|
481
|
-
promise.reject("METER_ERROR", "Error executing meterActive", e)
|
482
|
-
}
|
483
|
-
|
484
|
-
composer.getExperience(request, listener, errorListener)
|
485
|
-
} catch (e: Exception) {
|
486
|
-
promise.reject("METER_ERROR", "Error executing meterActive", e)
|
314
|
+
private fun validateArray(array: ReadableArray?, paramName: String, promise: Promise): Boolean {
|
315
|
+
if (array == null || array.size() == 0) {
|
316
|
+
promise.reject("INVALID_PARAMETER", "Array '$paramName' cannot be empty")
|
317
|
+
return false
|
318
|
+
}
|
319
|
+
return true
|
487
320
|
}
|
488
|
-
}
|
489
|
-
|
490
|
-
@ReactMethod
|
491
|
-
fun meterExpired(promise: Promise) {
|
492
|
-
try {
|
493
|
-
val composer = Composer.getInstance()
|
494
|
-
if (composer == null) {
|
495
|
-
promise.reject("NOT_INITIALIZED", "Piano Composer is not initialized.")
|
496
|
-
return
|
497
|
-
}
|
498
|
-
|
499
|
-
val request = ExperienceRequest.Builder()
|
500
|
-
.debug(true)
|
501
|
-
.tags(tags)
|
502
|
-
.zone(zoneId)
|
503
|
-
.referer(referrer)
|
504
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
505
|
-
.url(url)
|
506
|
-
.userToken(userToken)
|
507
|
-
.build()
|
508
|
-
|
509
|
-
val listener = ExecuteExperienceListener { events ->
|
510
|
-
promise.resolve(true)
|
511
|
-
}
|
512
|
-
|
513
|
-
val errorListener = Consumer<Exception> { e ->
|
514
|
-
promise.reject("METER_ERROR", "Error executing meterExpired", e)
|
515
|
-
}
|
516
321
|
|
517
|
-
|
518
|
-
|
519
|
-
|
322
|
+
private fun validateMap(map: ReadableMap?, paramName: String, promise: Promise): Boolean {
|
323
|
+
if (map == null) {
|
324
|
+
promise.reject("INVALID_PARAMETER", "Map '$paramName' cannot be empty")
|
325
|
+
return false
|
326
|
+
}
|
327
|
+
return true
|
520
328
|
}
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
fun composerExecutionCompleted(promise: Promise) {
|
525
|
-
try {
|
526
|
-
val composer = Composer.getInstance()
|
527
|
-
if (composer == null) {
|
528
|
-
promise.reject("NOT_INITIALIZED", "Piano Composer is not initialized.")
|
529
|
-
return
|
530
|
-
}
|
531
|
-
|
532
|
-
val request = ExperienceRequest.Builder()
|
533
|
-
.debug(true)
|
534
|
-
.tags(tags)
|
535
|
-
.zone(zoneId)
|
536
|
-
.referer(referrer)
|
537
|
-
.customVariables(customVariables.mapValues { listOf(it.value) })
|
538
|
-
.url(url)
|
539
|
-
.userToken(userToken)
|
540
|
-
.build()
|
541
|
-
|
542
|
-
val listener = ExecuteExperienceListener { events ->
|
543
|
-
promise.resolve(true)
|
544
|
-
}
|
545
|
-
|
546
|
-
val errorListener = Consumer<Exception> { e ->
|
547
|
-
promise.reject("COMPLETION_ERROR", "Error executing composerExecutionCompleted", e)
|
548
|
-
}
|
549
|
-
|
550
|
-
composer.getExperience(request, listener, errorListener)
|
551
|
-
} catch (e: Exception) {
|
552
|
-
promise.reject("COMPLETION_ERROR", "Error executing composerExecutionCompleted", e)
|
329
|
+
|
330
|
+
companion object {
|
331
|
+
const val NAME = "SdkPianoio"
|
553
332
|
}
|
554
|
-
}
|
555
|
-
|
556
|
-
companion object {
|
557
|
-
const val NAME = "SdkPianoio"
|
558
|
-
}
|
559
333
|
}
|