react-native-spike-sdk 2.4.4 → 2.4.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.
|
@@ -18,6 +18,8 @@ import kotlinx.coroutines.CoroutineScope
|
|
|
18
18
|
import kotlinx.coroutines.Dispatchers
|
|
19
19
|
import kotlinx.coroutines.SupervisorJob
|
|
20
20
|
import kotlinx.coroutines.launch
|
|
21
|
+
import kotlinx.coroutines.sync.Mutex
|
|
22
|
+
import kotlinx.coroutines.sync.withLock
|
|
21
23
|
import java.time.OffsetDateTime
|
|
22
24
|
import java.util.UUID
|
|
23
25
|
|
|
@@ -32,7 +34,8 @@ fun <I, O> ComponentActivity.registerActivityResultLauncher(
|
|
|
32
34
|
class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
33
35
|
ReactContextBaseJavaModule(reactContext), LifecycleEventListener {
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
// Do not use this directly, use `addConnection` and `getConnection` instead
|
|
38
|
+
private val _connections = mutableMapOf<String, SpikeConnection>()
|
|
36
39
|
|
|
37
40
|
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
|
38
41
|
|
|
@@ -85,7 +88,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
85
88
|
} else {
|
|
86
89
|
null
|
|
87
90
|
}
|
|
88
|
-
|
|
91
|
+
addConnection(connection = SpikeConnection.createConnection(
|
|
89
92
|
context = reactApplicationContext,
|
|
90
93
|
authToken = authToken,
|
|
91
94
|
customerEndUserId = customerEndUserId,
|
|
@@ -93,7 +96,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
93
96
|
callbackUrl = callbackUrl,
|
|
94
97
|
env = SpikeEnvironment.PROD,
|
|
95
98
|
logger = logger,
|
|
96
|
-
)
|
|
99
|
+
), uuid = uuid)
|
|
97
100
|
promise.resolve(uuid)
|
|
98
101
|
} catch (e: SpikeExceptions) {
|
|
99
102
|
promise.reject(e.mapException(), e.message)
|
|
@@ -103,38 +106,43 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
103
106
|
|
|
104
107
|
@ReactMethod
|
|
105
108
|
fun getAppId(uuid: String, promise: Promise) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
109
|
+
scope.launch {
|
|
110
|
+
try {
|
|
111
|
+
val connection = getConnection(uuid) ?: return@launch promise.reject(
|
|
112
|
+
SpikeExceptions.SpikeException(
|
|
113
|
+
"Connection not found"
|
|
114
|
+
).mapException(), "Connection not found"
|
|
115
|
+
)
|
|
116
|
+
val appId = connection.getAppId()
|
|
117
|
+
promise.resolve(appId)
|
|
118
|
+
} catch (e: SpikeExceptions) {
|
|
119
|
+
promise.reject(e.mapException(), e.message)
|
|
120
|
+
}
|
|
116
121
|
}
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
@ReactMethod
|
|
120
125
|
fun getSpikeEndUserId(uuid: String, promise: Promise) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
scope.launch {
|
|
127
|
+
try {
|
|
128
|
+
val connection = getConnection(uuid) ?: return@launch promise.reject(
|
|
129
|
+
SpikeExceptions.SpikeException(
|
|
130
|
+
"Connection not found"
|
|
131
|
+
).mapException(), "Connection not found"
|
|
132
|
+
)
|
|
133
|
+
val spikeEndUserId = connection.getSpikeUserId()
|
|
134
|
+
promise.resolve(spikeEndUserId)
|
|
135
|
+
} catch (e: SpikeExceptions) {
|
|
136
|
+
promise.reject(e.mapException(), e.message)
|
|
137
|
+
}
|
|
131
138
|
}
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
@ReactMethod
|
|
135
142
|
fun getCustomerEndUserId(uuid: String, promise: Promise) {
|
|
143
|
+
scope.launch {
|
|
136
144
|
try {
|
|
137
|
-
val connection =
|
|
145
|
+
val connection = getConnection(uuid) ?: return@launch promise.reject(
|
|
138
146
|
SpikeExceptions.SpikeException(
|
|
139
147
|
"Connection not found"
|
|
140
148
|
).mapException(), "Connection not found"
|
|
@@ -144,21 +152,23 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
144
152
|
} catch (e: SpikeExceptions) {
|
|
145
153
|
promise.reject(e.mapException(), e.message)
|
|
146
154
|
}
|
|
155
|
+
}
|
|
147
156
|
}
|
|
148
157
|
|
|
149
158
|
@ReactMethod
|
|
150
159
|
fun getCallbackUrl(uuid: String, promise: Promise) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
160
|
+
scope.launch {
|
|
161
|
+
try {
|
|
162
|
+
val connection = getConnection(uuid) ?: return@launch promise.reject(
|
|
154
163
|
SpikeExceptions.SpikeException(
|
|
155
164
|
"Connection not found"
|
|
156
165
|
).mapException(), "Connection not found"
|
|
157
166
|
)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
167
|
+
val callbackUrl = connection.getPostbackUrl()
|
|
168
|
+
promise.resolve(callbackUrl)
|
|
169
|
+
} catch (e: SpikeExceptions) {
|
|
170
|
+
promise.reject(e.mapException(), e.message)
|
|
171
|
+
}
|
|
162
172
|
}
|
|
163
173
|
}
|
|
164
174
|
|
|
@@ -167,7 +177,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
167
177
|
fun close(uuid: String, promise: Promise) {
|
|
168
178
|
scope.launch {
|
|
169
179
|
try {
|
|
170
|
-
val connection =
|
|
180
|
+
val connection = getConnection(uuid) ?: return@launch promise.reject(
|
|
171
181
|
SpikeExceptions.SpikeException(
|
|
172
182
|
"Connection not found"
|
|
173
183
|
).mapException(), "Connection not found"
|
|
@@ -190,7 +200,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
190
200
|
) {
|
|
191
201
|
scope.launch {
|
|
192
202
|
try {
|
|
193
|
-
val connection =
|
|
203
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
194
204
|
SpikeExceptions.SpikeException(
|
|
195
205
|
"Connection not found"
|
|
196
206
|
).mapException(), "Connection not found"
|
|
@@ -217,7 +227,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
217
227
|
) {
|
|
218
228
|
scope.launch {
|
|
219
229
|
try {
|
|
220
|
-
val connection =
|
|
230
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
221
231
|
SpikeExceptions.SpikeException(
|
|
222
232
|
"Connection not found"
|
|
223
233
|
).mapException(), "Connection not found"
|
|
@@ -242,7 +252,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
242
252
|
) {
|
|
243
253
|
scope.launch {
|
|
244
254
|
try {
|
|
245
|
-
val connection =
|
|
255
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
246
256
|
SpikeExceptions.SpikeException(
|
|
247
257
|
"Connection not found"
|
|
248
258
|
).mapException(), "Connection not found"
|
|
@@ -265,7 +275,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
265
275
|
) {
|
|
266
276
|
scope.launch {
|
|
267
277
|
try {
|
|
268
|
-
val connection =
|
|
278
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
269
279
|
SpikeExceptions.SpikeException(
|
|
270
280
|
"Connection not found"
|
|
271
281
|
).mapException(), "Connection not found"
|
|
@@ -282,16 +292,18 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
282
292
|
|
|
283
293
|
@ReactMethod
|
|
284
294
|
fun manageHealthConnect(connectionUUID: String, promise: Promise) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
+
scope.launch {
|
|
296
|
+
try {
|
|
297
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
298
|
+
SpikeExceptions.SpikeException(
|
|
299
|
+
"Connection not found"
|
|
300
|
+
).mapException(), "Connection not found"
|
|
301
|
+
)
|
|
302
|
+
connection.manageHealthConnect()
|
|
303
|
+
promise.resolve(true)
|
|
304
|
+
} catch (e: SpikeExceptions) {
|
|
305
|
+
promise.reject(e.mapException(), e.message)
|
|
306
|
+
}
|
|
295
307
|
}
|
|
296
308
|
}
|
|
297
309
|
|
|
@@ -299,7 +311,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
299
311
|
fun checkPermissionsGranted(connectionUUID: String, dataType: String, promise: Promise) {
|
|
300
312
|
scope.launch {
|
|
301
313
|
try {
|
|
302
|
-
val connection =
|
|
314
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
303
315
|
SpikeExceptions.SpikeException(
|
|
304
316
|
"Connection not found"
|
|
305
317
|
).mapException(), "Connection not found"
|
|
@@ -320,7 +332,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
320
332
|
fun getHealthConnectAvailability(connectionUUID: String, promise: Promise) {
|
|
321
333
|
scope.launch {
|
|
322
334
|
try {
|
|
323
|
-
val connection =
|
|
335
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
324
336
|
SpikeExceptions.SpikeException(
|
|
325
337
|
"Connection not found"
|
|
326
338
|
).mapException(), "Connection not found"
|
|
@@ -337,7 +349,7 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
337
349
|
fun revokeAllPermissions(connectionUUID: String, promise: Promise) {
|
|
338
350
|
scope.launch {
|
|
339
351
|
try {
|
|
340
|
-
val connection =
|
|
352
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
341
353
|
SpikeExceptions.SpikeException(
|
|
342
354
|
"Connection not found"
|
|
343
355
|
).mapException(), "Connection not found"
|
|
@@ -352,98 +364,117 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
352
364
|
|
|
353
365
|
@ReactMethod
|
|
354
366
|
fun requestHealthPermissions(connectionUUID: String, dataType: String, promise: Promise) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
val availability = connection.getHealthConnectAvailability()
|
|
370
|
-
if (availability == HealthConnectAvailability.INSTALLED) {
|
|
371
|
-
reactApplicationContext.currentActivity?.startActivityForResult(
|
|
372
|
-
intent,
|
|
373
|
-
REQUEST_CODE
|
|
367
|
+
scope.launch {
|
|
368
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
369
|
+
SpikeExceptions.SpikeException(
|
|
370
|
+
"Connection not found"
|
|
371
|
+
).mapException(), "Connection not found"
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
val permissions =
|
|
375
|
+
connection.getRequiredHealthPermissionsMetadata(dataType.toSpikeDataType())
|
|
376
|
+
|
|
377
|
+
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU) {
|
|
378
|
+
val intent = SpikeConnection.requestReadAuthorization().createIntent(
|
|
379
|
+
reactApplicationContext, permissions
|
|
374
380
|
)
|
|
375
|
-
promise.resolve(true)
|
|
376
|
-
} else {
|
|
377
|
-
promise.reject(SpikeExceptions.SpikeException().mapException(), SpikeExceptions.SpikeException().message)
|
|
378
|
-
}
|
|
379
|
-
} else {
|
|
380
|
-
val activity = reactApplicationContext.currentActivity
|
|
381
|
-
if (activity is ComponentActivity) {
|
|
382
|
-
checkPermissionsFor = Triple(connectionUUID, setOf(dataType), promise)
|
|
383
|
-
val launcher =
|
|
384
|
-
activity.registerActivityResultLauncher(
|
|
385
|
-
SpikeConnection.requestReadAuthorization()
|
|
386
|
-
) {
|
|
387
381
|
|
|
382
|
+
val availability = connection.getHealthConnectAvailability()
|
|
383
|
+
if (availability == HealthConnectAvailability.INSTALLED) {
|
|
384
|
+
reactApplicationContext.currentActivity?.startActivityForResult(
|
|
385
|
+
intent,
|
|
386
|
+
REQUEST_CODE
|
|
387
|
+
)
|
|
388
|
+
promise.resolve(true)
|
|
389
|
+
} else {
|
|
390
|
+
promise.reject(
|
|
391
|
+
SpikeExceptions.SpikeException().mapException(),
|
|
392
|
+
SpikeExceptions.SpikeException().message
|
|
393
|
+
)
|
|
394
|
+
}
|
|
395
|
+
} else {
|
|
396
|
+
val activity = reactApplicationContext.currentActivity
|
|
397
|
+
if (activity is ComponentActivity) {
|
|
398
|
+
checkPermissionsFor = Triple(connectionUUID, setOf(dataType), promise)
|
|
399
|
+
val launcher =
|
|
400
|
+
activity.registerActivityResultLauncher(
|
|
401
|
+
SpikeConnection.requestReadAuthorization()
|
|
402
|
+
) {
|
|
403
|
+
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (permissions.isNotEmpty()) {
|
|
407
|
+
launcher.launch(permissions)
|
|
408
|
+
} else {
|
|
409
|
+
promise.resolve(false)
|
|
388
410
|
}
|
|
389
|
-
|
|
390
|
-
if (permissions.isNotEmpty()) {
|
|
391
|
-
launcher.launch(permissions)
|
|
392
411
|
} else {
|
|
393
412
|
promise.resolve(false)
|
|
394
413
|
}
|
|
395
|
-
} else {
|
|
396
|
-
promise.resolve(false)
|
|
397
414
|
}
|
|
398
415
|
}
|
|
399
416
|
}
|
|
400
417
|
|
|
401
418
|
@ReactMethod
|
|
402
419
|
fun requestMultipleHealthPermissions(connectionUUID: String, dataTypes: ReadableArray, promise: Promise) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
val permissions = mutableSetOf<String>()
|
|
410
|
-
dataTypes.toArrayList().forEach {
|
|
411
|
-
connection.getRequiredHealthPermissionsMetadata((it as String).toSpikeDataType()).forEach {
|
|
412
|
-
permissions.add(it)
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU) {
|
|
417
|
-
val availability = connection.getHealthConnectAvailability()
|
|
418
|
-
if (permissions.isNotEmpty() && availability == HealthConnectAvailability.INSTALLED) {
|
|
419
|
-
val intent = SpikeConnection.requestReadAuthorization().createIntent(
|
|
420
|
-
reactApplicationContext, permissions
|
|
421
|
-
)
|
|
420
|
+
scope.launch {
|
|
421
|
+
val connection = getConnection(connectionUUID) ?: return@launch promise.reject(
|
|
422
|
+
SpikeExceptions.SpikeException(
|
|
423
|
+
"Connection not found"
|
|
424
|
+
).mapException(), "Connection not found"
|
|
425
|
+
)
|
|
422
426
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
promise.reject(SpikeExceptions.SpikeException().mapException(), SpikeExceptions.SpikeException().message)
|
|
427
|
+
val permissions = mutableSetOf<String>()
|
|
428
|
+
dataTypes.toArrayList().forEach {
|
|
429
|
+
connection.getRequiredHealthPermissionsMetadata((it as String).toSpikeDataType())
|
|
430
|
+
.forEach {
|
|
431
|
+
permissions.add(it)
|
|
432
|
+
}
|
|
430
433
|
}
|
|
431
|
-
} else {
|
|
432
|
-
val activity = reactApplicationContext.currentActivity
|
|
433
|
-
if (activity is ComponentActivity) {
|
|
434
|
-
checkPermissionsFor = Triple(connectionUUID, dataTypes.toArrayList().toSet() as Set<String>, promise)
|
|
435
|
-
val launcher =
|
|
436
|
-
activity.registerActivityResultLauncher(
|
|
437
|
-
SpikeConnection.requestReadAuthorization()
|
|
438
|
-
) {
|
|
439
434
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
435
|
+
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU) {
|
|
436
|
+
val availability = connection.getHealthConnectAvailability()
|
|
437
|
+
if (permissions.isNotEmpty() && availability == HealthConnectAvailability.INSTALLED) {
|
|
438
|
+
val intent = SpikeConnection.requestReadAuthorization().createIntent(
|
|
439
|
+
reactApplicationContext, permissions
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
reactApplicationContext.currentActivity?.startActivityForResult(
|
|
443
|
+
intent,
|
|
444
|
+
REQUEST_CODE
|
|
445
|
+
)
|
|
446
|
+
promise.resolve(true)
|
|
443
447
|
} else {
|
|
444
|
-
promise.reject(
|
|
448
|
+
promise.reject(
|
|
449
|
+
SpikeExceptions.SpikeException().mapException(),
|
|
450
|
+
SpikeExceptions.SpikeException().message
|
|
451
|
+
)
|
|
452
|
+
}
|
|
445
453
|
} else {
|
|
446
|
-
|
|
454
|
+
val activity = reactApplicationContext.currentActivity
|
|
455
|
+
if (activity is ComponentActivity) {
|
|
456
|
+
checkPermissionsFor = Triple(
|
|
457
|
+
connectionUUID,
|
|
458
|
+
dataTypes.toArrayList().toSet() as Set<String>,
|
|
459
|
+
promise
|
|
460
|
+
)
|
|
461
|
+
val launcher =
|
|
462
|
+
activity.registerActivityResultLauncher(
|
|
463
|
+
SpikeConnection.requestReadAuthorization()
|
|
464
|
+
) {
|
|
465
|
+
|
|
466
|
+
}
|
|
467
|
+
if (permissions.isNotEmpty()) {
|
|
468
|
+
launcher.launch(permissions)
|
|
469
|
+
} else {
|
|
470
|
+
promise.reject(
|
|
471
|
+
SpikeExceptions.SpikeException().mapException(),
|
|
472
|
+
SpikeExceptions.SpikeException().message
|
|
473
|
+
)
|
|
474
|
+
}
|
|
475
|
+
} else {
|
|
476
|
+
promise.resolve(false)
|
|
477
|
+
}
|
|
447
478
|
}
|
|
448
479
|
}
|
|
449
480
|
}
|
|
@@ -504,4 +535,23 @@ class SpikeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
504
535
|
const val NAME = "SpikeSdk"
|
|
505
536
|
const val REQUEST_CODE = 4200
|
|
506
537
|
}
|
|
538
|
+
|
|
539
|
+
// Connections
|
|
540
|
+
|
|
541
|
+
private val mutex = Mutex()
|
|
542
|
+
|
|
543
|
+
// Add new connection to the dictionary in a thread-safe manner
|
|
544
|
+
private suspend fun addConnection(connection: SpikeConnection, uuid: String) {
|
|
545
|
+
mutex.withLock {
|
|
546
|
+
_connections[uuid] = connection
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// Synchronised read for safe multithreaded usage
|
|
551
|
+
private suspend fun getConnection(uuid: String): SpikeConnection? {
|
|
552
|
+
mutex.withLock {
|
|
553
|
+
return _connections[uuid]
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
507
557
|
}
|