Initial commit

This commit is contained in:
siliconsolder committed 2026-09-07 09:54:30 +00:00
commit 38c24fc9dc
166 files changed
+22002

No files matched your search

+58
View File
@@ -0,0 +1,58 @@
// ntfy-style priority scale (docs/migration-ntfy.md) — reused here so a
// value already familiar to anyone migrating from ntfy behaves the way
// they'd expect: "min"/1 means "log it, don't buzz the phone."
const PRIORITY_ALIASES: Record<string, number> = {
min: 1,
low: 2,
default: 3,
high: 4,
urgent: 5,
max: 5,
}
const DEFAULT_PRIORITY = 3
const MIN_PRIORITY_NO_PUSH = 1
export function resolvePriority(raw: string | null | undefined): number {
if (!raw) return DEFAULT_PRIORITY
const trimmed = raw.trim().toLowerCase()
// The `in` check above guarantees the key exists.
if (trimmed in PRIORITY_ALIASES) return PRIORITY_ALIASES[trimmed]!
const parsed = Number(trimmed)
return Number.isFinite(parsed) ? parsed : DEFAULT_PRIORITY
}
// "min" priority notifications are stored and shown in-app like any other
// — they just don't trigger a push, so a noisy automation can stay in its
// normal topic instead of needing a dedicated quiet topic.
export function isQuietPriority(raw: string | null | undefined): boolean {
return resolvePriority(raw) <= MIN_PRIORITY_NO_PUSH
}
// Household-wide "quiet hours" window (Admin > System) — true when `now`
// falls inside [start, end) in the given IANA timezone. Handles a window
// that wraps past midnight (e.g. 23:00-07:00) by checking OR instead of
// AND once start > end.
export function isWithinQuietHours(start: string, end: string, timezone: string, now = new Date()): boolean {
const parts = new Intl.DateTimeFormat('en-GB', {
timeZone: timezone,
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23',
}).formatToParts(now)
const hour = Number(parts.find((p) => p.type === 'hour')?.value ?? '0')
const minute = Number(parts.find((p) => p.type === 'minute')?.value ?? '0')
const nowMinutes = hour * 60 + minute
const [startH, startM] = start.split(':').map(Number)
const [endH, endM] = end.split(':').map(Number)
const startMinutes = (startH ?? 0) * 60 + (startM ?? 0)
const endMinutes = (endH ?? 0) * 60 + (endM ?? 0)
if (startMinutes === endMinutes) return false
if (startMinutes < endMinutes) {
return nowMinutes >= startMinutes && nowMinutes < endMinutes
}
return nowMinutes >= startMinutes || nowMinutes < endMinutes
}