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
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Didomi_kotlinVersion=2.1.20

Didomi_buildToolsVersion=36.0.0
Didomi_compileSdkVersion=36
Didomi_minSdkVersion=21
Didomi_minSdkVersion=24
Didomi_targetSdkVersion=36
6 changes: 3 additions & 3 deletions ios/RNDidomi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ class RNDidomi: RCTEventEmitter {
@objc(getText:resolve:reject:)
dynamic func getText(key: String, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) {
let text = Didomi.shared.getText(key: key)
resolve(text)
resolve(text ?? [:])
}

@objc(setLogLevel:resolve:reject:)
Expand Down Expand Up @@ -919,8 +919,8 @@ extension RNDidomi {
let callbackIndex = self?.syncAcknowledgedCallbackIndex ?? -1
self?.syncAcknowledgedCallbackIndex += 1
self?.syncAcknowledgedCallbacks[callbackIndex] = event.syncAcknowledged
let result = [
"organizationUserId": event.organizationUserId,
let result: [String: Any] = [
"organizationUserId": event.organizationUserId as Any,
"statusApplied": event.statusApplied,
"syncAcknowledgedIndex": callbackIndex
]
Expand Down
86 changes: 38 additions & 48 deletions sample/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useCallback } from 'react';

import { ScrollView, StyleSheet, Text, View } from 'react-native';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
Expand All @@ -7,28 +7,28 @@ import Methods from './Methods';
import Getters from './Getters';
import Setters from './Setters';
import { TestEvent } from './Types';
import ErrorBoundary from './ErrorBoundary';

function App() {
const MAX_EVENTS_DISPLAYED = 3;

const [receivedEvents, setReceivedEvents] = useState<TestEvent[]>([]);

function pushReceivedEvent(event: TestEvent) {
receivedEvents.push(event);
if (receivedEvents.length > MAX_EVENTS_DISPLAYED) {
receivedEvents.shift();
}
setReceivedEvents([
...receivedEvents
]);
}
const pushReceivedEvent = useCallback((event: TestEvent) => {
setReceivedEvents(prevEvents => {
const newEvents = [...prevEvents, event];
return newEvents.length > MAX_EVENTS_DISPLAYED
? newEvents.slice(-MAX_EVENTS_DISPLAYED)
: newEvents;
});
}, [MAX_EVENTS_DISPLAYED]);

const registerListener = (eventType: DidomiEventType) => {
const registerListener = useCallback((eventType: DidomiEventType) => {
Didomi.addEventListener(eventType, (data: any) => {
pushReceivedEvent({ name: eventType, data });
console.log('event received: ' + eventType);
});
};
}, [pushReceivedEvent]);

React.useEffect(() => {
Didomi.removeAllEventListeners();
Expand Down Expand Up @@ -74,23 +74,11 @@ function App() {
console.log('error');
});

/*Didomi.addEventListener(DidomiEventType.READY, (data: any) => {
setReceivedEvent({ name: DidomiEventType.READY, data });
console.log("I'm ready");
});

Didomi.addEventListener(DidomiEventType.SHOW_NOTICE, (data: any) => {
setReceivedEvent({ name: DidomiEventType.SHOW_NOTICE, data });
console.log('Show notice');
});

Didomi.addEventListener(DidomiEventType.CONSENT_CHANGED, (data: any) => {
setReceivedEvent({ name: DidomiEventType.CONSENT_CHANGED, data });
console.log('Consent changed');
});*/

// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Cleanup on unmount
return () => {
Didomi.removeAllEventListeners();
};
}, [registerListener]);

function displayEvents() {
return receivedEvents.map((event)=>{
Expand All @@ -102,26 +90,28 @@ function App() {
}

return (
<SafeAreaProvider>
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.title}>
<Text style={styles.title}>
LAST RECEIVED EVENTS:
{ displayEvents() }
</Text>
</View>
<ScrollView>
<View style={styles.container}>
<Text style={styles.title}>METHODS</Text>
<Methods />
<Text style={styles.title}>GETTERS</Text>
<Getters />
<Text style={styles.title}>SETTERS</Text>
<Setters />
<ErrorBoundary>
<SafeAreaProvider>
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.title}>
<Text style={styles.title}>
LAST RECEIVED EVENTS:
{ displayEvents() }
</Text>
</View>
</ScrollView>
</SafeAreaView>
</SafeAreaProvider>
<ScrollView>
<View style={styles.container}>
<Text style={styles.title}>METHODS</Text>
<Methods />
<Text style={styles.title}>GETTERS</Text>
<Getters />
<Text style={styles.title}>SETTERS</Text>
<Setters />
</View>
</ScrollView>
</SafeAreaView>
</SafeAreaProvider>
</ErrorBoundary>
);
}

Expand Down
66 changes: 66 additions & 0 deletions sample/src/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { Component, ErrorInfo, ReactNode } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';

interface Props {
children: ReactNode;
}

interface State {
hasError: boolean;
error: Error | null;
}

class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false, error: null };
}

static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}

componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('ErrorBoundary caught an error:', error, errorInfo);
}

handleReset = () => {
this.setState({ hasError: false, error: null });
};

render() {
if (this.state.hasError) {
return (
<View style={styles.container}>
<Text style={styles.title}>Something went wrong</Text>
<Text style={styles.message}>{this.state.error?.message}</Text>
<Button title="Try Again" onPress={this.handleReset} />
</View>
);
}

return this.props.children;
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
title: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
message: {
fontSize: 14,
color: 'red',
marginBottom: 20,
textAlign: 'center',
},
});

