Ship Expo Router screens, seeded stores, and polished UX so auth, shop, checkout, prescriptions, loyalty, family, and account processes work end-to-end offline. Co-authored-by: Cursor <cursoragent@cursor.com>
73 lines
1.9 KiB
TypeScript
73 lines
1.9 KiB
TypeScript
import * as Notifications from "expo-notifications";
|
|
import { Platform } from "react-native";
|
|
|
|
Notifications.setNotificationHandler({
|
|
handleNotification: async () => ({
|
|
shouldShowAlert: true,
|
|
shouldPlaySound: true,
|
|
shouldSetBadge: false,
|
|
shouldShowBanner: true,
|
|
shouldShowList: true,
|
|
}),
|
|
});
|
|
|
|
export async function ensureNotificationPermissions() {
|
|
const settings = await Notifications.getPermissionsAsync();
|
|
if (settings.granted) return true;
|
|
const req = await Notifications.requestPermissionsAsync();
|
|
return req.granted;
|
|
}
|
|
|
|
export async function scheduleDoseReminder(opts: {
|
|
title: string;
|
|
body: string;
|
|
secondsFromNow: number;
|
|
data?: Record<string, string>;
|
|
}) {
|
|
await ensureNotificationPermissions();
|
|
return Notifications.scheduleNotificationAsync({
|
|
content: {
|
|
title: opts.title,
|
|
body: opts.body,
|
|
data: opts.data,
|
|
categoryIdentifier: "dose",
|
|
},
|
|
trigger: {
|
|
type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL,
|
|
seconds: Math.max(5, opts.secondsFromNow),
|
|
repeats: false,
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function scheduleEscalationCheck(opts: {
|
|
title: string;
|
|
body: string;
|
|
graceSeconds: number;
|
|
data?: Record<string, string>;
|
|
}) {
|
|
await ensureNotificationPermissions();
|
|
return Notifications.scheduleNotificationAsync({
|
|
content: {
|
|
title: opts.title,
|
|
body: opts.body,
|
|
data: { ...opts.data, type: "escalation" },
|
|
},
|
|
trigger: {
|
|
type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL,
|
|
seconds: Math.max(10, opts.graceSeconds),
|
|
repeats: false,
|
|
},
|
|
});
|
|
}
|
|
|
|
export function androidChannel() {
|
|
if (Platform.OS === "android") {
|
|
return Notifications.setNotificationChannelAsync("gishen-reminders", {
|
|
name: "Gishen reminders",
|
|
importance: Notifications.AndroidImportance.HIGH,
|
|
});
|
|
}
|
|
return Promise.resolve();
|
|
}
|