65 lines
2.0 KiB
TypeScript
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
|
|
});
|
|
}
|