import { type EventSubscription, type TurboModule } from 'react-native'; import { InlineInAppMessageView } from './components'; import { NativeLoggerListener } from './native-logger-listener'; import { NotificationInbox, type NotificationInboxSpec, } from './notification-inbox'; import NativeCustomerIOMessagingInApp, { type Spec as CodegenSpec, } from './specs/modules/NativeCustomerIOMessagingInApp'; import type { InAppMessageEventType } from './types'; import { callNativeModule, ensureNativeModule } from './utils/native-bridge'; /** * Ensures all methods defined in codegen spec are implemented by the public module * * @internal */ interface NativeInAppSpec extends Omit< CodegenSpec, keyof TurboModule | NotificationInboxSpec | 'onInAppEventReceived' > {} // Reference to the native CustomerIO Data Pipelines module for SDK operations const nativeModule = ensureNativeModule(NativeCustomerIOMessagingInApp); // Wrapper function that ensures SDK is initialized before calling native methods const withNativeModule = (fn: (native: CodegenSpec) => R): R => { return callNativeModule(nativeModule, fn); }; /** * Helper class so that registering event listeners is easier for customers. * * @public */ class CustomerIOInAppMessaging implements NativeInAppSpec { private _notificationInbox?: NotificationInbox; registerEventsListener( listener: (event: InAppMessageEvent) => void ): EventSubscription { const emitter = (data: any) => { // Convert raw native payload to InAppMessageEvent const event = new InAppMessageEvent( data.eventType as InAppMessageEventType, data.messageId, data.deliveryId, data.actionValue, data.actionName ); listener(event); }; return withNativeModule((native) => { try { // Register TurboModule event listener and return subscription. // This method is generated by codegen in the native modules. // Wrapped in try-catch due to previous reports of crashes on certain Android architectures. return native.onInAppEventReceived(emitter); } catch (error) { NativeLoggerListener.warn( 'Failed to attach in-app event listener:', error ); // Return a no-op subscription to maintain backwards compatibility return { remove: () => {}, eventType: '', key: 0, subscriber: null as any, } as EventSubscription; } }); } /** * Dismisses any currently displayed in-app message */ dismissMessage() { withNativeModule((native) => native.dismissMessage()); } /** * Gets the message inbox instance for managing inbox messages * * @returns NotificationInbox instance for fetching and managing inbox messages */ inbox(): NotificationInbox { if (!this._notificationInbox) { this._notificationInbox = new NotificationInbox(); } return this._notificationInbox; } } /** * Class to hold in-app event attributes. */ /** @public */ class InAppMessageEvent { eventType: InAppMessageEventType; messageId: string; deliveryId?: string; actionValue?: string; actionName?: string; constructor( eventType: InAppMessageEventType, messageId: string, deliveryId?: string, actionValue?: string, actionName?: string ) { this.eventType = eventType; this.deliveryId = deliveryId; this.messageId = messageId; this.actionValue = actionValue; this.actionName = actionName; } } // Export in-app messaging types and components for simplified imports export type { InlineInAppMessageViewProps } from './components'; export { NotificationInbox } from './notification-inbox'; export type { InboxMessage, NotificationInboxChangeListener } from './types'; export { CustomerIOInAppMessaging, InAppMessageEvent, InlineInAppMessageView };