Avoid showing default New Activity copy when dual content is missing or outside contentTimeout, per PLUGIN_NOTIFICATION_FIX_ANDROID.md.
85 lines
2.6 KiB
TypeScript
85 lines
2.6 KiB
TypeScript
/**
|
|
* Builds DualScheduleConfiguration for the Daily Notification plugin.
|
|
* Used for API-driven "New Activity" notifications (prefetch + notify).
|
|
*/
|
|
|
|
import type { DualScheduleConfiguration } from "@timesafari/daily-notification-plugin";
|
|
|
|
/** Matches `plugins.DailyNotification.networkConfig` in capacitor.config.ts */
|
|
const CONTENT_FETCH_NETWORK = {
|
|
timeout: 30_000,
|
|
retryAttempts: 3,
|
|
retryDelay: 1_000,
|
|
} as const;
|
|
|
|
/**
|
|
* Convert "HH:mm" (24h) to cron expression "minute hour * * *" (daily at that time).
|
|
*/
|
|
export function timeToCron(timeHHmm: string): string {
|
|
const [h, m] = timeHHmm.split(":").map(Number);
|
|
const hour = Math.max(0, Math.min(23, h ?? 0));
|
|
const minute = Math.max(0, Math.min(59, m ?? 0));
|
|
return `${minute} ${hour} * * *`;
|
|
}
|
|
|
|
/**
|
|
* Cron for 5 minutes before the given "HH:mm" (so prefetch runs before the notification).
|
|
*/
|
|
export function timeToCronFiveMinutesBefore(timeHHmm: string): string {
|
|
const [h, m] = timeHHmm.split(":").map(Number);
|
|
let hour = Math.max(0, Math.min(23, h ?? 0));
|
|
let minute = Math.max(0, Math.min(59, m ?? 0));
|
|
minute -= 5;
|
|
if (minute < 0) {
|
|
minute += 60;
|
|
hour -= 1;
|
|
if (hour < 0) hour += 24;
|
|
}
|
|
return `${minute} ${hour} * * *`;
|
|
}
|
|
|
|
export interface DualScheduleConfigInput {
|
|
/** Time in HH:mm (24h) for the user notification */
|
|
notifyTime: string;
|
|
/** Optional title; default "New Activity" */
|
|
title?: string;
|
|
/** Optional body; default describes API-driven content */
|
|
body?: string;
|
|
}
|
|
|
|
/**
|
|
* Build plugin DualScheduleConfiguration for scheduleDualNotification().
|
|
* contentFetch runs 5 minutes before notifyTime; userNotification at notifyTime.
|
|
*/
|
|
export function buildDualScheduleConfig(
|
|
input: DualScheduleConfigInput,
|
|
): DualScheduleConfiguration {
|
|
const notifyTime = input.notifyTime || "09:00";
|
|
const fetchCron = timeToCronFiveMinutesBefore(notifyTime);
|
|
const notifyCron = timeToCron(notifyTime);
|
|
return {
|
|
contentFetch: {
|
|
enabled: true,
|
|
schedule: fetchCron,
|
|
timeout: CONTENT_FETCH_NETWORK.timeout,
|
|
retryAttempts: CONTENT_FETCH_NETWORK.retryAttempts,
|
|
retryDelay: CONTENT_FETCH_NETWORK.retryDelay,
|
|
callbacks: {},
|
|
},
|
|
userNotification: {
|
|
enabled: true,
|
|
schedule: notifyCron,
|
|
title: input.title ?? "New Activity",
|
|
body: input.body ?? "Check your starred projects and offers for updates.",
|
|
sound: true,
|
|
vibration: true,
|
|
priority: "normal",
|
|
},
|
|
relationship: {
|
|
autoLink: true,
|
|
contentTimeout: 5 * 60 * 1000, // 5 minutes
|
|
fallbackBehavior: "skip", // was "show_default"
|
|
},
|
|
};
|
|
}
|