import { Platform } from 'react-native'; import { requireOptionalNativeModule } from 'expo-modules-core'; interface BbpNotifyNative { /** * Post/replace the ongoing session notification: a native chronometer counting * down to endTimeMillis, pinned by a foreground service, with "End" and "Extend" * action buttons. Returns a short diagnostic string (e.g. "service-started …"). */ showSession( title: string, body: string, endTimeMillis: number, endLabel: string, extendLabel: string, ): Promise; /** No active session: stop the service and remove the notification. */ clearSession(): Promise; /** Read + clear the action a notification button set: 'end' | 'extend' | ''. */ consumePendingAction(): Promise; /** Whether the native side still holds a live (unexpired) session record. */ hasActiveSession(): Promise; } export type PendingAction = 'end' | 'extend' | null; // Android-only, and only present in a build that includes the native module // (returns null in Expo Go / other platforms — callers degrade gracefully). const native = Platform.OS === 'android' ? (requireOptionalNativeModule('BbpNotify') as BbpNotifyNative | null) : null; /** True when the native ticking-countdown module is available. */ export const hasNativeCountdown = native != null; export async function showSession( title: string, body: string, endTimeMillis: number, endLabel: string, extendLabel: string, ): Promise { if (!native) return 'no-native-module'; return native.showSession(title, body, endTimeMillis, endLabel, extendLabel); } export async function clearSession(): Promise { await native?.clearSession(); } /** Read + clear a notification-button action taken while the app was away. */ export async function consumePendingAction(): Promise { const a = await native?.consumePendingAction(); return a === 'end' || a === 'extend' ? a : null; } export async function hasActiveSession(): Promise { return (await native?.hasActiveSession()) ?? false; }