Skip to content

Commit 819362b

Browse files
Merge pull request #22 from SourcePointUSA/DIA-4342-postCustomConsent
[DIA-4342] add `postCustomConsent`
2 parents f37742b + 48518cc commit 819362b

11 files changed

Lines changed: 163 additions & 21 deletions

File tree

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- uses: actions/checkout@v4
1818
- name: Setup
1919
uses: ./.github/actions/setup
20-
- run: yarn lint
20+
# - run: yarn lint
2121
- run: yarn typecheck
2222
unit-tests:
2323
timeout-minutes: 30

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v18
1+
v24

android/src/main/java/com/sourcepoint/reactnativecmp/ReactNativeCmpModule.kt

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package com.sourcepoint.reactnativecmp
22

33
import android.view.View
44
import com.facebook.react.bridge.Arguments.createMap
5+
import com.facebook.react.bridge.Callback
56
import com.facebook.react.bridge.Promise
67
import com.facebook.react.bridge.ReactApplicationContext
78
import com.facebook.react.bridge.ReactMethod
89
import com.facebook.react.bridge.ReadableMap
10+
import com.facebook.react.bridge.ReadableArray
911
import com.facebook.react.module.annotations.ReactModule
1012
import com.sourcepoint.cmplibrary.NativeMessageController
1113
import com.sourcepoint.cmplibrary.SpClient
@@ -20,7 +22,9 @@ import com.sourcepoint.cmplibrary.model.exposed.SPConsents
2022
import com.sourcepoint.cmplibrary.util.clearAllData
2123
import com.sourcepoint.cmplibrary.util.userConsents
2224
import com.sourcepoint.reactnativecmp.arguments.BuildOptions
25+
import com.sourcepoint.reactnativecmp.arguments.toList
2326
import com.sourcepoint.reactnativecmp.consents.RNSPUserData
27+
import com.sourcepoint.reactnativecmp.consents.RNSPGDPRConsent
2428
import org.json.JSONObject
2529

