From 981a9e186c4f502c7f82c4bb88a62a84abe98a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Herculano?= Date: Mon, 16 Jun 2025 09:42:55 +0200 Subject: [PATCH 1/8] feat: change PreferencesSubType from string to enum --- src/NativeReactNativeCmp.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/NativeReactNativeCmp.ts b/src/NativeReactNativeCmp.ts index c6cee5c..d425cad 100644 --- a/src/NativeReactNativeCmp.ts +++ b/src/NativeReactNativeCmp.ts @@ -99,13 +99,14 @@ export type SPAction = { customActionId?: string; }; -export type PreferencesSubType = - | 'AIPolicy' - | 'TermsAndConditions' - | 'PrivacyPolicy' - | 'LegalPolicy' - | 'TermsOfSale' - | 'Unknown'; +export const enum PreferencesSubType { + AIPolicy = 'AIPolicy', + TermsAndConditions = 'TermsAndConditions', + PrivacyPolicy = 'PrivacyPolicy', + LegalPolicy = 'LegalPolicy', + TermsOfSale = 'TermsOfSale', + Unknown = 'Unknown', +} export type PreferencesChannel = { id: number; From 8f60abfa01d415702051cb7b538a534f699602b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Herculano?= Date: Mon, 16 Jun 2025 18:44:50 +0200 Subject: [PATCH 2/8] feat: add groupPmId --- ios/ReactNativeCmp.mm | 6 +++--- src/NativeReactNativeCmp.ts | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ios/ReactNativeCmp.mm b/ios/ReactNativeCmp.mm index 025d2ae..5ca0113 100644 --- a/ios/ReactNativeCmp.mm +++ b/ios/ReactNativeCmp.mm @@ -20,7 +20,7 @@ - (void)build:(double)accountId propertyId:(double)propertyId propertyName:(nonn NSDictionary *targetingParams = (NSDictionary *)gdprCampaign.targetingParams(); gdpr = [[RNSPCampaign alloc] initWithTargetingParams:targetingParams ?: @{} - groupPmId:nil + groupPmId:gdprCampaign.groupPmId() supportLegacyUSPString:false]; } @@ -30,7 +30,7 @@ - (void)build:(double)accountId propertyId:(double)propertyId propertyName:(nonn BOOL legacy = usnatCampaign.supportLegacyUSPString().value_or(false); usnat = [[RNSPCampaign alloc] initWithTargetingParams:targetingParams ?: @{} - groupPmId:nil + groupPmId:usnatCampaign.groupPmId() supportLegacyUSPString:legacy]; } @@ -39,7 +39,7 @@ - (void)build:(double)accountId propertyId:(double)propertyId propertyName:(nonn NSDictionary *targetingParams = (NSDictionary *)preferencesCampaign.targetingParams(); preferences = [[RNSPCampaign alloc] initWithTargetingParams:targetingParams ?: @{} - groupPmId:nil + groupPmId:preferences.groupPmId supportLegacyUSPString:false]; } diff --git a/src/NativeReactNativeCmp.ts b/src/NativeReactNativeCmp.ts index d425cad..3d8b081 100644 --- a/src/NativeReactNativeCmp.ts +++ b/src/NativeReactNativeCmp.ts @@ -3,6 +3,7 @@ import type { TurboModule } from 'react-native'; import type { EventEmitter } from 'react-native/Libraries/Types/CodegenTypes'; export type SPCampaign = { + groupPmId?: string; targetingParams?: { [key: string]: string }; supportLegacyUSPString?: boolean; }; From 5542d7980b27a0964a9a9bb410da6b8fcdbb2090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Herculano?= Date: Mon, 16 Jun 2025 18:45:35 +0200 Subject: [PATCH 3/8] feat: add globalcmp to ts interface --- src/NativeReactNativeCmp.ts | 12 ++++++++++++ src/index.tsx | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/NativeReactNativeCmp.ts b/src/NativeReactNativeCmp.ts index 3d8b081..c8f7495 100644 --- a/src/NativeReactNativeCmp.ts +++ b/src/NativeReactNativeCmp.ts @@ -27,6 +27,7 @@ export type SPCampaigns = { gdpr?: SPCampaign; usnat?: SPCampaign; preferences?: SPCampaign; + globalcmp?: SPCampaign; environment?: SPCampaignEnvironment; }; @@ -85,10 +86,20 @@ export type USNatConsent = { gppData?: { [key: string]: string }; }; +export type GlobalCMPConsent = { + applies: boolean; + uuid?: string; + expirationDate?: string; + createdDate?: string; + vendors: Array; + categories: Array; +}; + export type SPUserData = { gdpr?: GDPRConsent; usnat?: USNatConsent; preferences?: PreferencesConsent; + globalcmp?: GlobalCMPConsent; }; export type LoadMessageParams = { @@ -141,6 +152,7 @@ export interface Spec extends TurboModule { clearLocalData(): void; loadGDPRPrivacyManager(pmId: string): void; loadUSNatPrivacyManager(pmId: string): void; + loadGlobalCmpPrivacyManager(pmId: string): void; readonly onAction: EventEmitter; readonly onSPUIReady: EventEmitter; diff --git a/src/index.tsx b/src/index.tsx index 5b8eb9b..b5a3768 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -40,6 +40,10 @@ export default class SPConsentManager implements Spec { ReactNativeCmp.loadUSNatPrivacyManager(pmId); } + loadGlobalCmpPrivacyManager(pmId: string) { + ReactNativeCmp.loadGlobalCmpPrivacyManager(pmId); + } + onAction: EventEmitter = ReactNativeCmp.onAction; onSPUIReady: EventEmitter = ReactNativeCmp.onSPUIReady; onSPUIFinished: EventEmitter = ReactNativeCmp.onSPUIFinished; From 2a1481d3ad6b634a06503b45cd33c79e100542e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Herculano?= Date: Mon, 16 Jun 2025 18:46:02 +0200 Subject: [PATCH 4/8] feat: implement globalcmp on native iOS --- ios/RNSPUserData/RNSPConsentable.swift | 13 ++++++++++ ios/RNSPUserData/RNSPGlobalCMPConsent.swift | 28 +++++++++++++++++++++ ios/RNSPUserData/RNSPUSNatConsent.swift | 18 +++---------- ios/RNSPUserData/RNSPUserData.swift | 8 ++++-- ios/ReactNativeCmp.mm | 11 ++++++++ ios/Wrappers/RNSPCampaigns.swift | 5 +++- 6 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 ios/RNSPUserData/RNSPConsentable.swift create mode 100644 ios/RNSPUserData/RNSPGlobalCMPConsent.swift diff --git a/ios/RNSPUserData/RNSPConsentable.swift b/ios/RNSPUserData/RNSPConsentable.swift new file mode 100644 index 0000000..dd9700e --- /dev/null +++ b/ios/RNSPUserData/RNSPConsentable.swift @@ -0,0 +1,13 @@ +import ConsentViewController + +struct RNSPConsentable: Encodable { + let id: String + let consented: Bool +} + +extension RNSPConsentable { + init(from consentable: SPConsentable) { + id = consentable.id + consented = consentable.consented + } +} diff --git a/ios/RNSPUserData/RNSPGlobalCMPConsent.swift b/ios/RNSPUserData/RNSPGlobalCMPConsent.swift new file mode 100644 index 0000000..7969349 --- /dev/null +++ b/ios/RNSPUserData/RNSPGlobalCMPConsent.swift @@ -0,0 +1,28 @@ +// +// RNSPGlobalCMPConsent.swift +// sourcepoint-react-native-cmp +// +// Created by Andre Herculano on 22/5/24. +// + +import Foundation +import ConsentViewController + +struct RNSPGlobalCMPConsent: Encodable { + let uuid: String? + let applies: Bool + let vendors, categories: [RNSPConsentable] +} + +extension RNSPGlobalCMPConsent { + init?(from globalCMP: SPGlobalCmpConsent?) { + guard let globalCMP = globalCMP else { return nil } + + self.init( + uuid: globalCMP.uuid, + applies: globalCMP.applies, + vendors: globalCMP.vendors.map { RNSPConsentable(from: $0) }, + categories: globalCMP.categories.map { RNSPConsentable(from: $0) } + ) + } +} diff --git a/ios/RNSPUserData/RNSPUSNatConsent.swift b/ios/RNSPUserData/RNSPUSNatConsent.swift index 07f1d8f..5cf62ed 100644 --- a/ios/RNSPUserData/RNSPUSNatConsent.swift +++ b/ios/RNSPUserData/RNSPUSNatConsent.swift @@ -17,11 +17,6 @@ struct RNSPUSNatConsent: Encodable { sensitiveDataStatus, gpcStatus: Bool? } - struct Consentable: Encodable { - let id: String - let consented: Bool - } - struct ConsentSection: Encodable { let id: Int let name, consentString: String @@ -42,7 +37,7 @@ struct RNSPUSNatConsent: Encodable { let gppData: SPJson? // a list of vendors/categories identified by id, indicating if they are consented or rejected based on the boolean `consented` - let vendors, categories: [Consentable] + let vendors, categories: [RNSPConsentable] } extension RNSPUSNatConsent.Statuses { @@ -57,13 +52,6 @@ extension RNSPUSNatConsent.Statuses { } } -extension RNSPUSNatConsent.Consentable { - init(from consentable: SPConsentable) { - id = consentable.id - consented = consentable.consented - } -} - extension RNSPUSNatConsent.ConsentSection { init(from section: SPUSNatConsent.ConsentString) { id = section.sectionId @@ -83,8 +71,8 @@ extension RNSPUSNatConsent { consentSections: usnat.consentStrings.map { ConsentSection(from: $0) }, statuses: Statuses(from: usnat.statuses), gppData: usnat.GPPData, - vendors: usnat.vendors.map { Consentable(from: $0) }, - categories: usnat.categories.map { Consentable(from: $0) } + vendors: usnat.vendors.map { RNSPConsentable(from: $0) }, + categories: usnat.categories.map { RNSPConsentable(from: $0) } ) } } diff --git a/ios/RNSPUserData/RNSPUserData.swift b/ios/RNSPUserData/RNSPUserData.swift index e9c72ed..6eddb3b 100644 --- a/ios/RNSPUserData/RNSPUserData.swift +++ b/ios/RNSPUserData/RNSPUserData.swift @@ -12,15 +12,18 @@ struct RNSPUserData: Encodable { let gdpr: RNSPGDPRConsent? let usnat: RNSPUSNatConsent? let preferences: RNSPPreferencesConsent? + let globalcmp: RNSPGlobalCMPConsent? init( gdpr: RNSPGDPRConsent? = nil, usnat: RNSPUSNatConsent? = nil, - preferences: RNSPPreferencesConsent? = nil + preferences: RNSPPreferencesConsent? = nil, + globalcmp: RNSPGlobalCMPConsent? = nil ) { self.gdpr = gdpr self.usnat = usnat self.preferences = preferences + self.globalcmp = globalcmp } } @@ -34,7 +37,8 @@ extension RNSPUserData { self.init( gdpr: RNSPGDPRConsent(from: sdkConsents.gdpr?.consents), usnat: RNSPUSNatConsent(from: sdkConsents.usnat?.consents), - preferences: RNSPPreferencesConsent(from: sdkConsents.preferences?.consents) + preferences: RNSPPreferencesConsent(from: sdkConsents.preferences?.consents), + globalcmp: RNSPGlobalCMPConsent(from: sdkConsents.globalcmp?.consents) ) } } diff --git a/ios/ReactNativeCmp.mm b/ios/ReactNativeCmp.mm index 5ca0113..25ab2f3 100644 --- a/ios/ReactNativeCmp.mm +++ b/ios/ReactNativeCmp.mm @@ -14,6 +14,7 @@ - (void)build:(double)accountId propertyId:(double)propertyId propertyName:(nonn RNSPCampaign *gdpr = nil; RNSPCampaign *usnat = nil; RNSPCampaign *preferences = nil; + RNSPCampaign *globalcmp = nil; if (campaigns.gdpr().has_value()) { auto gdprCampaign = campaigns.gdpr().value(); @@ -43,11 +44,21 @@ - (void)build:(double)accountId propertyId:(double)propertyId propertyName:(nonn supportLegacyUSPString:false]; } + if (campaigns.globalcmp().has_value()) { + auto globalCMPCampaign = campaigns.globalcmp().value(); + NSDictionary *targetingParams = (NSDictionary *)globalCMPCampaign.targetingParams(); + + globalcmp = [[RNSPCampaign alloc] initWithTargetingParams:targetingParams ?: @{} + groupPmId:globalCMPCampaign.groupPmId() + supportLegacyUSPString:false]; + } + RNSPCampaigns *internalCampaigns = [[RNSPCampaigns alloc] initWithGdpr: gdpr ccpa:nil usnat:usnat ios14:nil preferences:preferences + globalcmp: globalcmp environment:RNSPCampaignEnvPublic]; [sdk diff --git a/ios/Wrappers/RNSPCampaigns.swift b/ios/Wrappers/RNSPCampaigns.swift index 74a80de..13ef6a4 100644 --- a/ios/Wrappers/RNSPCampaigns.swift +++ b/ios/Wrappers/RNSPCampaigns.swift @@ -38,7 +38,7 @@ import ConsentViewController } @objcMembers public class RNSPCampaigns: NSObject { - @objc public let gdpr, ccpa, usnat, ios14, preferences: RNSPCampaign? + @objc public let gdpr, ccpa, usnat, ios14, preferences, globalcmp: RNSPCampaign? @objc public let environment: RNSPCampaignEnv @objc public init( @@ -47,6 +47,7 @@ import ConsentViewController usnat: RNSPCampaign? = nil, ios14: RNSPCampaign? = nil, preferences: RNSPCampaign? = nil, + globalcmp: RNSPCampaign? = nil, environment: RNSPCampaignEnv = .Public ) { self.gdpr = gdpr @@ -54,6 +55,7 @@ import ConsentViewController self.usnat = usnat self.ios14 = ios14 self.preferences = preferences + self.globalcmp = globalcmp self.environment = environment } @@ -63,6 +65,7 @@ import ConsentViewController ccpa: ccpa?.toSP(), usnat: usnat?.toSP(), ios14: ios14?.toSP(), + globalcmp: globalcmp?.toSP(), preferences: preferences?.toSP(), environment: environment.toSP() ) From 0b8c7ba5092a699115d9c351517020b6a2ea7bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Herculano?= Date: Mon, 16 Jun 2025 18:47:05 +0200 Subject: [PATCH 5/8] feat: implement globalcmp on native Android --- android/build.gradle | 2 +- .../reactnativecmp/RNSourcepointCmpTypes.kt | 11 +++++-- .../reactnativecmp/ReactNativeCmpModule.kt | 19 ++++++----- .../consents/RNSPConsentable.kt | 17 ++++++++++ .../consents/RNSPGlobalCMPConsent.kt | 33 +++++++++++++++++++ .../consents/RNSPUSNatConsent.kt | 23 +++---------- .../reactnativecmp/consents/RNSPUserData.kt | 9 ++--- 7 files changed, 79 insertions(+), 35 deletions(-) create mode 100644 android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPConsentable.kt create mode 100644 android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPGlobalCMPConsent.kt diff --git a/android/build.gradle b/android/build.gradle index 622a223..8dbec58 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath "com.android.tools.build:gradle:8.7.2" + classpath "com.android.tools.build:gradle:8.7.3" // noinspection DifferentKotlinGradleVersion classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}" } diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpTypes.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpTypes.kt index 7a7a89d..b0cf086 100644 --- a/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpTypes.kt +++ b/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpTypes.kt @@ -2,14 +2,15 @@ package com.sourcepoint.reactnativecmp import com.facebook.react.bridge.ReadableMap import com.sourcepoint.cmplibrary.model.CampaignsEnv +import com.sourcepoint.cmplibrary.model.CampaignsEnv.* import com.sourcepoint.cmplibrary.model.exposed.ActionType import com.sourcepoint.cmplibrary.model.exposed.ActionType.* import com.sourcepoint.cmplibrary.model.exposed.TargetingParam fun campaignsEnvFrom(rawValue: String?): CampaignsEnv? = when (rawValue) { - "Public" -> CampaignsEnv.PUBLIC - "Stage" -> CampaignsEnv.STAGE + "Public" -> PUBLIC + "Stage" -> STAGE else -> { null } } @@ -18,13 +19,16 @@ data class SPCampaign( val supportLegacyUSPString: Boolean, val groupPmId: String? = null, ) { - val targetingParams = rawTargetingParam?.toHashMap()?.map { TargetingParam(it.key, it.value.toString()) } ?: emptyList() + val targetingParams = rawTargetingParam?.toHashMap()?.map { + TargetingParam(it.key, it.value.toString()) + } ?: emptyList() } data class SPCampaigns( val gdpr: SPCampaign?, val usnat: SPCampaign?, val preferences: SPCampaign?, + val globalcmp: SPCampaign?, val environment: CampaignsEnv? ) @@ -55,5 +59,6 @@ fun ReadableMap.SPCampaigns() = SPCampaigns( gdpr = this.getMap("gdpr")?.SPCampaign(), usnat = this.getMap("usnat")?.SPCampaign(), preferences = this.getMap("preferences")?.SPCampaign(), + globalcmp = this.getMap("globalcmp")?.SPCampaign(), environment = campaignsEnvFrom(rawValue = this.getString("environment")) ) diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/ReactNativeCmpModule.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/ReactNativeCmpModule.kt index f41be37..bbecf01 100644 --- a/android/src/main/java/com/sourcepoint/reactnativecmp/ReactNativeCmpModule.kt +++ b/android/src/main/java/com/sourcepoint/reactnativecmp/ReactNativeCmpModule.kt @@ -11,10 +11,10 @@ import com.sourcepoint.cmplibrary.NativeMessageController import com.sourcepoint.cmplibrary.SpClient import com.sourcepoint.cmplibrary.SpConsentLib import com.sourcepoint.cmplibrary.core.nativemessage.MessageStructure -import com.sourcepoint.cmplibrary.creation.ConfigOption +import com.sourcepoint.cmplibrary.creation.ConfigOption.SUPPORT_LEGACY_USPSTRING import com.sourcepoint.cmplibrary.creation.SpConfigDataBuilder import com.sourcepoint.cmplibrary.creation.makeConsentLib -import com.sourcepoint.cmplibrary.data.network.util.CampaignType +import com.sourcepoint.cmplibrary.data.network.util.CampaignType.* import com.sourcepoint.cmplibrary.model.ConsentAction import com.sourcepoint.cmplibrary.model.exposed.SPConsents import com.sourcepoint.cmplibrary.util.clearAllData @@ -47,18 +47,21 @@ class ReactNativeCmpModule(reactContext: ReactApplicationContext) : NativeReactN addPropertyId(propertyId.toInt()) addMessageTimeout(30000) convertedCampaigns.gdpr?.let { - addCampaign(campaignType = CampaignType.GDPR, params = it.targetingParams, groupPmId = it.groupPmId) + addCampaign(campaignType = GDPR, params = it.targetingParams, groupPmId = it.groupPmId) } convertedCampaigns.usnat?.let { addCampaign( - campaignType = CampaignType.USNAT, + campaignType = USNAT, params = it.targetingParams, groupPmId = it.groupPmId, - configParams = if(it.supportLegacyUSPString) setOf(ConfigOption.SUPPORT_LEGACY_USPSTRING) else emptySet() + configParams = if(it.supportLegacyUSPString) setOf(SUPPORT_LEGACY_USPSTRING) else emptySet() ) } convertedCampaigns.preferences?.let { - addCampaign(campaignType = CampaignType.PREFERENCES, params = it.targetingParams, groupPmId = it.groupPmId) + addCampaign(campaignType = PREFERENCES, params = it.targetingParams, groupPmId = it.groupPmId) + } + convertedCampaigns.globalcmp?.let { + addCampaign(campaignType = GLOBALCMP, params = it.targetingParams, groupPmId = it.groupPmId) } }.build() @@ -95,12 +98,12 @@ class ReactNativeCmpModule(reactContext: ReactApplicationContext) : NativeReactN @ReactMethod override fun loadGDPRPrivacyManager(pmId: String) { - runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, CampaignType.GDPR) } + runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, GDPR) } } @ReactMethod override fun loadUSNatPrivacyManager(pmId: String) { - runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, CampaignType.USNAT) } + runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, USNAT) } } companion object { diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPConsentable.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPConsentable.kt new file mode 100644 index 0000000..896d085 --- /dev/null +++ b/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPConsentable.kt @@ -0,0 +1,17 @@ +package com.sourcepoint.reactnativecmp.consents + +import com.facebook.react.bridge.Arguments.createMap +import com.facebook.react.bridge.ReadableMap +import com.sourcepoint.cmplibrary.model.exposed.Consentable + +data class RNSPConsentable(override val id: String, override val consented: Boolean): Consentable, RNMappable { + constructor(spConsentable: Consentable): this( + id = spConsentable.id, + consented = spConsentable.consented + ) + + override fun toRN(): ReadableMap = createMap().apply { + putString("id", id) + putBoolean("consented", consented) + } +} diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPGlobalCMPConsent.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPGlobalCMPConsent.kt new file mode 100644 index 0000000..815daa6 --- /dev/null +++ b/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPGlobalCMPConsent.kt @@ -0,0 +1,33 @@ +package com.sourcepoint.reactnativecmp.consents + +import com.facebook.react.bridge.Arguments.createArray +import com.facebook.react.bridge.Arguments.createMap +import com.facebook.react.bridge.ReadableMap +import com.sourcepoint.cmplibrary.model.exposed.GlobalCmpConsent + +data class RNSPGlobalCMPConsent( + val uuid: String?, + val applies: Boolean, + val createdDate: String?, + val expirationDate: String?, + val vendors: List, + val categories: List +): RNMappable { + constructor(globalCMP: GlobalCmpConsent) : this( + uuid = globalCMP.uuid, + applies = globalCMP.applies, + createdDate = globalCMP.dateCreated, + expirationDate = null, + vendors = globalCMP.vendors?.map { RNSPConsentable(it) } ?: emptyList(), + categories = globalCMP.categories?.map { RNSPConsentable(it) } ?: emptyList() + ) + + override fun toRN(): ReadableMap = createMap().apply { + putString("uuid", uuid) + putBoolean("applies", applies) + putString("createdDate", createdDate) + putString("expirationDate", expirationDate) + putArray("vendors", createArray().apply { vendors.forEach { pushMap(it.toRN()) } }) + putArray("categories", createArray().apply { categories.forEach { pushMap(it.toRN()) } }) + } +} diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPUSNatConsent.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPUSNatConsent.kt index 5d084f1..eed9c98 100644 --- a/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPUSNatConsent.kt +++ b/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPUSNatConsent.kt @@ -4,13 +4,10 @@ import com.facebook.react.bridge.Arguments.createArray import com.facebook.react.bridge.Arguments.createMap import com.facebook.react.bridge.ReadableMap import com.sourcepoint.cmplibrary.data.network.model.optimized.USNatConsentData.ConsentString -import com.sourcepoint.cmplibrary.model.exposed.Consentable import com.sourcepoint.cmplibrary.model.exposed.UsNatConsent import com.sourcepoint.cmplibrary.model.exposed.UsNatStatuses import com.sourcepoint.reactnativecmp.arguments.putAny -typealias SPConsentable = Consentable - data class RNSPUSNatConsent( val uuid: String?, val applies: Boolean, @@ -19,8 +16,8 @@ data class RNSPUSNatConsent( val consentSections: List, val statuses: Statuses, val gppData: Map, - val vendors: List, - val categories: List + val vendors: List, + val categories: List ): RNMappable { data class ConsentSection(val id: Int?, val name: String?, val consentString: String?) { constructor(section: ConsentString): this( @@ -66,18 +63,6 @@ data class RNSPUSNatConsent( } } - data class Consentable(override val id: String, override val consented: Boolean): SPConsentable, RNMappable { - constructor(spConsentable: SPConsentable): this( - id = spConsentable.id, - consented = spConsentable.consented - ) - - override fun toRN(): ReadableMap = createMap().apply { - putString("id", id) - putBoolean("consented", consented) - } - } - constructor(usnat: UsNatConsent) : this( uuid = usnat.uuid, applies = usnat.applies, @@ -86,8 +71,8 @@ data class RNSPUSNatConsent( consentSections = usnat.consentStrings?.map { ConsentSection(section = it) } ?: emptyList(), statuses = Statuses(status = usnat.statuses), gppData = usnat.gppData, - vendors = usnat.vendors?.map { Consentable(it) } ?: emptyList(), - categories = usnat.categories?.map { Consentable(it) } ?: emptyList(), + vendors = usnat.vendors?.map { RNSPConsentable(it) } ?: emptyList(), + categories = usnat.categories?.map { RNSPConsentable(it) } ?: emptyList(), ) override fun toRN(): ReadableMap = createMap().apply { diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPUserData.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPUserData.kt index a57bb4c..13eb7ab 100644 --- a/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPUserData.kt +++ b/android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPUserData.kt @@ -1,9 +1,7 @@ package com.sourcepoint.reactnativecmp.consents -import com.facebook.react.bridge.Arguments.createArray import com.facebook.react.bridge.Arguments.createMap import com.facebook.react.bridge.ReadableMap -import com.sourcepoint.cmplibrary.model.exposed.PreferencesConsent import com.sourcepoint.cmplibrary.model.exposed.SPConsents interface RNMappable { @@ -13,17 +11,20 @@ interface RNMappable { data class RNSPUserData( val gdpr: RNSPGDPRConsent?, val usnat: RNSPUSNatConsent?, - val preferences: RNSPPreferencesConsent? + val preferences: RNSPPreferencesConsent?, + val globalCMP: RNSPGlobalCMPConsent? ): RNMappable { constructor(spData: SPConsents): this( gdpr = spData.gdpr?.let { RNSPGDPRConsent(gdpr = it.consent)}, usnat = spData.usNat?.let { RNSPUSNatConsent(usnat = it.consent)}, - preferences = spData.preferences?.let { RNSPPreferencesConsent(preferences = it.consent) } + preferences = spData.preferences?.let { RNSPPreferencesConsent(preferences = it.consent) }, + globalCMP = spData.globalcmp?.let { RNSPGlobalCMPConsent(globalCMP = it.consent) } ) override fun toRN(): ReadableMap = createMap().apply { gdpr?.let { putMap("gdpr", it.toRN()) } usnat?.let { putMap("usnat", it.toRN()) } preferences?.let { putMap("preferences", it.toRN()) } + globalCMP?.let { putMap("globalcmp", it.toRN()) } } } From 7915a37e93a2471dcea1d4cc155b62ee8072516f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Herculano?= Date: Mon, 16 Jun 2025 18:47:36 +0200 Subject: [PATCH 6/8] feat: add globalcmp to example app --- example/src/App.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/example/src/App.tsx b/example/src/App.tsx index 4a1870c..f2cd724 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -33,10 +33,12 @@ const config = { propertyName: 'mobile.multicampaign.demo', gdprPMId: '488393', usnatPMId: '988851', + globalCmpPMId: '', campaigns: { gdpr: {}, usnat: { supportLegacyUSPString: true }, preferences: {}, + // globalcmp: {}, environment: SPCampaignEnvironment.Public, } as SPCampaigns, ...launchArgs?.config, @@ -108,6 +110,11 @@ export default function App() { consentManager.current?.loadUSNatPrivacyManager(config.usnatPMId); }, []); + const onGlobalCMPPress = useCallback(() => { + setSDKStatus(SDKStatus.Networking); + consentManager.current?.loadGlobalCmpPrivacyManager(config.globalCmpPMId); + }, []); + const onClearDataPress = useCallback(() => { consentManager.current?.clearLocalData(); consentManager.current?.build( @@ -146,12 +153,17 @@ export default function App() {