@usercentrics/react-native-sdk 2.2.1 → 2.4.0

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 (44) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/android/build.gradle +1 -1
  3. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/RNUsercentricsModuleTest.kt +13 -144
  4. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/api/FakeUsercentricsProxy.kt +4 -31
  5. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetTCFDataMock.kt +3 -1
  6. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/RNUsercentricsModule.kt +25 -76
  7. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/api/UsercentricsProxy.kt +12 -64
  8. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/BannerFontExtensions.kt +26 -0
  9. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/FirstLayerOptionsExtensions.kt +39 -14
  10. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/TCFDataExtensions.kt +2 -1
  11. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsReadyStatusExtensions.kt +1 -1
  12. package/ios/Extensions/BannerSettings+Dict.swift +103 -16
  13. package/ios/Extensions/ReadyStatus+Dict.swift +1 -1
  14. package/ios/Manager/UsercentricsManager.swift +12 -25
  15. package/ios/RNUsercentricsModule.swift +19 -55
  16. package/ios/RNUsercentricsModule.xcodeproj/project.pbxproj +0 -8
  17. package/lib/Usercentrics.d.ts +4 -5
  18. package/lib/Usercentrics.js +3 -7
  19. package/lib/Usercentrics.js.map +1 -1
  20. package/lib/models/BannerSettings.d.ts +26 -4
  21. package/lib/models/BannerSettings.js +25 -1
  22. package/lib/models/BannerSettings.js.map +1 -1
  23. package/lib/models/FirstLayerOptions.d.ts +14 -12
  24. package/lib/models/FirstLayerOptions.js +10 -8
  25. package/lib/models/FirstLayerOptions.js.map +1 -1
  26. package/lib/models/SecondLayerOptions.d.ts +7 -3
  27. package/lib/models/SecondLayerOptions.js +6 -1
  28. package/lib/models/SecondLayerOptions.js.map +1 -1
  29. package/lib/models/TCFData.d.ts +2 -1
  30. package/lib/models/TCFData.js +2 -1
  31. package/lib/models/TCFData.js.map +1 -1
  32. package/lib/models/UsercentricsReadyStatus.d.ts +2 -2
  33. package/lib/models/UsercentricsReadyStatus.js +2 -2
  34. package/lib/models/UsercentricsReadyStatus.js.map +1 -1
  35. package/lib/models/index.d.ts +2 -3
  36. package/lib/models/index.js +2 -3
  37. package/lib/models/index.js.map +1 -1
  38. package/package.json +2 -2
  39. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsUserInterfaceExtensions.kt +0 -45
  40. package/ios/Extensions/UIFont+UsercentricsFontDict.swift +0 -15
  41. package/ios/Extensions/UsercentricsUISettings+Dict.swift +0 -27
  42. package/lib/models/UsercentricsUIOptions.d.ts +0 -18
  43. package/lib/models/UsercentricsUIOptions.js +0 -21
  44. package/lib/models/UsercentricsUIOptions.js.map +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,74 @@
