@usercentrics/react-native-sdk 2.0.4-rc1 → 2.3.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 (59) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +2 -0
  3. package/android/build.gradle +1 -1
  4. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/RNUsercentricsModuleTest.kt +13 -110
  5. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/api/FakeUsercentricsProxy.kt +21 -19
  6. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetCMPDataMock.kt +2 -1
  7. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetConsentsMock.kt +19 -1
  8. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetTCFDataMock.kt +2 -0
  9. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/SaveDecisionsForTCFMock.kt +18 -1
  10. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/SaveDecisionsMock.kt +0 -1
  11. package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/ShowFirstLayerMock.kt +27 -0
  12. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/RNUsercentricsModule.kt +41 -34
  13. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/api/UsercentricsProxy.kt +36 -17
  14. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/BannerFontExtensions.kt +26 -0
  15. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/FirstLayerOptionsExtensions.kt +161 -0
  16. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/TCFDataExtensions.kt +1 -0
  17. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsReadyStatusExtensions.kt +1 -1
  18. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsServiceConsentExtensions.kt +21 -0
  19. package/ios/Extensions/BannerSettings+Dict.swift +227 -0
  20. package/ios/Extensions/ReadyStatus+Dict.swift +1 -1
  21. package/ios/Extensions/TCFData+Dict.swift +2 -1
  22. package/ios/Extensions/UIColor+Extensions.swift +52 -0
  23. package/ios/Extensions/UIImage+UsercentricsLogoDict.swift +14 -0
  24. package/ios/Extensions/UsercentricsCMPData+Dict.swift +1 -1
  25. package/ios/Extensions/UsercentricsServiceConsents+Dict.swift +14 -0
  26. package/ios/Manager/UsercentricsManager.swift +29 -3
  27. package/ios/RNUsercentricsModule.m +8 -0
  28. package/ios/RNUsercentricsModule.swift +61 -34
  29. package/ios/RNUsercentricsModule.xcodeproj/project.pbxproj +12 -4
  30. package/lib/Usercentrics.d.ts +3 -2
  31. package/lib/Usercentrics.js +6 -2
  32. package/lib/Usercentrics.js.map +1 -1
  33. package/lib/models/BannerSettings.d.ts +18 -0
  34. package/lib/models/BannerSettings.js +21 -0
  35. package/lib/models/BannerSettings.js.map +1 -0
  36. package/lib/models/FirstLayerOptions.d.ts +85 -0
  37. package/lib/models/FirstLayerOptions.js +107 -0
  38. package/lib/models/FirstLayerOptions.js.map +1 -0
  39. package/lib/models/SecondLayerOptions.d.ts +6 -0
  40. package/lib/models/SecondLayerOptions.js +7 -0
  41. package/lib/models/SecondLayerOptions.js.map +1 -0
  42. package/lib/models/TCFData.d.ts +9 -8
  43. package/lib/models/TCFData.js +2 -1
  44. package/lib/models/TCFData.js.map +1 -1
  45. package/lib/models/UsercentricsReadyStatus.d.ts +2 -2
  46. package/lib/models/UsercentricsReadyStatus.js +2 -2
  47. package/lib/models/UsercentricsReadyStatus.js.map +1 -1
  48. package/lib/models/UsercentricsServiceConsent.d.ts +9 -1
  49. package/lib/models/UsercentricsServiceConsent.js +10 -1
  50. package/lib/models/UsercentricsServiceConsent.js.map +1 -1
  51. package/lib/models/index.d.ts +3 -1
  52. package/lib/models/index.js +3 -1
  53. package/lib/models/index.js.map +1 -1
  54. package/package.json +2 -2
  55. package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsUserInterfaceExtensions.kt +0 -45
  56. package/ios/Extensions/UsercentricsUISettings+Dict.swift +0 -26
  57. package/lib/models/UsercentricsUIOptions.d.ts +0 -17
  58. package/lib/models/UsercentricsUIOptions.js +0 -20
  59. package/lib/models/UsercentricsUIOptions.js.map +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,58 @@
