Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ useEffect(() => {
config.accountId,
config.propertyId,
config.propertyName,
config.campaigns
config.campaigns,
config.buildOptions
);

return () => {
Expand All @@ -64,6 +65,7 @@ The following attributes should be replaced with your organization's details:
| `config.propertyId` | Number | ID for property found in the Sourcepoint portal |
| `config.propertyName` | String | Name of property found in the Sourcepoint portal |
| `config.campaigns` | Object | Campaigns launched on the property through the Sourcepoint portal. Accepts `gdpr: {}`, `usnat: {}`, `preferences: {}` and `globalcmp: {}`. See table below for information on each campaign type. |
| `config.buildOptions` | Object? | Check `SPBuildOptions` type for more information. |

Refer to the table below regarding the different campaigns that can be implemented:

Expand Down Expand Up @@ -210,7 +212,7 @@ In the example below, you can find a fully configured example in React:

```jsx
import React, { useState, useEffect, useRef } from 'react';
import { View, Text, SafeAreaView } from 'react-native';
import { View, Text, SafeAreaView, SPMessageLanguage } from 'react-native';

import SPConsentManager, { SPCampaignEnvironment, SPUserData } from '@sourcepoint/react-native-cmp';

Expand All @@ -231,6 +233,12 @@ export default function App() {
// usnat: {},
// preferences: {},
// globalcmp: {}
},
{
// in order to override the message language, make sure the option "Use Browser Default"
// is disabled in the Sourcepoint dashboard
language: SPMessageLanguage.ENGLISH,
messageTimeoutInSeconds: 20,
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.sourcepoint.cmplibrary.model.ConsentAction
import com.sourcepoint.cmplibrary.model.exposed.SPConsents
import com.sourcepoint.cmplibrary.util.clearAllData
import com.sourcepoint.cmplibrary.util.userConsents
import com.sourcepoint.reactnativecmp.arguments.BuildOptions
import com.sourcepoint.reactnativecmp.consents.RNSPUserData
import org.json.JSONObject

Expand All @@ -38,14 +39,17 @@ class ReactNativeCmpModule(reactContext: ReactApplicationContext) : NativeReactN
accountId: Double,
propertyId: Double,
propertyName: String,
campaigns: ReadableMap
campaigns: ReadableMap,
options: ReadableMap?,
) {
val convertedCampaigns = campaigns.SPCampaigns()
val parsedOptions = BuildOptions(options)
val config = SpConfigDataBuilder().apply {
addAccountId(accountId.toInt())
addPropertyName(propertyName)
addPropertyId(propertyId.toInt())
addMessageTimeout(30000)
addMessageTimeout(parsedOptions.messageTimeoutInSeconds)
addMessageLanguage(parsedOptions.language)
convertedCampaigns.gdpr?.let {
addCampaign(campaignType = GDPR, params = it.targetingParams, groupPmId = it.groupPmId)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sourcepoint.reactnativecmp.arguments

import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableMap
import kotlinx.serialization.json.JsonArray
Expand Down Expand Up @@ -158,3 +159,10 @@ fun WritableMap.putArray(name: String, value: Iterable<*>) {
value.forEach { this.pushAny(it) }
})
}

fun ReadableMap.getLongOrNull(name: String) =
if (hasKey(name) && !isNull(name)) {
getLong(name)
} else {
null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.sourcepoint.reactnativecmp.arguments

import com.facebook.react.bridge.ReadableMap
import com.sourcepoint.cmplibrary.model.MessageLanguage
import com.sourcepoint.cmplibrary.model.MessageLanguage.ENGLISH

data class BuildOptions(
val language: MessageLanguage,
val messageTimeoutInSeconds: Long,
) {
constructor(options: ReadableMap?) : this(
language = MessageLanguage.entries.find { it.value == options?.getString("language") } ?: ENGLISH,
messageTimeoutInSeconds = options?.getLongOrNull("messageTimeoutInSeconds") ?: 30000
)
}
21 changes: 15 additions & 6 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { LaunchArguments } from 'react-native-launch-arguments';

import SPConsentManager, {
SPCampaignEnvironment,
SPMessageLanguage,
} from '@sourcepoint/react-native-cmp';
import type { SPCampaigns, SPUserData } from '@sourcepoint/react-native-cmp';
import type { LaunchArgs } from './LaunchArgs';
Expand All @@ -31,6 +32,12 @@ const config = {
accountId: 22,
propertyId: 16893,
propertyName: 'mobile.multicampaign.demo',
buildOptions: {
// in order to override the message language, make sure the option "Use Browser Default"
// is disabled in the Sourcepoint dashboard
language: SPMessageLanguage.ENGLISH,
messageTimeoutInSeconds: 20,
},
gdprPMId: '488393',
usnatPMId: '988851',
globalCmpPMId: '1323762',
Expand Down Expand Up @@ -58,7 +65,8 @@ export default function App() {
config.accountId,
config.propertyId,
config.propertyName,
config.campaigns
config.campaigns,
config.buildOptions
);

if (launchArgs.clearData === true) {
Expand Down Expand Up @@ -127,7 +135,8 @@ export default function App() {
config.accountId,
config.propertyId,
config.propertyName,
config.campaigns
config.campaigns,
config.buildOptions
);
setUserData({});
}, []);
Expand Down Expand Up @@ -159,22 +168,22 @@ export default function App() {
<Button
title="Load GDPR PM"
onPress={onGDPRPMPress}
disabled={disable || config.campaigns.gdpr == undefined}
disabled={disable || config.campaigns.gdpr === undefined}
/>
<Button
title="Load USNAT PM"
onPress={onUSNATPMPress}
disabled={disable || config.campaigns.usnat == undefined}
disabled={disable || config.campaigns.usnat === undefined}
/>
<Button
title="Load GlobalCMP PM"
onPress={onGlobalCMPPress}
disabled={disable || config.campaigns.globalcmp == undefined}
disabled={disable || config.campaigns.globalcmp === undefined}
/>
<Button
title="Load Preferences Center"
onPress={onPreferencesPress}
disabled={disable || config.campaigns.preferences == undefined}
disabled={disable || config.campaigns.preferences === undefined}
/>
<Button title="Clear All" onPress={onClearDataPress} />
<Text testID="sdkStatus" style={styles.status}>
Expand Down
6 changes: 5 additions & 1 deletion example/src/LaunchArgs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { SPCampaigns } from '@sourcepoint/react-native-cmp';
import type {
SPCampaigns,
SPBuildOptions

Check failure on line 3 in example/src/LaunchArgs.ts

View workflow job for this annotation

GitHub Actions / lint

Insert `,`
} from '@sourcepoint/react-native-cmp';

export type LaunchArgs = {
config?: {
Expand All @@ -8,6 +11,7 @@
gdprPMId?: string;
usnatPMId?: string;
campaigns?: SPCampaigns;
buildOptions?: SPBuildOptions;
};
authId?: string;
clearData?: boolean;
Expand Down
22 changes: 20 additions & 2 deletions ios/RNSourcepointCmp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import ConsentViewController
import Foundation
import React

@objcMembers public class RNBuildOptions: NSObject {
public let language: String
public let messageTimeout: Int

@objc public init(language: String, messageTimeout: Int) {
self.language = language
self.messageTimeout = messageTimeout
}
}

@objcMembers public class RNAction: NSObject {
public let type: RNSourcepointActionType
public let customActionId: String?
Expand Down Expand Up @@ -80,7 +90,14 @@ import React
UIApplication.shared.delegate?.window??.rootViewController
}

public func build(_ accountId: Int, propertyId: Int, propertyName: String, campaigns: RNSPCampaigns, delegate: ReactNativeCmpImplDelegate?) {
public func build(
accountId: Int,
propertyId: Int,
propertyName: String,
campaigns: RNSPCampaigns,
options: RNBuildOptions,
delegate: ReactNativeCmpImplDelegate?
) {
let manager = SPConsentManager(
accountId: accountId,
propertyId: propertyId,
Expand All @@ -89,7 +106,8 @@ import React
delegate: Self.objcDelegate
)
self.delegate = delegate
manager.messageTimeoutInSeconds = 10
manager.messageLanguage = SPMessageLanguage.init(rawValue: options.language) ?? .English
manager.messageTimeoutInSeconds = TimeInterval(options.messageTimeout)
Self.shared?.consentManager = manager
}

Expand Down
11 changes: 9 additions & 2 deletions ios/ReactNativeCmp.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ @implementation ReactNativeCmp {
}
RCT_EXPORT_MODULE(ReactNativeCmpImpl)

- (void)build:(double)accountId propertyId:(double)propertyId propertyName:(nonnull NSString *)propertyName campaigns:(JS::NativeReactNativeCmp::SPCampaigns &)campaigns {
- (void)build:(double)accountId propertyId:(double)propertyId propertyName:(nonnull NSString *)propertyName campaigns:(JS::NativeReactNativeCmp::SPCampaigns &)campaigns options:(JS::NativeReactNativeCmp::SPBuildOptions &)options {
if (sdk == nil) {
sdk = [[ReactNativeCmpImpl alloc] init];
}
Expand Down Expand Up @@ -61,11 +61,18 @@ - (void)build:(double)accountId propertyId:(double)propertyId propertyName:(nonn
globalcmp: globalcmp
environment:RNSPCampaignEnvPublic];

RNBuildOptions *buildOptions = [
[RNBuildOptions alloc]
initWithLanguage: options.language()
messageTimeout: options.messageTimeoutInSeconds().has_value() ? (NSInteger)options.messageTimeoutInSeconds().value(): 30
];

[sdk
build:(NSInteger)accountId
buildWithAccountId:(NSInteger)accountId
propertyId:(NSInteger)propertyId
propertyName:propertyName
campaigns: internalCampaigns
options: buildOptions
delegate: self
];
}
Expand Down
14 changes: 0 additions & 14 deletions lefthook.yml

This file was deleted.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
"@eslint/compat": "^1.2.7",
"@eslint/eslintrc": "^3.3.0",
"@eslint/js": "^9.22.0",
"@evilmartians/lefthook": "^1.5.0",
"@react-native-community/cli": "15.0.0-alpha.2",
"@react-native/babel-preset": "0.79.2",
"@react-native/eslint-config": "^0.78.0",
Expand Down
62 changes: 61 additions & 1 deletion src/NativeReactNativeCmp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,60 @@
Stage = 'Stage',
}

export const enum SPMessageLanguage {
ALBANIAN = 'sq',
ARABIC = 'ar',
BASQUE = 'eu',
BOSNIAN_LATIN = 'bs',
BULGARIAN = 'bg',
CATALAN = 'ca',
CHINESE_SIMPLIFIED = 'zh',
CHINESE_TRADITIONAL = 'zh-hant',
CROATIAN = 'hr',
CZECH = 'cs',
DANISH = 'da',
DUTCH = 'nl',
ENGLISH = 'en',
ESTONIAN = 'et',
FINNISH = 'fi',
FRENCH = 'fr',
GALICIAN = 'gl',
GEORGIAN = 'ka',
GERMAN = 'de',
GREEK = 'el',
HEBREW = 'he',
HINDI = 'hi',
HUNGARIAN = 'hu',
INDONESIAN = 'id',
ITALIAN = 'it',
JAPANESE = 'ja',
KOREAN = 'ko',
LATVIAN = 'lv',
LITHUANIAN = 'lt',
MACEDONIAN = 'mk',
MALAY = 'ms',
MALTESE = 'mt',
NORWEGIAN = 'no',
POLISH = 'pl',
PORTUGUESE_BRAZIL = 'pt-br',
PORTUGUESE_PORTUGAL = 'pt-pt',
ROMANIAN = 'ro',
RUSSIAN = 'ru',
SERBIAN_CYRILLIC = 'sr-cyrl',
SERBIAN_LATIN = 'sr-latn',
SLOVAK = 'sk',
SLOVENIAN = 'sl',
SPANISH = 'es',
SWAHILI = 'sw',
SWEDISH = 'sv',
TAGALOG = 'tl',
THAI = 'th',
TURKISH = 'tr',
UKRAINIAN = 'uk',
VIETNAMESE = 'vi',
WELSH = 'cy',
}

export const enum SPActionType {
acceptAll = 'acceptAll',
rejectAll = 'rejectAll',
Expand Down Expand Up @@ -141,12 +195,18 @@
rejectedStatus: PreferencesStatus[];
};

export type SPBuildOptions = {
language?: SPMessageLanguage;
messageTimeoutInSeconds?: number;
}

Check failure on line 201 in src/NativeReactNativeCmp.ts

View workflow job for this annotation

GitHub Actions / lint

Insert `;`

export interface Spec extends TurboModule {
build(
accountId: number,
propertyId: number,
propertyName: string,
campaigns: SPCampaigns
campaigns: SPCampaigns,
options?: SPBuildOptions,

Check failure on line 209 in src/NativeReactNativeCmp.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `,`
): void;
getUserData(): Promise<SPUserData>;
loadMessage(params?: LoadMessageParams): void;
Expand Down
13 changes: 10 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,27 @@
SPUserData,
LoadMessageParams,
SPAction,
SPBuildOptions,
} from './NativeReactNativeCmp';
import ReactNativeCmp from './NativeReactNativeCmp';
import ReactNativeCmp, { SPMessageLanguage } from './NativeReactNativeCmp';
import type { EventEmitter } from 'react-native/Libraries/Types/CodegenTypes';

export * from './NativeReactNativeCmp';

const defaultBuildOptions: SPBuildOptions = {
language: SPMessageLanguage.ENGLISH,
messageTimeoutInSeconds: 30,
}

Check failure on line 17 in src/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `;`

export default class SPConsentManager implements Spec {
build(
accountId: number,
propertyId: number,
propertyName: string,
campaigns: SPCampaigns
campaigns: SPCampaigns,
options: SPBuildOptions = defaultBuildOptions,

Check failure on line 25 in src/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Delete `,`
) {
ReactNativeCmp.build(accountId, propertyId, propertyName, campaigns);
ReactNativeCmp.build(accountId, propertyId, propertyName, campaigns, options);

Check failure on line 27 in src/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `accountId,·propertyId,·propertyName,·campaigns,·options` with `⏎······accountId,⏎······propertyId,⏎······propertyName,⏎······campaigns,⏎······options⏎····`
}

getUserData(): Promise<SPUserData> {
Expand Down
Loading
Loading