import { NativeEventEmitter, NativeModules, Platform } from "react-native"; import type { AndroidNotificationChannelConfig, IOSNotificationCategoryConfig, NativeNotificationEvent, NotificationPermissionStatus, PushNotificationPayload, } from "../types"; interface NativeSirrusNotificationsModule { requestPermission(): Promise; registerAndroidChannels(channels: AndroidNotificationChannelConfig[]): Promise; registerIOSCategories(categories: IOSNotificationCategoryConfig[]): Promise; showLocalNotification(payload: Record): Promise; cancelNotification(notificationId: string): Promise; cancelAllNotifications(): Promise; setBadgeCount(count: number): Promise; consumeInitialNotificationEvent(): Promise; consumeLatestNativePushToken(): Promise<{ token: string; provider: "fcm" | "apns"; } | null>; addListener?(eventName: string): void; removeListeners?(count: number): void; } const moduleRef = NativeModules.SirrusReactNativeSdk as | NativeSirrusNotificationsModule | undefined; const eventEmitter = moduleRef ? new NativeEventEmitter(moduleRef as never) : null; const NOTIFICATION_EVENT_NAME = "sirrusNotificationEvent"; const ensureModule = (): NativeSirrusNotificationsModule => { if (!moduleRef) { throw new Error( "Sirrus native notification module is not linked. Reinstall pods / Gradle dependencies and rebuild the app." ); } return moduleRef; }; export const isSirrusNativeNotificationsAvailable = (): boolean => Boolean(moduleRef); export const requestNativeNotificationPermission = async (): Promise => { return { granted: false, status: "unavailable", }; }; export const registerNativeAndroidChannels = async ( channels: AndroidNotificationChannelConfig[] ): Promise => { if (Platform.OS !== "android" || channels.length === 0 || !moduleRef) { return; } await ensureModule().registerAndroidChannels(channels); }; export const registerNativeIOSCategories = async ( categories: IOSNotificationCategoryConfig[] ): Promise => { if (Platform.OS !== "ios" || categories.length === 0 || !moduleRef) { return; } await ensureModule().registerIOSCategories(categories); }; export const showNativeLocalNotification = async ( payload: PushNotificationPayload ): Promise => { await ensureModule().showLocalNotification(payload as unknown as Record); }; export const cancelNativeNotification = async ( notificationId: string ): Promise => { if (!moduleRef) { return; } await ensureModule().cancelNotification(notificationId); }; export const cancelAllNativeNotifications = async (): Promise => { if (!moduleRef) { return; } await ensureModule().cancelAllNotifications(); }; export const setNativeBadgeCount = async (count: number): Promise => { if (!moduleRef) { return; } await ensureModule().setBadgeCount(count); }; export const subscribeToNativeNotificationEvents = ( listener: (event: NativeNotificationEvent) => void ): (() => void) => { if (!eventEmitter) { return () => undefined; } const subscription = eventEmitter.addListener( NOTIFICATION_EVENT_NAME, listener ); return () => { subscription.remove(); }; }; export const consumeInitialNativeNotificationEvent = async (): Promise => { if (!moduleRef) { return null; } return ensureModule().consumeInitialNotificationEvent(); }; export const consumeLatestNativePushToken = async (): Promise<{ token: string; provider: "fcm" | "apns" } | null> => { if (!moduleRef) { return null; } return ensureModule().consumeLatestNativePushToken(); };