From 3b080cc97fdcb21be43c5e01a5e2d3ce594403fe Mon Sep 17 00:00:00 2001 From: Nicolas CHAIX Date: Thu, 11 Dec 2025 17:59:49 +0100 Subject: [PATCH 01/12] align min API with current React-Native version --- android/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/gradle.properties b/android/gradle.properties index fd0c5191..e132fb82 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -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 From ba22b6e96ab8932876b4862d40f56928e35def96 Mon Sep 17 00:00:00 2001 From: Nicolas CHAIX Date: Thu, 11 Dec 2025 18:00:48 +0100 Subject: [PATCH 02/12] fix discrepancy with Android --- ios/RNDidomi.swift | 2 +- test/ios/DidomiUITests/DidomiUITests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/RNDidomi.swift b/ios/RNDidomi.swift index 34623ce8..3222bbfc 100644 --- a/ios/RNDidomi.swift +++ b/ios/RNDidomi.swift @@ -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:) diff --git a/test/ios/DidomiUITests/DidomiUITests.swift b/test/ios/DidomiUITests/DidomiUITests.swift index f602817f..bf3a76bc 100644 --- a/test/ios/DidomiUITests/DidomiUITests.swift +++ b/test/ios/DidomiUITests/DidomiUITests.swift @@ -505,7 +505,7 @@ class DidomiUITests: XCTestCase { let app = initApp() tapButton(in: app, name: "getText [Key = '0']") - assertResult(in: app, name: "getText [Key = '0']", expected: "") + assertResult(in: app, name: "getText [Key = '0']", expected: "{}") } func testGetTranslatedText() throws { From 50fb8861a0174a7c1c0f65b4e8763313ee4c1f77 Mon Sep 17 00:00:00 2001 From: Nicolas CHAIX Date: Thu, 11 Dec 2025 18:01:38 +0100 Subject: [PATCH 03/12] add ErrorBoundary component to sample and test Apps --- sample/src/App.tsx | 86 +++++++++++------------- sample/src/ErrorBoundary.tsx | 66 +++++++++++++++++++ test/src/App.tsx | 122 ++++++++++++++++------------------- test/src/ErrorBoundary.tsx | 66 +++++++++++++++++++ 4 files changed, 227 insertions(+), 113 deletions(-) create mode 100644 sample/src/ErrorBoundary.tsx create mode 100644 test/src/ErrorBoundary.tsx diff --git a/sample/src/App.tsx b/sample/src/App.tsx index c3d3b293..7411f6c8 100644 --- a/sample/src/App.tsx +++ b/sample/src/App.tsx @@ -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'; @@ -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([]); - 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(); @@ -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)=>{ @@ -102,26 +90,28 @@ function App() { } return ( - - - - - LAST RECEIVED EVENTS: - { displayEvents() } - - - - - METHODS - - GETTERS - - SETTERS - + + + + + + LAST RECEIVED EVENTS: + { displayEvents() } + - - - + + + METHODS + + GETTERS + + SETTERS + + + + + + ); } diff --git a/sample/src/ErrorBoundary.tsx b/sample/src/ErrorBoundary.tsx new file mode 100644 index 00000000..6824df38 --- /dev/null +++ b/sample/src/ErrorBoundary.tsx @@ -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 { + 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 ( + + Something went wrong + {this.state.error?.message} +