2026-06-28 10:00:25 -05:00
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
|
|
exports.recipientInQuietHours = recipientInQuietHours;
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Quiet-hours suppression for partner-action pushes.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The Settings UI promises "10 PM – 8 AM, no notifications". The client stores the window in local
|
|
|
|
|
|
* DataStore AND mirrors it to the recipient's `users/{uid}` doc (quietHoursEnabled / *StartMinutes /
|
|
|
|
|
|
* *EndMinutes / timezone). Because a partner push carries a `notification` block, the OS shows it
|
|
|
|
|
|
* directly when the recipient app is backgrounded/killed — so the only place the promise can be kept
|
|
|
|
|
|
* is server-side, here, before the push is sent (M-001).
|
|
|
|
|
|
*
|
|
|
|
|
|
* FAIL-OPEN by design: if quiet hours is not explicitly enabled, or any field (window/timezone) is
|
|
|
|
|
|
* missing or malformed, we return `false` (do NOT suppress). A bug here can therefore only ever fall
|
|
|
|
|
|
* back to today's behavior (notification delivered) — it can never wrongly drop a notification, and
|
|
|
|
|
|
* existing installs keep delivering exactly as before until the client backfills the fields.
|
|
|
|
|
|
*/
|
|
|
|
|
|
function recipientInQuietHours(userData, now = new Date()) {
|
|
|
|
|
|
var _a, _b;
|
|
|
|
|
|
if (!userData || userData.quietHoursEnabled !== true)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
const start = userData.quietHoursStartMinutes;
|
|
|
|
|
|
const end = userData.quietHoursEndMinutes;
|
|
|
|
|
|
const tz = userData.timezone;
|
|
|
|
|
|
if (typeof start !== 'number' || typeof end !== 'number' || typeof tz !== 'string' || !tz) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
let nowMinutes;
|
|
|
|
|
|
try {
|
|
|
|
|
|
const parts = new Intl.DateTimeFormat('en-US', {
|
|
|
|
|
|
timeZone: tz,
|
|
|
|
|
|
hour: '2-digit',
|
|
|
|
|
|
minute: '2-digit',
|
|
|
|
|
|
hour12: false,
|
|
|
|
|
|
}).formatToParts(now);
|
|
|
|
|
|
const hour = Number((_a = parts.find((p) => p.type === 'hour')) === null || _a === void 0 ? void 0 : _a.value) % 24;
|
|
|
|
|
|
const minute = Number((_b = parts.find((p) => p.type === 'minute')) === null || _b === void 0 ? void 0 : _b.value);
|
|
|
|
|
|
if (Number.isNaN(hour) || Number.isNaN(minute))
|
|
|
|
|
|
return false;
|
|
|
|
|
|
nowMinutes = hour * 60 + minute;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (_c) {
|
|
|
|
|
|
// Unknown/invalid timezone id → fail open.
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2026-06-30 00:38:06 -05:00
|
|
|
|
// Start == end means "no window" (nothing suppressed) — kept in lockstep with the client's
|
|
|
|
|
|
// QuietHoursManager.isInQuietHours so both decide identically.
|
|
|
|
|
|
if (start === end)
|
|
|
|
|
|
return false;
|
2026-06-28 10:00:25 -05:00
|
|
|
|
// Window may cross midnight (e.g. 22:00 → 08:00).
|
2026-06-30 00:38:06 -05:00
|
|
|
|
return start < end
|
2026-06-28 10:00:25 -05:00
|
|
|
|
? nowMinutes >= start && nowMinutes <= end
|
|
|
|
|
|
: nowMinutes >= start || nowMinutes <= end;
|
|
|
|
|
|
}
|
|
|
|
|
|
//# sourceMappingURL=quietHours.js.map
|