@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.
- package/CHANGELOG.md +58 -0
- package/README.md +2 -0
- package/android/build.gradle +1 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/RNUsercentricsModuleTest.kt +13 -110
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/api/FakeUsercentricsProxy.kt +21 -19
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetCMPDataMock.kt +2 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetConsentsMock.kt +19 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetTCFDataMock.kt +2 -0
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/SaveDecisionsForTCFMock.kt +18 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/SaveDecisionsMock.kt +0 -1
- package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/ShowFirstLayerMock.kt +27 -0
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/RNUsercentricsModule.kt +41 -34
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/api/UsercentricsProxy.kt +36 -17
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/BannerFontExtensions.kt +26 -0
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/FirstLayerOptionsExtensions.kt +161 -0
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/TCFDataExtensions.kt +1 -0
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsReadyStatusExtensions.kt +1 -1
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsServiceConsentExtensions.kt +21 -0
- package/ios/Extensions/BannerSettings+Dict.swift +227 -0
- package/ios/Extensions/ReadyStatus+Dict.swift +1 -1
- package/ios/Extensions/TCFData+Dict.swift +2 -1
- package/ios/Extensions/UIColor+Extensions.swift +52 -0
- package/ios/Extensions/UIImage+UsercentricsLogoDict.swift +14 -0
- package/ios/Extensions/UsercentricsCMPData+Dict.swift +1 -1
- package/ios/Extensions/UsercentricsServiceConsents+Dict.swift +14 -0
- package/ios/Manager/UsercentricsManager.swift +29 -3
- package/ios/RNUsercentricsModule.m +8 -0
- package/ios/RNUsercentricsModule.swift +61 -34
- package/ios/RNUsercentricsModule.xcodeproj/project.pbxproj +12 -4
- package/lib/Usercentrics.d.ts +3 -2
- package/lib/Usercentrics.js +6 -2
- package/lib/Usercentrics.js.map +1 -1
- package/lib/models/BannerSettings.d.ts +18 -0
- package/lib/models/BannerSettings.js +21 -0
- package/lib/models/BannerSettings.js.map +1 -0
- package/lib/models/FirstLayerOptions.d.ts +85 -0
- package/lib/models/FirstLayerOptions.js +107 -0
- package/lib/models/FirstLayerOptions.js.map +1 -0
- package/lib/models/SecondLayerOptions.d.ts +6 -0
- package/lib/models/SecondLayerOptions.js +7 -0
- package/lib/models/SecondLayerOptions.js.map +1 -0
- package/lib/models/TCFData.d.ts +9 -8
- package/lib/models/TCFData.js +2 -1
- package/lib/models/TCFData.js.map +1 -1
- package/lib/models/UsercentricsReadyStatus.d.ts +2 -2
- package/lib/models/UsercentricsReadyStatus.js +2 -2
- package/lib/models/UsercentricsReadyStatus.js.map +1 -1
- package/lib/models/UsercentricsServiceConsent.d.ts +9 -1
- package/lib/models/UsercentricsServiceConsent.js +10 -1
- package/lib/models/UsercentricsServiceConsent.js.map +1 -1
- package/lib/models/index.d.ts +3 -1
- package/lib/models/index.js +3 -1
- package/lib/models/index.js.map +1 -1
- package/package.json +2 -2
- package/android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/UsercentricsUserInterfaceExtensions.kt +0 -45
- package/ios/Extensions/UsercentricsUISettings+Dict.swift +0 -26
- package/lib/models/UsercentricsUIOptions.d.ts +0 -17
- package/lib/models/UsercentricsUIOptions.js +0 -20
- 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
|
|
package/android/build.gradle
CHANGED
package/android/src/androidTest/java/com/usercentrics/reactnativemodule/RNUsercentricsModuleTest.kt
CHANGED
|
@@ -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
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
|
56
|
-
|
|
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("
|
|
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("
|
|
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>()
|
package/android/src/androidTest/java/com/usercentrics/reactnativemodule/api/FakeUsercentricsProxy.kt
CHANGED
|
@@ -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
|
|
44
|
-
var usercentricsOptions: UsercentricsUISettings? = null
|
|
45
|
+
var resetCount: Int = 0
|
|
45
46
|
private set
|
|
46
47
|
|
|
47
|
-
override fun
|
|
48
|
-
|
|
49
|
-
usercentricsOptions: UsercentricsUISettings
|
|
50
|
-
): Intent {
|
|
51
|
-
this.usercentricsOptions = usercentricsOptions
|
|
52
|
-
return createIntentValue!!
|
|
48
|
+
override fun reset() {
|
|
49
|
+
resetCount++
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
var
|
|
56
|
-
|
|
57
|
-
var
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
64
|
-
private set
|
|
68
|
+
override fun showSecondLayer() {
|
|
65
69
|
|
|
66
|
-
override fun reset() {
|
|
67
|
-
resetCount++
|
|
68
70
|
}
|
|
69
71
|
}
|
package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetCMPDataMock.kt
CHANGED
|
@@ -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",
|
package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetConsentsMock.kt
CHANGED
|
@@ -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
|
}
|
package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/GetTCFDataMock.kt
CHANGED
|
@@ -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
|
}
|
package/android/src/androidTest/java/com/usercentrics/reactnativemodule/mock/ShowFirstLayerMock.kt
ADDED
|
@@ -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
|
+
}
|
package/android/src/main/java/com/usercentrics/reactnativeusercentrics/RNUsercentricsModule.kt
CHANGED
|
@@ -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
|
|
65
|
-
|
|
66
|
-
|
|
43
|
+
fun showFirstLayer(options: ReadableMap, promise: Promise) {
|
|
44
|
+
UiThreadUtil.runOnUiThread {
|
|
45
|
+
try {
|
|
46
|
+
val assetManager = currentActivity!!.assets
|
|
67
47
|
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
79
|
-
|
|
79
|
+
UsercentricsBanner(currentActivity!!, bannerSettings).showSecondLayer(
|
|
80
|
+
showCloseButton
|
|
81
|
+
) {
|
|
82
|
+
promise.resolve(it?.toWritableMap())
|
|
83
|
+
}
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
} catch (e: Exception) {
|
|
86
|
+
promise.reject(e)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
@ReactMethod
|
package/android/src/main/java/com/usercentrics/reactnativeusercentrics/api/UsercentricsProxy.kt
CHANGED
|
@@ -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
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
fun showFirstLayer(
|
|
28
|
+
activity: Activity,
|
|
29
|
+
layout: UsercentricsLayout,
|
|
30
|
+
bannerSettings: BannerSettings?,
|
|
31
|
+
firstLayerStyleSettings: FirstLayerStyleSettings?,
|
|
32
|
+
promise: Promise
|
|
33
|
+
)
|
|
23
34
|
|
|
24
|
-
fun
|
|
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
|
-
|
|
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
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
54
|
-
|
|
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
|
+
}
|