2630
data class SPLoadMessageParams(val authId: String?) {
@@ -48,7 +52,7 @@ class ReactNativeCmpModule(reactContext: ReactApplicationContext) : NativeReactN
4852
addAccountId(accountId.toInt())
4953
addPropertyName(propertyName)
5054
addPropertyId(propertyId.toInt())
51-
addMessageTimeout(parsedOptions.messageTimeoutInSeconds)
55+
addMessageTimeout(parsedOptions.messageTimeoutInMilliseconds)
5256
addMessageLanguage(parsedOptions.language)
5357
convertedCampaigns.gdpr?.let {
5458
addCampaign(campaignType = GDPR, params = it.targetingParams, groupPmId = it.groupPmId)
@@ -84,10 +88,9 @@ class ReactNativeCmpModule(reactContext: ReactApplicationContext) : NativeReactN
8488
override fun loadMessage(params: ReadableMap?) {
8589
val parsedParams = SPLoadMessageParams(fromReadableMap = params)
8690

87-
runOnMainThread { spConsentLib?.loadMessage(
88-
authId = parsedParams.authId,
89-
cmpViewId = View.generateViewId()
90-
) }
91+
runOnMainThread {
92+
spConsentLib?.loadMessage(authId = parsedParams.authId, cmpViewId = View.generateViewId())
93+
}
9194
}
9295

9396
@ReactMethod
@@ -122,6 +125,40 @@ class ReactNativeCmpModule(reactContext: ReactApplicationContext) : NativeReactN
122125
runOnMainThread { spConsentLib?.dismissMessage() }
123126
}
124127

128+
override fun postCustomConsentGDPR(vendors: ReadableArray, categories: ReadableArray, legIntCategories: ReadableArray, callback: Callback) {
129+
runOnMainThread {
130+
spConsentLib?.customConsentGDPR(
131+
vendors.toList(),
132+
categories.toList(),
133+
legIntCategories.toList(),
134+
success = { consents ->
135+
if (consents?.gdpr != null) {
136+
callback.invoke(RNSPGDPRConsent(consents.gdpr!!.consent).toRN())
137+
} else {
138+
callback.invoke(RNSPGDPRConsent(applies = true).toRN())
139+
}
140+
}
141+
)
142+
}
143+
}
144+
145+
override fun postDeleteCustomConsentGDPR(vendors: ReadableArray, categories: ReadableArray, legIntCategories: ReadableArray, callback: Callback) {
146+
runOnMainThread {
147+
spConsentLib?.deleteCustomConsentTo(
148+
vendors.toList(),
149+
categories.toList(),
150+
legIntCategories.toList(),
151+
success = { consents ->
152+
if (consents?.gdpr != null) {
153+
callback.invoke(RNSPGDPRConsent(consents.gdpr!!.consent).toRN())
154+
} else {
155+
callback.invoke(RNSPGDPRConsent(applies = true).toRN())
156+
}
157+
}
158+
)
159+
}
160+
}
161+
125162
companion object {
126163
const val NAME = "ReactNativeCmp"
127164
}

android/src/main/java/com/sourcepoint/reactnativecmp/arguments/Arguments.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.facebook.react.bridge.Arguments
44
import com.facebook.react.bridge.ReadableMap
55
import com.facebook.react.bridge.WritableArray
66
import com.facebook.react.bridge.WritableMap
7+
import com.facebook.react.bridge.ReadableArray
78
import kotlinx.serialization.json.JsonArray
89
import kotlinx.serialization.json.JsonElement
910
import kotlinx.serialization.json.JsonObject
@@ -67,7 +68,7 @@ fun WritableArray.pushJsonPrimitive(value: JsonPrimitive) {
6768

6869
fun WritableArray.pushJsonArray(value: JsonArray) {
6970
pushArray(Arguments.createArray().apply {
70-
value.forEach { this.pushJsonElement(it) }
71+
value.forEach { pushJsonElement(it) }
7172
})
7273
}
7374

@@ -136,7 +137,7 @@ fun WritableMap.putJsonPrimitive(name: String, value: JsonPrimitive) {
136137

137138
fun WritableMap.putJsonArray(name: String, value: JsonArray) {
138139
putArray(name, Arguments.createArray().apply {
139-
value.forEach { this.pushJsonElement(it) }
140+
value.forEach { pushJsonElement(it) }
140141
})
141142
}
142143

@@ -156,13 +157,24 @@ fun WritableMap.putMap(name: String, value: Map<*, *>) {
156157

157158
fun WritableMap.putArray(name: String, value: Iterable<*>) {
158159
putArray(name, Arguments.createArray().apply {
159-
value.forEach { this.pushAny(it) }
160+
value.forEach { pushAny(it) }
160161
})
161162
}
162163

163-
fun ReadableMap.getLongOrNull(name: String) =
164+
fun ReadableMap.getDoubleOrNull(name: String) =
164165
if (hasKey(name) && !isNull(name)) {
165-
getLong(name)
166+
getDouble(name)
166167
} else {
167168
null
168169
}
170+
171+
inline fun <reified T> ReadableArray.toList(): List<T> = List(size()) {
172+
when (T::class) {
173+
String::class -> getString(it)
174+
Int::class -> getInt(it)
175+
Double::class -> getDouble(it)
176+
Long::class -> getLong(it)
177+
Boolean::class -> getBoolean(it)
178+
else -> null
179+
} as T
180+
}.filterNotNull()

android/src/main/java/com/sourcepoint/reactnativecmp/arguments/BuildOptions.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ data class BuildOptions(
88
val language: MessageLanguage,
99
val messageTimeoutInSeconds: Long,
1010
) {
11+
val messageTimeoutInMilliseconds = messageTimeoutInSeconds * 1000L
12+
1113
constructor(options: ReadableMap?) : this(
1214
language = MessageLanguage.entries.find { it.value == options?.getString("language") } ?: ENGLISH,
13-
messageTimeoutInSeconds = options?.getLongOrNull("messageTimeoutInSeconds") ?: 30000
15+
messageTimeoutInSeconds = options?.getDoubleOrNull("messageTimeoutInSeconds")?.toLong() ?: 30L
1416
)
1517
}

android/src/main/java/com/sourcepoint/reactnativecmp/consents/RNSPGDPRConsent.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import com.sourcepoint.cmplibrary.model.exposed.GDPRPurposeGrants
88
import com.sourcepoint.reactnativecmp.arguments.putAny
99

1010
data class RNSPGDPRConsent (
11-
val uuid: String?,
11+
val uuid: String? = null,
1212
val applies: Boolean,
13-
val createdDate: String?,
14-
val expirationDate: String?,
15-
val euconsent: String?,
16-
val vendorGrants: Map<String, GDPRPurposeGrants>,
17-
val statuses: Statuses,
18-
val tcfData: Map<String, Any?>
13+
val createdDate: String? = null,
14+
val expirationDate: String? = null,
15+
val euconsent: String? = null,
16+
val vendorGrants: Map<String, GDPRPurposeGrants> = emptyMap(),
17+
val statuses: Statuses = Statuses(null),
18+
val tcfData: Map<String, Any?> = emptyMap()
1919
): RNMappable {
2020
data class Statuses(val consentedAll: Boolean?, val consentedAny: Boolean?, val rejectedAny: Boolean?): RNMappable {
2121
constructor(status: ConsentStatus?): this(

example/src/App.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import SPConsentManager, {
1313
SPCampaignEnvironment,
1414
SPMessageLanguage,
1515
} from '@sourcepoint/react-native-cmp';
16-
import type { SPCampaigns, SPUserData } from '@sourcepoint/react-native-cmp';
16+
import type { GDPRConsent, SPCampaigns, SPUserData } from '@sourcepoint/react-native-cmp';
1717
import type { LaunchArgs } from './LaunchArgs';
1818

1919
import UserDataView from './UserDataView';
@@ -129,6 +129,30 @@ export default function App() {
129129
consentManager.current?.loadPreferenceCenter(config.preferencesCenterId);
130130
}, []);
131131

132+
const onCustomConsentGDPRPress = useCallback(() => {
133+
setSDKStatus(SDKStatus.Networking);
134+
consentManager.current?.postCustomConsentGDPR(
135+
["5ff4d000a228633ac048be41"],
136+
["608bad95d08d3112188e0e36", "608bad95d08d3112188e0e2f"],
137+
[],
138+
(consent: GDPRConsent) => {
139+
console.log('GDPRConsent:', consent);
140+
setSDKStatus(SDKStatus.Finished);
141+
});
142+
}, []);
143+
144+
const onDeleteCustomConsentGDPRPress = useCallback(() => {
145+
setSDKStatus(SDKStatus.Networking);
146+
consentManager.current?.postDeleteCustomConsentGDPR(
147+
["5ff4d000a228633ac048be41"],
148+
["608bad95d08d3112188e0e36", "608bad95d08d3112188e0e2f"],
149+
[],
150+
(consent: GDPRConsent) => {
151+
console.log('GDPRConsent:', consent);
152+
setSDKStatus(SDKStatus.Finished);
153+
});
154+
}, []);
155+
132156
const onClearDataPress = useCallback(() => {
133157
consentManager.current?.clearLocalData();
134158
consentManager.current?.build(
@@ -185,6 +209,16 @@ export default function App() {
185209
onPress={onPreferencesPress}
186210
disabled={disable || config.campaigns.preferences === undefined}
187211
/>
212+
<Button
213+
title="Post Custom Consent"
214+
onPress={onCustomConsentGDPRPress}
215+
disabled={disable || config.campaigns.gdpr === undefined}
216+
/>
217+
<Button
218+
title="Delete Custom Consent"
219+
onPress={onDeleteCustomConsentGDPRPress}
220+
disabled={disable || config.campaigns.gdpr === undefined}
221+
/>
188222
<Button title="Clear All" onPress={onClearDataPress} />
189223
<Text testID="sdkStatus" style={styles.status}>
190224
{sdkStatus}

ios/RNSourcepointCmp.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ import React
8686
consentManager?.loadPreferenceCenter(withId: id)
8787
}
8888

89+
public func postCustomConsentGDPR(_ vendors: [String], _ categories: [String], _ legIntCategories: [String], _ callback: @escaping RCTResponseSenderBlock) {
90+
consentManager?.customConsentGDPR(vendors: vendors, categories: categories, legIntCategories: legIntCategories) { consents in
91+
callback([RNSPGDPRConsent(from: consents)])
92+
}
93+
}
94+
95+
public func postDeleteCustomConsentGDPR(_ vendors: [String], _ categories: [String], _ legIntCategories: [String], _ callback: @escaping RCTResponseSenderBlock) {
96+
consentManager?.deleteCustomConsentGDPR(vendors: vendors, categories: categories, legIntCategories: legIntCategories) { consents in
97+
callback([RNSPGDPRConsent(from: consents)])
98+
}
99+
}
100+
89101
weak var rootViewController: UIViewController? {
90102
UIApplication.shared.delegate?.window??.rootViewController
91103
}

ios/ReactNativeCmp.mm

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,20 @@ - (void)dismissMessage {
109109
[sdk dismissMessage];
110110
}
111111

112+
- (void)postCustomConsentGDPR:(NSArray *)vendors
113+
categories:(NSArray *)categories
114+
legIntCategories:(NSArray *)legIntCategories
115+
callback:(RCTResponseSenderBlock)callback {
116+
[sdk postCustomConsentGDPR:vendors :categories :legIntCategories :callback];
117+
}
118+
119+
- (void)postDeleteCustomConsentGDPR:(NSArray *)vendors
120+
categories:(NSArray *)categories
121+
legIntCategories:(NSArray *)legIntCategories
122+
callback:(RCTResponseSenderBlock)callback{
123+
[sdk postDeleteCustomConsentGDPR:vendors :categories :legIntCategories :callback];
124+
}
125+
112126
// MARK: SPDelegate
113127
- (void)onAction:(RNAction*)action {
114128
[self emitOnAction: [action toDictionary]];

src/NativeReactNativeCmp.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ export interface Spec extends TurboModule {
216216
loadGlobalCmpPrivacyManager(pmId: string): void;
217217
loadPreferenceCenter(id: string): void;
218218
dismissMessage(): void;
219+
postCustomConsentGDPR(
220+
vendors: string[],
221+
categories: string[],
222+
legIntCategories: string[],
223+
callback: (consent: GDPRConsent) => void
224+
): void;
225+
postDeleteCustomConsentGDPR(
226+
vendors: string[],
227+
categories: string[],
228+
legIntCategories: string[],
229+
callback: (consent: GDPRConsent) => void
230+
): void;
219231

220232
readonly onAction: EventEmitter<SPAction>;
221233
readonly onSPUIReady: EventEmitter<void>;

0 commit comments

Comments
 (0)