BigBrainParking/app/modules/bbp-notify/index.ts
Erik 2b973348bc
All checks were successful
build-apk / build (push) Successful in 28m23s
v0.2.4: fix countdown notification not appearing + wrong time-remaining
Countdown notification "nothing appears" on session start:
- The small icon was the adaptive launcher mipmap (applicationInfo.icon),
  which Android 13+/GrapheneOS rejects as an invalid notification small icon
  and drops the post silently. Ship a proper white-on-transparent vector
  small icon (bbp_stat_parking) inside the module and use it.
- showCountdown now returns a diagnostic string (posted / notifications
  disabled / exception) instead of swallowing failures; JS logs the branch,
  permission result, and native outcome to the in-app diagnostics log.
- Log the raw active-session payload in refreshSessionStatus (element shape
  was previously unconfirmed).

Time remaining showed "7694 min":
- API's TimeRemaining is SECONDS, not minutes. Format it as hours+minutes
  in SessionDetail; annotate the type.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 21:55:45 +00:00

35 lines
1.2 KiB
TypeScript

import { Platform } from 'react-native';
import { requireOptionalNativeModule } from 'expo-modules-core';
interface BbpNotifyNative {
/**
* Post/replace an ongoing notification with a native chronometer counting down
* to endTimeMillis. Returns a short diagnostic string (e.g. "posted enabled=true").
*/
showCountdown(title: string, body: string, endTimeMillis: number): Promise<string>;
/** Remove the countdown notification. */
clear(): Promise<void>;
}
// 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 showCountdown(
title: string,
body: string,
endTimeMillis: number,
): Promise<string> {
if (!native) return 'no-native-module';
return native.showCountdown(title, body, endTimeMillis);
}
export async function clearCountdown(): Promise<void> {
await native?.clear();
}