1
+ [Release Notes](https://docs.usercentrics.com/cmp_in_app_sdk/latest/about/history/)
2
+
3
+ # 2.4.0
4
+
5
+ ## Features
6
+
7
+ - **[Customization]** You now have full control over the appearance of the First & Second Layer via our Admin Interface Style options and our Programmatic API. We have updated and extended our Programmatic API to simplify banner customization.
8
+ - **[UI]** Legal links are now added to our the First Layer, and can be hidden or shown as desired via programmatic API.
9
+ - **[CCPA]** Consent button can now be customized via the Admin Interface.
10
+
11
+ ## Improvements
12
+
13
+ - Improve initialization flow for stability and avoid edge case crashes.
14
+
15
+ ## Resolved Issues
16
+
17
+ - Solve stability issues and bug fixes.
18
+
19
+ # 2.3.0
20
+
21
+ ## Features
22
+
23
+ - **[API Update]** `shouldShowCMP` has been deprecated in favor of `shouldCollectConsent`. See [Initializing the SDK](https://docs.usercentrics.com/cmp_in_app_sdk/latest/getting_started/initialize/#initializing-the-sdk)
24
+ - **[Banner API v2]** Banner API v1 is now discontinued and removed from the SDK. If you don't wish to upgrade, please stick to v2.0.3 to avoid unexpected behaviour. See the [alert in the "Banner API V1" tab](https://docs.usercentrics.com/cmp_in_app_sdk/latest/collect_consent/present_cmp/)
25
+ - **[Banner API v2]** BannerSettings now requires a BannerFont object to pass a Bold and Regular font separately to apply for both layers. See [Banner Settings](https://docs.usercentrics.com/cmp_in_app_sdk/latest/collect_consent/customize_cmp/#banner-style-settings)
26
+ - **[Demo App]** You can now find a demo app in our documentation to test out your configuration before writing a single line of code. See [Sample Apps](https://docs.usercentrics.com/cmp_in_app_sdk/latest/samples/ios-android-demos/).
27
+
28
+ ## Improvements
29
+
30
+ - Updates to TCF 2.0 framework.
31
+
32
+ ## Resolved Issues
33
+
34
+ - Issue with position of logo on Second Layer is now solved.
35
+ - UI/UX improvements and fixes.
36
+
37
+ # 2.2.1
38
+
39
+ ## Features
40
+
41
+ - **[Banner API v2]** A complete revamp of our banner API will enable you to have high customisation and versatility to build a end-user friendly consent banner. We can't wait for you to give it a try. For more details, see: Presenting the Banner.
42
+ - Add a Header Image to your banner.
43
+ - Have full control over the layour of your action buttons with Column, Row or Grid configurations.
44
+ - Launch the second layer directly.
45
+ - Landscape Mode support.
46
+ - You can now add a "More Information" link to your banner message to forward users to the 2nd Layer. Appearance > Settings > More Information Link in Banner Message. Then you will be able to add this link in the banner message text editor.
47
+ - **[Usability]** Collect consent only at a category level. Option available in your Admin Interface: Configure > Legal Specifications > Settings > Category Consent.
48
+ - **[CNIL]** "Continue wthout Accepting" feature is now supported. (French regulation)
49
+ - **[Fonts]** Admin Interface fonts are now deprecated for App. To enable custom fonts, please inject the font via banner API.
50
+
51
+ ## Improvements
52
+
53
+ - **[API]** Expose user's consent history.
54
+ - **[TCF 2.0]** Adding support to actively inform users when vendors are sharing data outside a region.
55
+ - **[CCPA]** Improve API to facilitate compliance with new Banner API.
56
+
57
+ ## Resolved Issues
58
+ - **[TCF 2.0]** Minor design upgrades to improve usability.
59
+ - **[iOS]** Edge case with RestoreUserSession failing is now solved.
60
+ - **[iOS]** Issue with local and remote images losing quality is now solved.
61
+ - UI/UX improvements and fixes.
62
+
63
+ # 2.0.3
64
+
65
+ - Minor fix on UI related to consent toggles.
66
+ - Corner radius on iOS.
67
+
68
+ # 2.0.2
69
+
70
+ - Custom UI API.
71
+
72
+ # 2.0.1
73
+
74
+ - Initial version of the library.
@@ -1,4 +1,4 @@
1
- def usercentrics_version = "2.2.1"
1
+ def usercentrics_version = "2.4.0"
2
2
  version usercentrics_version
3
3
 
4
4
  buildscript {
@@ -19,11 +19,11 @@ import com.usercentrics.sdk.models.common.UsercentricsLoggerLevel
19
19
  import com.usercentrics.sdk.models.common.UsercentricsVariant
20
20
  import com.usercentrics.sdk.models.settings.UsercentricsConsentType
21
21
  import com.usercentrics.sdk.services.tcf.TCFDecisionUILayer
22
+ import com.usercentrics.sdk.services.tcf.interfaces.TCFData
22
23
  import io.mockk.every
23
24
  import io.mockk.mockk
24
25
  import io.mockk.verify
25
26
  import org.junit.Assert.assertEquals
26
- import org.junit.Assert.assertThrows
27
27
  import org.junit.Before
28
28
  import org.junit.Test
29
29
  import org.junit.runner.RunWith
@@ -48,7 +48,7 @@ class RNUsercentricsModuleTest {
48
48
  )
49
49
 
50
50
  private val usercentricsReadyStatus = UsercentricsReadyStatus(
51
- shouldShowCMP = false,
51
+ shouldCollectConsent = false,
52
52
  consents = listOf(
53
53
  UsercentricsServiceConsent(
54
54
  templateId = "ocv9HNX_g",
@@ -61,37 +61,6 @@ class RNUsercentricsModuleTest {
61
61
  )
62
62
  )
63
63
  )
64
-
65
- private val usercentricsUIOptions = JavaOnlyMap().apply {
66
- putBoolean("showCloseButton", false)
67
- putMap("customLogo", JavaOnlyMap().apply {
68
- putString("logoName", "logo.png")
69
- putString(
70
- "logoPath",
71
- "http://10.0.2.2:8081/assets/assets/images/logo.png"
72
- )
73
- })
74
- putMap("customFont", JavaOnlyMap().apply {
75
- putString("fontName", "Lora")
76
- putInt("fontSize", 14)
77
- })
78
- }
79
-
80
- private val usercentricsConsentUserResponse = UsercentricsConsentUserResponse(
81
- consents = listOf(
82
- UsercentricsServiceConsent(
83
- templateId = "ocv9HNX_g",
84
- status = false,
85
- dataProcessor = "Facebook SDK",
86
- type = UsercentricsConsentType.EXPLICIT,
87
- version = "1.0.1",
88
- isEssential = false,
89
- history = usercentricsConsentHistoryEntries
90
- )
91
- ),
92
- controllerId = "8620135313b043696b806868b20da905886a3a2598ddddc2b52973f9807d6b45",
93
- userInteraction = UsercentricsUserInteraction.ACCEPT_ALL
94
- )
95
64
  }
96
65
 
97
66
  @Before
@@ -151,7 +120,7 @@ class RNUsercentricsModuleTest {
151
120
  val consent = result.getArray("consents")?.getMap(0)!!
152
121
 
153
122
  assertEquals(1, usercentricsProxy.isReadyCount)
154
- assertEquals(false, result.getBoolean("shouldShowCMP"))
123
+ assertEquals(false, result.getBoolean("shouldCollectConsent"))
155
124
  assertEquals(false, consent.getBoolean("status"))
156
125
  assertEquals("ocv9HNX_g", consent.getString("templateId"))
157
126
  assertEquals("Facebook SDK", consent.getString("dataProcessor"))
@@ -194,7 +163,7 @@ class RNUsercentricsModuleTest {
194
163
  val result = promise.resolveValue as WritableMap
195
164
  val consent = result.getArray("consents")?.getMap(0)!!
196
165
 
197
- assertEquals(false, result.getBoolean("shouldShowCMP"))
166
+ assertEquals(false, result.getBoolean("shouldCollectConsent"))
198
167
  assertEquals(false, consent.getBoolean("status"))
199
168
  assertEquals("ocv9HNX_g", consent.getString("templateId"))
200
169
  assertEquals("Facebook SDK", consent.getString("dataProcessor"))
@@ -239,7 +208,9 @@ class RNUsercentricsModuleTest {
239
208
  @Test
240
209
  fun testGetTCString() {
241
210
  val usercentricsSDK = mockk<UsercentricsSDK>()
242
- every { usercentricsSDK.getTCString() }.returns("abc")
211
+ every { usercentricsSDK.getTCString(any()) }.answers {
212
+ firstArg<(String) -> Unit>().invoke("abc")
213
+ }
243
214
  val usercentricsProxy = FakeUsercentricsProxy(usercentricsSDK)
244
215
  val contextMock = mockk<ReactApplicationContext>(relaxed = true)
245
216
  val module = RNUsercentricsModule(contextMock, usercentricsProxy)
@@ -247,87 +218,10 @@ class RNUsercentricsModuleTest {
247
218
 
248
219
  module.getTCFString(promise)
249
220
 
250
- verify(exactly = 1) { usercentricsSDK.getTCString() }
221
+ verify(exactly = 1) { usercentricsSDK.getTCString(any()) }
251
222
  assertEquals("abc", promise.resolveValue)
252
223
  }
253
224
 
254
- @Test
255
- fun testShowCMP() {
256
- val usercentricsProxy = FakeUsercentricsProxy()
257
- usercentricsProxy.createIntentValue = mockk(relaxed = true)
258
-
259
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
260
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
261
- val promise = FakePromise()
262
-
263
- module.showCMP(usercentricsUIOptions, promise)
264
-
265
- val responseUsercentricsOptions = usercentricsProxy.usercentricsOptions!!
266
- val customLogoURL =
267
- (responseUsercentricsOptions.customLogo as UsercentricsImage.ImageUrl).imageUrl
268
-
269
- assertEquals(false, responseUsercentricsOptions.showCloseButton)
270
- assertEquals(
271
- "http://10.0.2.2:8081/assets/assets/images/logo.png",
272
- customLogoURL
273
- )
274
- }
275
-
276
- @Test
277
- fun testOnActivityResultWithOtherCode() {
278
- val usercentricsProxy = FakeUsercentricsProxy()
279
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
280
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
281
-
282
- val otherRequestCode = 123
283
- val consumed = module.parseActivityResult(otherRequestCode, 123, null)
284
-
285
- assertEquals(false, consumed)
286
- }
287
-
288
- @Test
289
- fun testOnActivityResultWithNoPendingResult() {
290
- val usercentricsProxy = FakeUsercentricsProxy()
291
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
292
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
293
-
294
- assertThrows(AssertionError::class.java) {
295
- module.parseActivityResult(81420, 123, null)
296
- }
297
- }
298
-
299
- @Test
300
- fun testOnActivityResultWithPendingResult() {
301
- val resultCode = 123
302
- val usercentricsProxy = FakeUsercentricsProxy()
303
- usercentricsProxy.createIntentValue = mockk(relaxed = true)
304
- usercentricsProxy.parseResultValue = usercentricsConsentUserResponse
305
-
306
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
307
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
308
-
309
- val promise = FakePromise()
310
- module.showCMP(usercentricsUIOptions, promise)
311
-
312
- module.parseActivityResult(81420, resultCode, null)
313
-
314
- assertEquals(resultCode, usercentricsProxy.parseResultResultCodeArgument)
315
-
316
- val result = promise.resolveValue as WritableMap
317
- val consent = result.getArray("consents")?.getMap(0)!!
318
-
319
- assertEquals(
320
- "8620135313b043696b806868b20da905886a3a2598ddddc2b52973f9807d6b45",
321
- result.getString("controllerId")
322
- )
323
- assertEquals(0, result.getInt("userInteraction"))
324
- assertEquals(false, consent.getBoolean("status"))
325
- assertEquals("ocv9HNX_g", consent.getString("templateId"))
326
- assertEquals("Facebook SDK", consent.getString("dataProcessor"))
327
- assertEquals(0, consent.getInt("type"))
328
- assertEquals("1.0.1", consent.getString("version"))
329
- }
330
-
331
225
  @Test
332
226
  fun testGetConsents() {
333
227
  val usercentricsSDK = mockk<UsercentricsSDK>()
@@ -415,7 +309,9 @@ class RNUsercentricsModuleTest {
415
309
  @Test
416
310
  fun testGetTCFData() {
417
311
  val usercentricsSDK = mockk<UsercentricsSDK>()
418
- every { usercentricsSDK.getTCFData() }.returns(GetTCFDataMock.fake)
312
+ every { usercentricsSDK.getTCFData(any()) }.answers {
313
+ firstArg<(TCFData) -> Unit>().invoke(GetTCFDataMock.fake)
314
+ }
419
315
 
420
316
  val usercentricsProxy = FakeUsercentricsProxy(usercentricsSDK)
421
317
  val contextMock = mockk<ReactApplicationContext>(relaxed = true)
@@ -426,7 +322,7 @@ class RNUsercentricsModuleTest {
426
322
 
427
323
  val result = promise.resolveValue
428
324
 
429
- verify(exactly = 1) { usercentricsSDK.getTCFData() }
325
+ verify(exactly = 1) { usercentricsSDK.getTCFData(any()) }
430
326
  assertEquals(GetTCFDataMock.expected.toWritableMap(), result)
431
327
  }
432
328
 
@@ -699,31 +595,4 @@ class RNUsercentricsModuleTest {
699
595
 
700
596
  assertEquals(1, usercentricsProxy.resetCount)
701
597
  }
702
-
703
- @Test
704
- fun testShowFirstLayer() {
705
- val usercentricsProxy = FakeUsercentricsProxy()
706
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
707
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
708
-
709
- val promise = FakePromise()
710
- module.showFirstLayer(ShowFirstLayerMock.arguments, promise)
711
-
712
- assertEquals(
713
- FirstLayerStyleSettings(
714
- title = TitleSettings(alignment = SectionAlignment.END),
715
- message = MessageSettings(alignment = SectionAlignment.CENTER),
716
- cornerRadius = 50
717
- ),
718
- usercentricsProxy.showFirstLayerStyle
719
- )
720
- assertEquals(
721
- BannerSettings(font = null, logo = null),
722
- usercentricsProxy.showFirstLayerBannerSettings
723
- )
724
- assertEquals(
725
- UsercentricsLayout.Popup(PopupPosition.CENTER),
726
- usercentricsProxy.showFirstLayerLayout
727
- )
728
- }
729
- }
598
+ }
@@ -42,26 +42,6 @@ internal class FakeUsercentricsProxy(
42
42
  }
43
43
  }
44
44
 
45
- var createIntentValue: Intent? = null
46
- var usercentricsOptions: UsercentricsUISettings? = null
47
- private set
48
-
49
- override fun createIntent(
50
- context: Context,
51
- usercentricsOptions: UsercentricsUISettings
52
- ): Intent {
53
- this.usercentricsOptions = usercentricsOptions
54
- return createIntentValue!!
55
- }
56
-
57
- var parseResultResultCodeArgument: Int = 0
58
- private set
59
- var parseResultValue: UsercentricsConsentUserResponse? = null
60
- override fun parseResult(resultCode: Int, data: Intent?): UsercentricsConsentUserResponse? {
61
- this.parseResultResultCodeArgument = resultCode
62
- return parseResultValue
63
- }
64
-
65
45
  var resetCount: Int = 0
66
46
  private set
67
47
 
@@ -73,19 +53,12 @@ internal class FakeUsercentricsProxy(
73
53
  var showFirstLayerBannerSettings: BannerSettings? = null
74
54
  var showFirstLayerStyle: FirstLayerStyleSettings? = null
75
55
 
76
- override fun showFirstLayer(
77
- activity: Activity,
78
- layout: UsercentricsLayout,
79
- bannerSettings: BannerSettings?,
80
- firstLayerStyleSettings: FirstLayerStyleSettings?,
81
- promise: Promise
82
- ) {
56
+ override fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise) {
83
57
  this.showFirstLayerLayout = layout
84
58
  this.showFirstLayerBannerSettings = bannerSettings
85
- this.showFirstLayerStyle = firstLayerStyleSettings
59
+ this.showFirstLayerStyle = bannerSettings?.firstLayerSettings
86
60
  }
87
61
 
88
- override fun showSecondLayer() {
89
-
62
+ override fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise) {
90
63
  }
91
- }
64
+ }
@@ -95,6 +95,7 @@ internal class GetTCFDataMock {
95
95
  dataSharedOutsideEU = false
96
96
  )
97
97
  ),
98
+ tcString = "abc"
98
99
  )
99
100
 
100
101
  // From the debugger
@@ -186,6 +187,7 @@ internal class GetTCFDataMock {
186
187
  "dataSharedOutsideEU" to false
187
188
  ),
188
189
  ),
190
+ "tcString" to "abc"
189
191
  )
190
192
  }
191
- }
193
+ }
@@ -1,15 +1,11 @@
1
1
  package com.usercentrics.reactnativeusercentrics
2
2
 
3
- import android.app.Activity
4
- import android.content.Intent
5
3
  import com.facebook.react.bridge.*
6
4
  import com.usercentrics.reactnativeusercentrics.api.UsercentricsProxy
7
5
  import com.usercentrics.reactnativeusercentrics.extensions.*
8
6
  import com.usercentrics.sdk.UsercentricsBanner
9
- import com.usercentrics.sdk.UsercentricsLayout
10
7
  import com.usercentrics.sdk.models.settings.UsercentricsConsentType
11
8
  import com.usercentrics.sdk.services.tcf.TCFDecisionUILayer
12
- import java.lang.Exception
13
9
 
14
10
  internal class RNUsercentricsModule(
15
11
  reactContext: ReactApplicationContext,
@@ -19,26 +15,6 @@ internal class RNUsercentricsModule(
19
15
 
20
16
  override fun getName() = "RNUsercentricsModule"
21
17
 
22
- private var pendingPromise: Promise? = null
23
- private val listener: ActivityEventListener = object : BaseActivityEventListener() {
24
- override fun onActivityResult(
25
- activity: Activity?,
26
- requestCode: Int,
27
- resultCode: Int,
28
- data: Intent?
29
- ) {
30
- parseActivityResult(requestCode, resultCode, data)
31
- }
32
- }
33
-
34
- init {
35
- reactApplicationContext.addActivityEventListener(listener)
36
- }
37
-
38
- companion object {
39
- private const val showCMPRequestCode = 81420
40
- }
41
-
42
18
  @ReactMethod
43
19
  fun configure(options: ReadableMap) {
44
20
  var alreadyConfigured = false
@@ -63,68 +39,36 @@ internal class RNUsercentricsModule(
63
39
  })
64
40
  }
65
41
 
66
- @ReactMethod
67
- fun showCMP(options: ReadableMap, promise: Promise) {
68
- val usercentricsOptions = options.usercentricsUISettingsFromMap(currentActivity!!.assets)
69
- this.pendingPromise = promise
70
-
71
- val intent = usercentricsProxy.createIntent(reactApplicationContext, usercentricsOptions)
72
- currentActivity?.startActivityForResult(intent, showCMPRequestCode)
73
- }
74
-
75
42
  @ReactMethod
76
43
  fun showFirstLayer(options: ReadableMap, promise: Promise) {
77
- try {
78
- val assetManager = currentActivity!!.assets
44
+ UiThreadUtil.runOnUiThread {
45
+ try {
46
+ val assetManager = currentActivity!!.assets
79
47
 
80
- val layout = options.getString("layout")!!.usercentricsLayoutFromEnumString()
81
- val bannerSettings = options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
82
- val styleSettings = options.getMap("styleSettings")?.firstLayerStyleSettingsFromMap(assetManager)
48
+ val layout = options.getString("layout")!!.usercentricsLayoutFromEnumString()
49
+ val bannerSettings = options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
50
+ usercentricsProxy.showFirstLayer(currentActivity!!, layout, bannerSettings, promise)
83
51
 
84
- usercentricsProxy.showFirstLayer(
85
- currentActivity!!,
86
- layout,
87
- bannerSettings,
88
- styleSettings,
89
- promise
90
- )
91
-
92
- } catch (e: Exception) {
93
- promise.reject(e)
52
+ } catch (e: Exception) {
53
+ promise.reject(e)
54
+ }
94
55
  }
95
56
  }
96
57
 
97
58
  @ReactMethod
98
59
  fun showSecondLayer(options: ReadableMap, promise: Promise) {
99
- try {
100
- val assetManager = currentActivity!!.assets
101
-
102
- val bannerSettings =
103
- options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
104
- val showCloseButton = options.getBoolean("showCloseButton")
105
-
106
- UsercentricsBanner(currentActivity!!, bannerSettings).showSecondLayer(
107
- showCloseButton
108
- ) {
109
- promise.resolve(it?.toWritableMap())
60
+ UiThreadUtil.runOnUiThread {
61
+ try {
62
+ val assetManager = currentActivity!!.assets
63
+
64
+ val bannerSettings = options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
65
+ usercentricsProxy.showSecondLayer(currentActivity!!, bannerSettings, promise)
66
+ } catch (e: Exception) {
67
+ promise.reject(e)
110
68
  }
111
- } catch (e: Exception) {
112
- promise.reject(e)
113
69
  }
114
70
  }
115
71
 
116
- internal fun parseActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
117
- if (requestCode != showCMPRequestCode) return false
118
- assert(pendingPromise != null)
119
-
120
- val response = usercentricsProxy.parseResult(resultCode, data)?.toWritableMap()
121
-
122
- pendingPromise?.resolve(response)
123
- pendingPromise = null
124
-
125
- return true
126
- }
127
-
128
72
  @ReactMethod
129
73
  fun restoreUserSession(controllerId: String, promise: Promise) {
130
74
  usercentricsProxy.instance.restoreUserSession(controllerId, {
@@ -135,8 +79,11 @@ internal class RNUsercentricsModule(
135
79
  }
136
80
 
137
81
  @ReactMethod
82
+ @Deprecated("Please, call getTCFData() to get the 'tcString' from that model")
138
83
  fun getTCFString(promise: Promise) {
139
- promise.resolve(usercentricsProxy.instance.getTCString())
84
+ usercentricsProxy.instance.getTCString {
85
+ promise.resolve(it)
86
+ }
140
87
  }
141
88
 
142
89
  @ReactMethod
@@ -161,7 +108,9 @@ internal class RNUsercentricsModule(
161
108
 
162
109
  @ReactMethod
163
110
  fun getTCFData(promise: Promise) {
164
- promise.resolve(usercentricsProxy.instance.getTCFData().serialize())
111
+ usercentricsProxy.instance.getTCFData {
112
+ promise.resolve(it.serialize())
113
+ }
165
114
  }
166
115
 
167
116
  @ReactMethod
@@ -263,4 +212,4 @@ internal class RNUsercentricsModule(
263
212
  fun reset() {
264
213
  usercentricsProxy.reset()
265
214
  }
266
- }
215
+ }
@@ -2,45 +2,19 @@ package com.usercentrics.reactnativeusercentrics.api
2
2
 
3
3
  import android.app.Activity
4
4
  import android.content.Context
5
- import android.content.Intent
6
- import android.util.Log
7
5
  import com.facebook.react.bridge.Promise
8
- import com.facebook.react.bridge.ReadableMap
9
- import com.usercentrics.reactnativeusercentrics.extensions.bannerSettingsFromMap
10
- import com.usercentrics.reactnativeusercentrics.extensions.firstLayerStyleSettingsFromMap
11
6
  import com.usercentrics.reactnativeusercentrics.extensions.toWritableMap
12
- import com.usercentrics.reactnativeusercentrics.extensions.usercentricsLayoutFromEnumString
13
7
  import com.usercentrics.sdk.*
14
8
  import com.usercentrics.sdk.errors.UsercentricsError
15
- import java.lang.Exception
16
9
 
17
10
  interface UsercentricsProxy {
11
+
18
12
  val instance: UsercentricsSDK
19
13
 
20
14
  fun initialize(context: Context, options: UsercentricsOptions)
21
-
22
- fun isReady(
23
- onSuccess: (UsercentricsReadyStatus) -> Unit,
24
- onFailure: (UsercentricsError) -> Unit
25
- )
26
-
27
- fun createIntent(
28
- context: Context,
29
- usercentricsOptions: UsercentricsUISettings
30
- ): Intent
31
-
32
- fun parseResult(resultCode: Int, data: Intent?): UsercentricsConsentUserResponse?
33
-
34
- fun showFirstLayer(
35
- activity: Activity,
36
- layout: UsercentricsLayout,
37
- bannerSettings: BannerSettings?,
38
- firstLayerStyleSettings: FirstLayerStyleSettings?,
39
- promise: Promise
40
- )
41
-
42
- fun showSecondLayer()
43
-
15
+ fun isReady(onSuccess: (UsercentricsReadyStatus) -> Unit, onFailure: (UsercentricsError) -> Unit)
16
+ fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise)
17
+ fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise)
44
18
  fun reset()
45
19
  }
46
20
 
@@ -57,45 +31,19 @@ internal class UsercentricsProxyImpl : UsercentricsProxy {
57
31
  }
58
32
  }
59
33
 
60
- override fun isReady(
61
- onSuccess: (UsercentricsReadyStatus) -> Unit,
62
- onFailure: (UsercentricsError) -> Unit
63
- ) = Usercentrics.isReady(onSuccess, onFailure)
64
-
65
- override fun createIntent(
66
- context: Context,
67
- usercentricsOptions: UsercentricsUISettings
68
- ): Intent {
69
- return UsercentricsActivityContract().createIntent(
70
- context,
71
- usercentricsOptions
72
- )
73
- }
74
-
75
- override fun parseResult(resultCode: Int, data: Intent?): UsercentricsConsentUserResponse? {
76
- return UsercentricsActivityContract()
77
- .parseResult(resultCode, data)
78
- }
34
+ override fun isReady(onSuccess: (UsercentricsReadyStatus) -> Unit, onFailure: (UsercentricsError) -> Unit) = Usercentrics.isReady(onSuccess, onFailure)
79
35
 
80
- override fun showFirstLayer(
81
- activity: Activity,
82
- layout: UsercentricsLayout,
83
- bannerSettings: BannerSettings?,
84
- firstLayerStyleSettings: FirstLayerStyleSettings?,
85
- promise: Promise
86
- ) {
87
- UsercentricsBanner(activity, bannerSettings).showFirstLayer(
88
- layout,
89
- firstLayerStyleSettings
90
- ) {
36
+ override fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise) {
37
+ UsercentricsBanner(activity, bannerSettings).showFirstLayer(layout) {
91
38
  promise.resolve(it?.toWritableMap())
92
39
  }
93
40
  }
94
41
 
95
- override fun showSecondLayer() {
96
-
42
+ override fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise) {
43
+ UsercentricsBanner(activity, bannerSettings).showSecondLayer {
44
+ promise.resolve(it?.toWritableMap())
45
+ }
97
46
  }
98
47
 
99
48
  override fun reset() = Usercentrics.reset()
100
-
101
- }
49
+ }
@@ -0,0 +1,26 @@
1
+ package com.usercentrics.reactnativeusercentrics.extensions
2
+
3
+ import android.content.res.AssetManager
4
+ import android.graphics.Typeface
5
+ import com.facebook.react.bridge.ReadableMap
6
+ import com.usercentrics.sdk.BannerFont
7
+
8
+
9
+ internal fun ReadableMap.bannerFontFromMap(assetManager: AssetManager): BannerFont? {
10
+ val size = getDoubleOrNull("fontSize") ?: return null
11
+ val regularTypeface = assetManager.createFontFromName(getString("regularFont")) ?: return null
12
+ val boldTypeface = assetManager.createFontFromName(getString("boldFont")) ?: return null
13
+
14
+ return BannerFont(
15
+ regularTypeface,
16
+ boldTypeface,
17
+ size.toFloat()
18
+ )
19
+ }
20
+
21
+ internal fun AssetManager.createFontFromName(fontName: String?): Typeface? {
22
+ if (fontName == null) { return null }
23
+ val fontsFolder = this.list("fonts")
24
+ val regularFontName = fontsFolder?.firstOrNull { it.startsWith(fontName) } ?: return null
25
+ return Typeface.createFromAsset(this, "fonts/$regularFontName")
26
+ }