/** * notifications.ts * * Wrapper sobre expo-notifications. Maneja: * - Configuración del canal Android * - Solicitud de permisos * - Disparo de notificaciones locales (aparecen en el centro de * notificaciones del sistema incluso si la app está en segundo plano) * * NOTA: Esto usa notificaciones LOCALES, no push remoto. Funciona cuando * la app está en foreground o background (no totalmente cerrada). Para * notificaciones con la app completamente cerrada hace falta un Development * Build + Expo Push Service, fuera del alcance del MVP. */ import * as Notifications from "expo-notifications"; import { Platform } from "react-native"; // Cómo se comportan las notificaciones cuando la app está en primer plano Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowBanner: true, shouldShowList: true, shouldPlaySound: true, shouldSetBadge: false, }), }); /** Crea el canal de Android (requerido en Android 8+). Idempotente. */ export async function setupAndroidChannel(): Promise { if (Platform.OS !== "android") return; await Notifications.setNotificationChannelAsync("ecoruta", { name: "EcoRuta", importance: Notifications.AndroidImportance.HIGH, vibrationPattern: [0, 250, 250, 250], lightColor: "#0E8A61", sound: "default", }); } /** Solicita permiso al usuario (no-op si ya está concedido). */ export async function requestPushPermissions(): Promise { const settings = await Notifications.getPermissionsAsync(); if (settings.granted) return true; const result = await Notifications.requestPermissionsAsync(); return result.granted; } /** Dispara una notificación local inmediata. */ export async function fireLocalNotification( title: string, body: string, data: Record = {}, ): Promise { await Notifications.scheduleNotificationAsync({ content: { title, body, data, sound: "default", }, trigger: null, // inmediata }); }