feat: add notification push
This commit is contained in:
64
frontend/src/lib/notifications.ts
Normal file
64
frontend/src/lib/notifications.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user