Files
hackathon-opti-1a67c9077937…/frontend/src/lib/notifications.ts
2026-05-23 07:34:21 -06:00

65 lines
2.0 KiB
TypeScript

/**
* 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<void> {
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<boolean> {
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<string, unknown> = {},
): Promise<void> {
await Notifications.scheduleNotificationAsync({
content: {
title,
body,
data,
sound: "default",
},
trigger: null, // inmediata
});
}