1
+ [Release Notes](https://docs.usercentrics.com/cmp_in_app_sdk/latest/about/history/)
2
+
3
+ # 2.3.0
4
+
5
+ ## Features
6
+
7
+ - **[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)
8
+ - **[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/)
9
+ - **[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)
10
+ - **[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/).
11
+
12
+ ## Improvements
13
+
14
+ - Updates to TCF 2.0 framework.
15
+
16
+ ## Resolved Issues
17
+
18
+ - Issue with position of logo on Second Layer is now solved.
19
+ - UI/UX improvements and fixes.
20
+
21
+ # 2.2.1
22
+
23
+ ## Features
24
+
25
+ - **[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.
26
+ - Add a Header Image to your banner.
27
+ - Have full control over the layour of your action buttons with Column, Row or Grid configurations.
28
+ - Launch the second layer directly.
29
+ - Landscape Mode support.
30
+ - 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.
31
+ - **[Usability]** Collect consent only at a category level. Option available in your Admin Interface: Configure > Legal Specifications > Settings > Category Consent.
32
+ - **[CNIL]** "Continue wthout Accepting" feature is now supported. (French regulation)
33
+ - **[Fonts]** Admin Interface fonts are now deprecated for App. To enable custom fonts, please inject the font via banner API.
34
+
35
+ ## Improvements
36
+
37
+ - **[API]** Expose user's consent history.
38
+ - **[TCF 2.0]** Adding support to actively inform users when vendors are sharing data outside a region.
39
+ - **[CCPA]** Improve API to facilitate compliance with new Banner API.
40
+
41
+ ## Resolved Issues
42
+ - **[TCF 2.0]** Minor design upgrades to improve usability.
43
+ - **[iOS]** Edge case with RestoreUserSession failing is now solved.
44
+ - **[iOS]** Issue with local and remote images losing quality is now solved.
45
+ - UI/UX improvements and fixes.
46
+
47
+ # 2.0.3
48
+
49
+ - Minor fix on UI related to consent toggles.
50
+ - Corner radius on iOS.
51
+
52
+ # 2.0.2
53
+
54
+ - Custom UI API.
55
+
56
+ # 2.0.1
57
+
58
+ - Initial version of the library.
package/README.md CHANGED
@@ -30,6 +30,8 @@ The Usercentrics Apps SDK is a Consent Management Platform framework for mobile,
30
30
  ### Requirements
31
31
  * Android 5.0 (API 21) or higher with Kotlin 1.5 or higher
32
32
  * iOS 11 or higher
33
+ * React 17.0 or higher
34
+ * React Native 0.65 or higher
33
35
 
34
36
  ## Installation
35
37
 
@@ -1,4 +1,4 @@
1
- def usercentrics_version = "2.0.3"
1
+ def usercentrics_version = "2.3.0"
2
2
  version usercentrics_version
3
3
 
4
4
  buildscript {
@@ -23,7 +23,6 @@ import io.mockk.every
23
23
  import io.mockk.mockk
24
24
  import io.mockk.verify
25
25
  import org.junit.Assert.assertEquals
26
- import org.junit.Assert.assertThrows
27
26
  import org.junit.Before
28
27
  import org.junit.Test
29
28
  import org.junit.runner.RunWith
@@ -39,46 +38,27 @@ class RNUsercentricsModuleTest {
39
38
  putString("version", "1.2.3")
40
39
  }
41
40
 
42
- private val usercentricsReadyStatus = UsercentricsReadyStatus(
43
- shouldShowCMP = false,
44
- consents = listOf(
45
- UsercentricsServiceConsent(
46
- templateId = "ocv9HNX_g",
47
- status = false,
48
- dataProcessor = "Facebook SDK",
49
- type = UsercentricsConsentType.EXPLICIT,
50
- version = "1.0.1"
51
- )
41
+ private val usercentricsConsentHistoryEntries = listOf(
42
+ UsercentricsConsentHistoryEntry(
43
+ status = false,
44
+ UsercentricsConsentType.EXPLICIT,
45
+ 123
52
46
  )
53
47
  )
54
48
 
55
- private val usercentricsUIOptions = JavaOnlyMap().apply {
56
- putBoolean("showCloseButton", false)
57
- putMap("customLogo", JavaOnlyMap().apply {
58
- putString("logoName", "logo.png")
59
- putString(
60
- "logoPath",
61
- "http://10.0.2.2:8081/assets/assets/images/logo.png"
62
- )
63
- })
64
- putMap("customFont", JavaOnlyMap().apply {
65
- putString("fontName", "Lora")
66
- putInt("fontSize", 14)
67
- })
68
- }
69
-
70
- private val usercentricsConsentUserResponse = UsercentricsConsentUserResponse(
49
+ private val usercentricsReadyStatus = UsercentricsReadyStatus(
50
+ shouldCollectConsent = false,
71
51
  consents = listOf(
72
52
  UsercentricsServiceConsent(
73
53
  templateId = "ocv9HNX_g",
74
54
  status = false,
75
55
  dataProcessor = "Facebook SDK",
76
56
  type = UsercentricsConsentType.EXPLICIT,
77
- version = "1.0.1"
57
+ version = "1.0.1",
58
+ isEssential = false,
59
+ history = usercentricsConsentHistoryEntries
78
60
  )
79
- ),
80
- controllerId = "8620135313b043696b806868b20da905886a3a2598ddddc2b52973f9807d6b45",
81
- userInteraction = UsercentricsUserInteraction.ACCEPT_ALL
61
+ )
82
62
  )
83
63
  }
84
64
 
@@ -139,7 +119,7 @@ class RNUsercentricsModuleTest {
139
119
  val consent = result.getArray("consents")?.getMap(0)!!
140
120
 
141
121
  assertEquals(1, usercentricsProxy.isReadyCount)
142
- assertEquals(false, result.getBoolean("shouldShowCMP"))
122
+ assertEquals(false, result.getBoolean("shouldCollectConsent"))
143
123
  assertEquals(false, consent.getBoolean("status"))
144
124
  assertEquals("ocv9HNX_g", consent.getString("templateId"))
145
125
  assertEquals("Facebook SDK", consent.getString("dataProcessor"))
@@ -182,7 +162,7 @@ class RNUsercentricsModuleTest {
182
162
  val result = promise.resolveValue as WritableMap
183
163
  val consent = result.getArray("consents")?.getMap(0)!!
184
164
 
185
- assertEquals(false, result.getBoolean("shouldShowCMP"))
165
+ assertEquals(false, result.getBoolean("shouldCollectConsent"))
186
166
  assertEquals(false, consent.getBoolean("status"))
187
167
  assertEquals("ocv9HNX_g", consent.getString("templateId"))
188
168
  assertEquals("Facebook SDK", consent.getString("dataProcessor"))
@@ -239,83 +219,6 @@ class RNUsercentricsModuleTest {
239
219
  assertEquals("abc", promise.resolveValue)
240
220
  }
241
221
 
242
- @Test
243
- fun testShowCMP() {
244
- val usercentricsProxy = FakeUsercentricsProxy()
245
- usercentricsProxy.createIntentValue = mockk(relaxed = true)
246
-
247
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
248
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
249
- val promise = FakePromise()
250
-
251
- module.showCMP(usercentricsUIOptions, promise)
252
-
253
- val responseUsercentricsOptions = usercentricsProxy.usercentricsOptions!!
254
- val customLogoURL =
255
- (responseUsercentricsOptions.customLogo as UsercentricsImage.ImageUrl).imageUrl
256
-
257
- assertEquals(false, responseUsercentricsOptions.showCloseButton)
258
- assertEquals(
259
- "http://10.0.2.2:8081/assets/assets/images/logo.png",
260
- customLogoURL
261
- )
262
- }
263
-
264
- @Test
265
- fun testOnActivityResultWithOtherCode() {
266
- val usercentricsProxy = FakeUsercentricsProxy()
267
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
268
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
269
-
270
- val otherRequestCode = 123
271
- val consumed = module.parseActivityResult(otherRequestCode, 123, null)
272
-
273
- assertEquals(false, consumed)
274
- }
275
-
276
- @Test
277
- fun testOnActivityResultWithNoPendingResult() {
278
- val usercentricsProxy = FakeUsercentricsProxy()
279
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
280
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
281
-
282
- assertThrows(AssertionError::class.java) {
283
- module.parseActivityResult(81420, 123, null)
284
- }
285
- }
286
-
287
- @Test
288
- fun testOnActivityResultWithPendingResult() {
289
- val resultCode = 123
290
- val usercentricsProxy = FakeUsercentricsProxy()
291
- usercentricsProxy.createIntentValue = mockk(relaxed = true)
292
- usercentricsProxy.parseResultValue = usercentricsConsentUserResponse
293
-
294
- val contextMock = mockk<ReactApplicationContext>(relaxed = true)
295
- val module = RNUsercentricsModule(contextMock, usercentricsProxy)
296
-
297
- val promise = FakePromise()
298
- module.showCMP(usercentricsUIOptions, promise)
299
-
300
- module.parseActivityResult(81420, resultCode, null)
301
-
302
- assertEquals(resultCode, usercentricsProxy.parseResultResultCodeArgument)
303
-
304
- val result = promise.resolveValue as WritableMap
305
- val consent = result.getArray("consents")?.getMap(0)!!
306
-
307
- assertEquals(
308
- "8620135313b043696b806868b20da905886a3a2598ddddc2b52973f9807d6b45",
309
- result.getString("controllerId")
310
- )
311
- assertEquals(0, result.getInt("userInteraction"))
312
- assertEquals(false, consent.getBoolean("status"))
313
- assertEquals("ocv9HNX_g", consent.getString("templateId"))
314
- assertEquals("Facebook SDK", consent.getString("dataProcessor"))
315
- assertEquals(0, consent.getInt("type"))
316
- assertEquals("1.0.1", consent.getString("version"))
317
- }
318
-
319
222
  @Test
320
223
  fun testGetConsents() {
321
224
  val usercentricsSDK = mockk<UsercentricsSDK>()
@@ -1,11 +1,13 @@
1
1
  package com.usercentrics.reactnativemodule.api
2
2
 
3
+ import android.app.Activity
3
4
  import android.content.Context
4
5
  import android.content.Intent
6
+ import com.facebook.react.bridge.Promise
7
+ import com.facebook.react.bridge.ReadableMap
5
8
  import com.usercentrics.reactnativeusercentrics.api.UsercentricsProxy
6
9
  import com.usercentrics.sdk.*
7
10
  import com.usercentrics.sdk.errors.UsercentricsError
8
- import com.usercentrics.sdk.models.settings.UsercentricsConsent
9
11
 
10
12
  internal class FakeUsercentricsProxy(
11
13
  private val instanceAnswer: UsercentricsSDK? = null,
@@ -40,30 +42,30 @@ internal class FakeUsercentricsProxy(
40
42
  }
41
43
  }
42
44
 
43
- var createIntentValue: Intent? = null
44
- var usercentricsOptions: UsercentricsUISettings? = null
45
+ var resetCount: Int = 0
45
46
  private set
46
47
 
47
- override fun createIntent(
48
- context: Context,
49
- usercentricsOptions: UsercentricsUISettings
50
- ): Intent {
51
- this.usercentricsOptions = usercentricsOptions
52
- return createIntentValue!!
48
+ override fun reset() {
49
+ resetCount++
53
50
  }
54
51
 
55
- var parseResultResultCodeArgument: Int = 0
56
- private set
57
- var parseResultValue: UsercentricsConsentUserResponse? = null
58
- override fun parseResult(resultCode: Int, data: Intent?): UsercentricsConsentUserResponse? {
59
- this.parseResultResultCodeArgument = resultCode
60
- return parseResultValue
52
+ var showFirstLayerLayout: UsercentricsLayout? = null
53
+ var showFirstLayerBannerSettings: BannerSettings? = null
54
+ var showFirstLayerStyle: FirstLayerStyleSettings? = null
55
+
56
+ override fun showFirstLayer(
57
+ activity: Activity,
58
+ layout: UsercentricsLayout,
59
+ bannerSettings: BannerSettings?,
60
+ firstLayerStyleSettings: FirstLayerStyleSettings?,
61
+ promise: Promise
62
+ ) {
63
+ this.showFirstLayerLayout = layout
64
+ this.showFirstLayerBannerSettings = bannerSettings
65
+ this.showFirstLayerStyle = firstLayerStyleSettings
61
66
  }
62
67
 
63
- var resetCount: Int = 0
64
- private set
68
+ override fun showSecondLayer() {
65
69
 
66
- override fun reset() {
67
- resetCount++
68
70
  }
69
71
  }
@@ -228,7 +228,8 @@ internal class GetCMPDataMock {
228
228
  hideButtonDeny = false,
229
229
  tabsServicesIsEnabled = true,
230
230
  isOverlayEnabled = true,
231
- title = ""
231
+ title = "",
232
+ hideTogglesForServices = false
232
233
  )
233
234
  private val fakeTCF2Settings = TCF2Settings(
234
235
  togglesSpecialFeaturesToggleOff = "Off",
@@ -1,17 +1,27 @@
1
1
  package com.usercentrics.reactnativemodule.mock
2
2
 
3
+ import com.usercentrics.sdk.UsercentricsConsentHistoryEntry
3
4
  import com.usercentrics.sdk.UsercentricsServiceConsent
4
5
  import com.usercentrics.sdk.models.settings.UsercentricsConsentType
5
6
 
6
7
  internal class GetConsentsMock {
7
8
  companion object {
9
+
8
10
  val fakeWithData = listOf(
9
11
  UsercentricsServiceConsent(
10
12
  templateId = "ocv9HNX_g",
11
13
  status = false,
12
14
  dataProcessor = "Facebook SDK",
13
15
  type = UsercentricsConsentType.EXPLICIT,
14
- version = "1.0.1"
16
+ version = "1.0.1",
17
+ history = listOf(
18
+ UsercentricsConsentHistoryEntry(
19
+ status = false,
20
+ UsercentricsConsentType.EXPLICIT,
21
+ 123
22
+ )
23
+ ),
24
+ isEssential = false
15
25
  )
16
26
  )
17
27
 
@@ -22,6 +32,14 @@ internal class GetConsentsMock {
22
32
  "type" to 0,
23
33
  "version" to "1.0.1",
24
34
  "dataProcessor" to "Facebook SDK",
35
+ "isEssential" to false,
36
+ "history" to listOf(
37
+ mapOf(
38
+ "timestampInMillis" to 123,
39
+ "type" to 0,
40
+ "status" to false
41
+ )
42
+ )
25
43
  )
26
44
  )
27
45
  }
@@ -92,6 +92,7 @@ internal class GetTCFDataMock {
92
92
  deviceStorage = null,
93
93
  usesCookies = false,
94
94
  cookieRefresh = null,
95
+ dataSharedOutsideEU = false
95
96
  )
96
97
  ),
97
98
  )
@@ -182,6 +183,7 @@ internal class GetTCFDataMock {
182
183
  "deviceStorageDisclosureUrl" to null,
183
184
  "usesCookies" to false,
184
185
  "cookieRefresh" to null,
186
+ "dataSharedOutsideEU" to false
185
187
  ),
186
188
  ),
187
189
  )
@@ -2,6 +2,7 @@ package com.usercentrics.reactnativemodule.mock
2
2
 
3
3
  import com.usercentrics.reactnativeusercentrics.extensions.toWritableMap
4
4
  import com.usercentrics.sdk.UserDecision
5
+ import com.usercentrics.sdk.UsercentricsConsentHistoryEntry
5
6
  import com.usercentrics.sdk.UsercentricsServiceConsent
6
7
  import com.usercentrics.sdk.models.settings.UsercentricsConsentType
7
8
  import com.usercentrics.sdk.services.tcf.TCFDecisionUILayer
@@ -18,7 +19,15 @@ internal class SaveDecisionsForTCFMock {
18
19
  status = true,
19
20
  dataProcessor = "Facebook SDK",
20
21
  type = UsercentricsConsentType.EXPLICIT,
21
- version = "1.0.1"
22
+ version = "1.0.1",
23
+ history = listOf(
24
+ UsercentricsConsentHistoryEntry(
25
+ status = false,
26
+ UsercentricsConsentType.EXPLICIT,
27
+ 123
28
+ )
29
+ ),
30
+ isEssential = false
22
31
  )
23
32
  )
24
33
 
@@ -62,6 +71,14 @@ internal class SaveDecisionsForTCFMock {
62
71
  "type" to 0,
63
72
  "version" to "1.0.1",
64
73
  "dataProcessor" to "Facebook SDK",
74
+ "isEssential" to false,
75
+ "history" to listOf(
76
+ mapOf(
77
+ "timestampInMillis" to 123,
78
+ "type" to 0,
79
+ "status" to false
80
+ )
81
+ )
65
82
  )
66
83
  )
67
84
  }
@@ -2,7 +2,6 @@ package com.usercentrics.reactnativemodule.mock
2
2
 
3
3
  import com.usercentrics.sdk.UserDecision
4
4
 
5
-
6
5
  internal class SaveDecisionsMock {
7
6
  companion object {
8
7
  val callDecisions = listOf(
@@ -0,0 +1,27 @@
1
+ package com.usercentrics.reactnativemodule.mock
2
+
3
+ import com.usercentrics.reactnativeusercentrics.extensions.toWritableMap
4
+
5
+ internal class ShowFirstLayerMock {
6
+ companion object {
7
+ val arguments = mapOf(
8
+ "layout" to "POPUP_CENTER",
9
+ "bannerSettings" to mapOf(
10
+ "font" to null,
11
+ "logo" to null,
12
+ ),
13
+ "styleSettings" to mapOf(
14
+ "headerImage" to null,
15
+ "title" to mapOf(
16
+ "alignment" to "END",
17
+ "textSize" to 20.0,
18
+ ),
19
+ "message" to mapOf(
20
+ "alignment" to "CENTER",
21
+ "textSize" to 16,
22
+ ),
23
+ "cornerRadius" to 50
24
+ ),
25
+ ).toWritableMap()
26
+ }
27
+ }
@@ -1,10 +1,9 @@
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.*
6
+ import com.usercentrics.sdk.UsercentricsBanner
8
7
  import com.usercentrics.sdk.models.settings.UsercentricsConsentType
9
8
  import com.usercentrics.sdk.services.tcf.TCFDecisionUILayer
10
9
 
@@ -16,26 +15,6 @@ internal class RNUsercentricsModule(
16
15
 
17
16
  override fun getName() = "RNUsercentricsModule"
18
17
 
19
- private var pendingPromise: Promise? = null
20
- private val listener: ActivityEventListener = object : BaseActivityEventListener() {
21
- override fun onActivityResult(
22
- activity: Activity?,
23
- requestCode: Int,
24
- resultCode: Int,
25
- data: Intent?
26
- ) {
27
- parseActivityResult(requestCode, resultCode, data)
28
- }
29
- }
30
-
31
- init {
32
- reactApplicationContext.addActivityEventListener(listener)
33
- }
34
-
35
- companion object {
36
- private const val showCMPRequestCode = 81420
37
- }
38
-
39
18
  @ReactMethod
40
19
  fun configure(options: ReadableMap) {
41
20
  var alreadyConfigured = false
@@ -61,24 +40,52 @@ internal class RNUsercentricsModule(
61
40
  }
62
41
 
63
42
  @ReactMethod
64
- fun showCMP(options: ReadableMap, promise: Promise) {
65
- val usercentricsOptions = options.usercentricsUISettingsFromMap(currentActivity!!.assets)
66
- this.pendingPromise = promise
43
+ fun showFirstLayer(options: ReadableMap, promise: Promise) {
44
+ UiThreadUtil.runOnUiThread {
45
+ try {
46
+ val assetManager = currentActivity!!.assets
67
47
 
68
- val intent = usercentricsProxy.createIntent(reactApplicationContext, usercentricsOptions)
69
- currentActivity?.startActivityForResult(intent, showCMPRequestCode)
48
+ val layout = options.getString("layout")!!.usercentricsLayoutFromEnumString()
49
+ val bannerSettings =
50
+ options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
51
+ val styleSettings =
52
+ options.getMap("styleSettings")?.firstLayerStyleSettingsFromMap(assetManager)
53
+
54
+ usercentricsProxy.showFirstLayer(
55
+ currentActivity!!,
56
+ layout,
57
+ bannerSettings,
58
+ styleSettings,
59
+ promise
60
+ )
61
+
62
+ } catch (e: Exception) {
63
+ promise.reject(e)
64
+ }
65
+ }
70
66
  }
71
67
 
72
- internal fun parseActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
73
- if (requestCode != showCMPRequestCode) return false
74
- assert(pendingPromise != null)
68
+ @ReactMethod
69
+ fun showSecondLayer(options: ReadableMap, promise: Promise) {
70
+ UiThreadUtil.runOnUiThread {
71
+ try {
72
+ val assetManager = currentActivity!!.assets
73
+
74
+ val bannerSettings =
75
+ options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
76
+ val showCloseButton = options.getBoolean("showCloseButton")
75
77
 
76
- val response = usercentricsProxy.parseResult(resultCode, data)?.toWritableMap()
77
78
 
78
- pendingPromise?.resolve(response)
79
- pendingPromise = null
79
+ UsercentricsBanner(currentActivity!!, bannerSettings).showSecondLayer(
80
+ showCloseButton
81
+ ) {
82
+ promise.resolve(it?.toWritableMap())
83
+ }
80
84
 
81
- return true
85
+ } catch (e: Exception) {
86
+ promise.reject(e)
87
+ }
88
+ }
82
89
  }
83
90
 
84
91
  @ReactMethod
@@ -1,10 +1,18 @@
1
1
  package com.usercentrics.reactnativeusercentrics.api
2
2
 
3
+ import android.app.Activity
3
4
  import android.content.Context
4
5
  import android.content.Intent
5
6
  import android.util.Log
7
+ 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
+ import com.usercentrics.reactnativeusercentrics.extensions.toWritableMap
12
+ import com.usercentrics.reactnativeusercentrics.extensions.usercentricsLayoutFromEnumString
6
13
  import com.usercentrics.sdk.*
7
14
  import com.usercentrics.sdk.errors.UsercentricsError
15
+ import java.lang.Exception
8
16
 
9
17
  interface UsercentricsProxy {
10
18
  val instance: UsercentricsSDK
@@ -16,12 +24,15 @@ interface UsercentricsProxy {
16
24
  onFailure: (UsercentricsError) -> Unit
17
25
  )
18
26
 
19
- fun createIntent(
20
- context: Context,
21
- usercentricsOptions: UsercentricsUISettings
22
- ): Intent
27
+ fun showFirstLayer(
28
+ activity: Activity,
29
+ layout: UsercentricsLayout,
30
+ bannerSettings: BannerSettings?,
31
+ firstLayerStyleSettings: FirstLayerStyleSettings?,
32
+ promise: Promise
33
+ )
23
34
 
24
- fun parseResult(resultCode: Int, data: Intent?): UsercentricsConsentUserResponse?
35
+ fun showSecondLayer()
25
36
 
26
37
  fun reset()
27
38
  }
@@ -32,7 +43,11 @@ internal class UsercentricsProxyImpl : UsercentricsProxy {
32
43
  get() = Usercentrics.instance
33
44
 
34
45
  override fun initialize(context: Context, options: UsercentricsOptions) {
35
- Usercentrics.initialize(context, options)
46
+ try {
47
+ Usercentrics.initialize(context, options)
48
+ } catch (e: Exception) {
49
+ e.printStackTrace()
50
+ }
36
51
  }
37
52
 
38
53
  override fun isReady(
@@ -40,19 +55,23 @@ internal class UsercentricsProxyImpl : UsercentricsProxy {
40
55
  onFailure: (UsercentricsError) -> Unit
41
56
  ) = Usercentrics.isReady(onSuccess, onFailure)
42
57
 
43
- override fun createIntent(
44
- context: Context,
45
- usercentricsOptions: UsercentricsUISettings
46
- ): Intent {
47
- return UsercentricsActivityContract().createIntent(
48
- context,
49
- usercentricsOptions
50
- )
58
+ override fun showFirstLayer(
59
+ activity: Activity,
60
+ layout: UsercentricsLayout,
61
+ bannerSettings: BannerSettings?,
62
+ firstLayerStyleSettings: FirstLayerStyleSettings?,
63
+ promise: Promise
64
+ ) {
65
+ UsercentricsBanner(activity, bannerSettings).showFirstLayer(
66
+ layout,
67
+ firstLayerStyleSettings
68
+ ) {
69
+ promise.resolve(it?.toWritableMap())
70
+ }
51
71
  }
52
72
 
53
- override fun parseResult(resultCode: Int, data: Intent?): UsercentricsConsentUserResponse? {
54
- return UsercentricsActivityContract()
55
- .parseResult(resultCode, data)
73
+ override fun showSecondLayer() {
74
+
56
75
  }
57
76
 
58
77
  override fun reset() = Usercentrics.reset()
@@ -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
+ }