export default ErrorBoundary;
2 changes: 2 additions & 0 deletions sample/src/Setters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default function Setters() {
consent_string: '',
addtl_consent: '',
didomi_dcs: '',
gpp_string: '',
regulation: ''
});
}}
Expand All @@ -51,6 +52,7 @@ export default function Setters() {
consent_string: '',
addtl_consent: '',
didomi_dcs: '',
gpp_string: '',
regulation: ''
});
}}
Expand Down
16 changes: 8 additions & 8 deletions src/Didomi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ export const Didomi = {
* Listen to SDK ready state
*/
onReady: (): Promise<void> => {
var promise = DidomiListener.setOnReadyListener();
RNDidomi.onReady();
const promise = DidomiListener.setOnReadyListener();
RNDidomi.onReady().catch((err: Error) => console.error('Didomi onReady native error:', err));
return promise;
},

/**
* Listen to SDK errors
*/
onError: (): Promise<void> => {
var promise = DidomiListener.setOnErrorListener();
RNDidomi.onError();
const promise = DidomiListener.setOnErrorListener();
RNDidomi.onError().catch((err: Error) => console.error('Didomi onError native error:', err));
return promise;
},

Expand Down Expand Up @@ -137,11 +137,11 @@ export const Didomi = {
* @param vendorId: the id of the vendor
* @param callback: the callback to trigger when the user status for the selected vendor changes
*/
addVendorStatusListener: (
addVendorStatusListener: async (
vendorId: string,
callback: (vendorStatus: VendorStatus) => void
) => {
RNDidomi.listenToVendorStatus(vendorId)
): Promise<void> => {
await RNDidomi.listenToVendorStatus(vendorId);
DidomiListener.addVendorStatusListener(vendorId, callback);
},

Expand Down Expand Up @@ -346,7 +346,7 @@ export const Didomi = {
* @returns: The user LI status corresponding to the specified vendor and all its required purposes.
* @deprecated use {@link #getCurrentUserStatus()} instead.
*/
getUserLegitimateInterestStatusForVendorAndRequiredPurposes: (vendorId: string): boolean => RNDidomi.getUserLegitimateInterestStatusForVendorAndRequiredPurposes(vendorId),
getUserLegitimateInterestStatusForVendorAndRequiredPurposes: (vendorId: string): Promise<boolean> => RNDidomi.getUserLegitimateInterestStatusForVendorAndRequiredPurposes(vendorId),

/**
* Get the current user consent status.
Expand Down
40 changes: 33 additions & 7 deletions src/DidomiListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export const DidomiListener = {
}
}
events.forEach((el: any) => {
el(_event);
try {
el(_event);
} catch (err) {
console.error('Didomi event listener error:', err);
}
});
} else { // No listener for this event type
if (eventTypeValue == "on_sync_ready") {
Expand All @@ -43,6 +47,13 @@ export const DidomiListener = {
reset: () => {
// Reset listeners
DidomiListener.listeners = new Map();
// Clear vendor status listeners and their native event emitters
DidomiListener.vendorStatusListeners.forEach((_, vendorId) => {
DidomiListener.eventEmitter.removeAllListeners(
InternalEventType.VENDOR_STATUS_CHANGE_PREFIX + vendorId
);
});
DidomiListener.vendorStatusListeners = new Map();
},

addEventListener: (
Expand Down Expand Up @@ -71,8 +82,14 @@ export const DidomiListener = {
},

setOnReadyListener: (): Promise<void> => {
return new Promise<void>((resolve) => {
return new Promise<void>((resolve, reject) => {
const timeoutId = setTimeout(() => {
DidomiListener.eventEmitter.removeAllListeners(InternalEventType.READY_CALLBACK);
reject(new Error('Didomi SDK ready timeout'));
}, 30000);

const listener = (_event: any) => {
clearTimeout(timeoutId);
resolve();
DidomiListener.eventEmitter.removeAllListeners(InternalEventType.READY_CALLBACK);
};
Expand All @@ -84,8 +101,14 @@ export const DidomiListener = {
},

setOnErrorListener: (): Promise<void> => {
return new Promise<void>((resolve) => {
return new Promise<void>((resolve, reject) => {
const timeoutId = setTimeout(() => {
DidomiListener.eventEmitter.removeAllListeners(InternalEventType.ERROR_CALLBACK);
reject(new Error('Didomi SDK error listener timeout'));
}, 30000);

const listener = (_event: any) => {
clearTimeout(timeoutId);
resolve(_event);
DidomiListener.eventEmitter.removeAllListeners(InternalEventType.ERROR_CALLBACK);
};
Expand All @@ -109,7 +132,11 @@ export const DidomiListener = {
let events = DidomiListener.vendorStatusListeners.get(vendorId);
if (events) {
events.forEach((el: any) => {
el(_event);
try {
el(_event);
} catch (err) {
console.error('Didomi vendor status listener error:', err);
}
});
}
});
Expand All @@ -118,10 +145,9 @@ export const DidomiListener = {
},

removeVendorStatusListener: (vendorId: string) => {
let events = DidomiListener.vendorStatusListeners.get(vendorId);
if (events) {
if (DidomiListener.vendorStatusListeners.has(vendorId)) {
DidomiListener.eventEmitter.removeAllListeners(InternalEventType.VENDOR_STATUS_CHANGE_PREFIX + vendorId);
DidomiListener.vendorStatusListeners.set(vendorId, undefined);
DidomiListener.vendorStatusListeners.delete(vendorId);
}
},
};
Loading