From acd3bfcf2ca45bcfacc2b50a311cf1a18ac54bb6 Mon Sep 17 00:00:00 2001 From: Braxton Ward Date: Mon, 11 May 2026 16:16:29 -0600 Subject: [PATCH] feat: add headless option to presentAction - Add optional headless?: boolean to Atomic.presentAction - Forward headless through iOS native module to Atomic.presentAction - Forward headless through Android native module to ActionConfig - Add headless toggle to example PresentActionScreen --- .../TransactReactNativeModule.kt | 4 +++- example/screens/PresentActionScreen.tsx | 18 ++++++++++++++++++ ios/TransactReactNative.m | 1 + ios/TransactReactNative.swift | 6 ++++-- src/android.tsx | 9 ++++++++- src/index.tsx | 3 +++ src/ios.tsx | 5 ++++- 7 files changed, 41 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/atomicfi/transactreactnative/TransactReactNativeModule.kt b/android/src/main/java/com/atomicfi/transactreactnative/TransactReactNativeModule.kt index 08db1a3..93e3bf1 100644 --- a/android/src/main/java/com/atomicfi/transactreactnative/TransactReactNativeModule.kt +++ b/android/src/main/java/com/atomicfi/transactreactnative/TransactReactNativeModule.kt @@ -125,6 +125,7 @@ class TransactReactNativeModule(reactContext: ReactApplicationContext) : id: String, environment: ReadableMap, wrapperVersion: String, + headless: Boolean?, promise: Promise, ) { val context = reactApplicationContext.currentActivity as Context @@ -135,7 +136,8 @@ class TransactReactNativeModule(reactContext: ReactApplicationContext) : val config = ActionConfig( id = id, environment = Config.Environment.CUSTOM, - environmentURL = environmentURL + environmentURL = environmentURL, + headless = headless, ) config.platform = Config.Platform.suffixed("react-$wrapperVersion") diff --git a/example/screens/PresentActionScreen.tsx b/example/screens/PresentActionScreen.tsx index b3713de..c4aa298 100644 --- a/example/screens/PresentActionScreen.tsx +++ b/example/screens/PresentActionScreen.tsx @@ -33,6 +33,7 @@ const PresentActionScreen: React.FC = () => { const [presentationStyleIOS, setPresentationStyleIOS] = useState(PresentationStyles.formSheet); const [debugEnabled, setDebugEnabled] = useState(false); + const [headless, setHeadless] = useState(false); const environmentOptions = [ { key: 'sandbox' as EnvironmentOption, label: 'Sandbox' }, @@ -88,6 +89,7 @@ const PresentActionScreen: React.FC = () => { environment: getEnvironment(), presentationStyleIOS, setDebug: debugEnabled, + headless, onLaunch: () => { console.log('Action launched'); setIsLoading(false); @@ -191,6 +193,22 @@ const PresentActionScreen: React.FC = () => { + + Headless + + + Off + + On + + + + How it works diff --git a/ios/TransactReactNative.m b/ios/TransactReactNative.m index 584082e..53fbc99 100644 --- a/ios/TransactReactNative.m +++ b/ios/TransactReactNative.m @@ -16,6 +16,7 @@ @interface RCT_EXTERN_MODULE(TransactReactNative, RCTEventEmitter) environment:(NSDictionary *)environment presentationStyle:(nullable NSString *)presentationStyle setDebug:(nullable NSNumber *)setDebug + headless:(nullable NSNumber *)headless withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) diff --git a/ios/TransactReactNative.swift b/ios/TransactReactNative.swift index 07e52c8..f3eec86 100644 --- a/ios/TransactReactNative.swift +++ b/ios/TransactReactNative.swift @@ -133,9 +133,10 @@ class TransactReactNative: RCTEventEmitter { } } - @objc(presentAction:environment:presentationStyle:setDebug:withResolver:withRejecter:) - func presentAction(id: String, environment: [String: Any], presentationStyle: String?, setDebug: NSNumber?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void { + @objc(presentAction:environment:presentationStyle:setDebug:headless:withResolver:withRejecter:) + func presentAction(id: String, environment: [String: Any], presentationStyle: String?, setDebug: NSNumber?, headless: NSNumber?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void { let debugEnabled = setDebug?.boolValue ?? false + let headlessEnabled = headless?.boolValue ?? false Task { @MainActor in await Atomic.setDebug(isEnabled: debugEnabled, forwardLogs: { logMessage in @@ -152,6 +153,7 @@ class TransactReactNative: RCTEventEmitter { id: id, environment: parsedEnvironment, presentationStyle: parsedPresentationStyle, + headless: headlessEnabled, onLaunch: { self.sendEvent(withName: "onLaunch", body: []) }, diff --git a/src/android.tsx b/src/android.tsx index 49120d3..e69ce7d 100644 --- a/src/android.tsx +++ b/src/android.tsx @@ -52,6 +52,7 @@ export const AtomicAndroid = { id, environment, wrapperVersion, + headless, onLaunch, onFinish, onClose, @@ -62,6 +63,7 @@ export const AtomicAndroid = { id: String; environment?: CONSTANTS.TransactEnvironment; wrapperVersion: string; + headless?: boolean; onLaunch?: Function; onFinish?: Function; onClose?: Function; @@ -74,6 +76,11 @@ export const AtomicAndroid = { _addEventListener('onTaskStatusUpdate', onTaskStatusUpdate); _addEventListener('onAuthStatusUpdate', onAuthStatusUpdate); - TransactReactNative.presentAction(id, environment, wrapperVersion); + TransactReactNative.presentAction( + id, + environment, + wrapperVersion, + headless + ); }, }; diff --git a/src/index.tsx b/src/index.tsx index 679dc21..c7c033d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -155,6 +155,7 @@ export const Atomic = { id, environment, presentationStyleIOS, + headless, onLaunch, onFinish, onClose, @@ -165,6 +166,7 @@ export const Atomic = { id: String; environment?: CONSTANTS.TransactEnvironment; presentationStyleIOS?: PresentationStyleIOS; + headless?: boolean; onLaunch?: Function; onFinish?: Function; onClose?: Function; @@ -178,6 +180,7 @@ export const Atomic = { environment: environment || CONSTANTS.Environment.production, wrapperVersion, presentationStyleIOS, + headless, onLaunch, onFinish, onClose, diff --git a/src/ios.tsx b/src/ios.tsx index ef88a75..acee49a 100644 --- a/src/ios.tsx +++ b/src/ios.tsx @@ -115,6 +115,7 @@ export const AtomicIOS = { id, environment, presentationStyleIOS, + headless, onLaunch, onFinish, onClose, @@ -129,6 +130,7 @@ export const AtomicIOS = { // for parity with Android callers but not forwarded to native. wrapperVersion?: string; presentationStyleIOS?: CONSTANTS.PresentationStyleIOS; + headless?: boolean; onLaunch?: Function; onFinish?: Function; onClose?: Function; @@ -180,7 +182,8 @@ export const AtomicIOS = { id, environment, presentationStyleIOS, - setDebug + setDebug, + headless ).then((event: any) => { if (event.finished && onFinish) { removeListeners();