76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
|
|
import { Platform } from "react-native";
|
||
|
|
import * as Notifications from "expo-notifications";
|
||
|
|
|
||
|
|
export type NotificationTarget =
|
||
|
|
| { type: "chat"; sessionId: string; chatId: string }
|
||
|
|
| { type: "transactions"; sessionId: string };
|
||
|
|
|
||
|
|
Notifications.setNotificationHandler({
|
||
|
|
handleNotification: async () => ({
|
||
|
|
shouldShowAlert: true,
|
||
|
|
shouldPlaySound: true,
|
||
|
|
shouldSetBadge: false,
|
||
|
|
}),
|
||
|
|
});
|
||
|
|
|
||
|
|
export function parseNotificationTarget(data: unknown): NotificationTarget | null {
|
||
|
|
if (!data || typeof data !== "object") return null;
|
||
|
|
const record = data as Record<string, unknown>;
|
||
|
|
const type = record.type;
|
||
|
|
const sessionId = record.sessionId;
|
||
|
|
if (typeof type !== "string" || typeof sessionId !== "string" || !sessionId.trim()) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (type === "transactions") {
|
||
|
|
return { type: "transactions", sessionId };
|
||
|
|
}
|
||
|
|
if (type === "chat") {
|
||
|
|
const chatId = record.chatId;
|
||
|
|
if (typeof chatId !== "string" || !chatId.trim()) return null;
|
||
|
|
return { type: "chat", sessionId, chatId };
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function registerForPushNotificationsAsync(): Promise<
|
||
|
|
| {
|
||
|
|
token: string;
|
||
|
|
platform: "ios" | "android";
|
||
|
|
}
|
||
|
|
| null
|
||
|
|
> {
|
||
|
|
try {
|
||
|
|
const existing = await Notifications.getPermissionsAsync();
|
||
|
|
let finalStatus = existing.status;
|
||
|
|
if (finalStatus !== "granted") {
|
||
|
|
const requested = await Notifications.requestPermissionsAsync();
|
||
|
|
finalStatus = requested.status;
|
||
|
|
}
|
||
|
|
if (finalStatus !== "granted") {
|
||
|
|
if (__DEV__) {
|
||
|
|
console.log("[push] permission not granted");
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (Platform.OS === "android") {
|
||
|
|
await Notifications.setNotificationChannelAsync("default", {
|
||
|
|
name: "default",
|
||
|
|
importance: Notifications.AndroidImportance.MAX,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const deviceToken = await Notifications.getDevicePushTokenAsync();
|
||
|
|
if (deviceToken.type !== "ios" && deviceToken.type !== "android") {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (__DEV__) {
|
||
|
|
console.log(`[push] registered device token=${deviceToken.data}`);
|
||
|
|
}
|
||
|
|
return { token: deviceToken.data, platform: deviceToken.type };
|
||
|
|
} catch (error) {
|
||
|
|
if (__DEV__) {
|
||
|
|
console.log("[push] registration failed", error);
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|