refactor(notifications): quiet-hours uses shared tested time-window helper

isInQuietHours was a hand-rolled, untested duplicate of the overnight-window
logic. Replace it with the shared, unit-tested isWithinTimeWindow (utils/
timeWindow.ts) - identical behavior for valid HH:MM inputs, more robust on
malformed ones (returns false rather than doing NaN math), and now covered by
timeWindow.test.ts. One implementation instead of two.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 20:43:08 -04:00
co-authored by Claude Opus 4.8
parent f155a4dc22
commit 5cce94edba
+3 -14
View File
@@ -15,6 +15,7 @@ import {
import { focusAssistActiveAtom } from '../../state/focusAssist';
import { manualDndAtom } from '../../state/manualDnd';
import { isSnoozeActive, notificationSnoozeUntilAtom } from '../../state/notificationSnooze';
import { isWithinTimeWindow } from '../../utils/timeWindow';
import { roomToUnreadAtom } from '../../state/room/roomToUnread';
import LogoSVG from '../../../../public/res/lotus.png';
import LogoUnreadSVG from '../../../../public/res/lotus-unread.png';
@@ -69,18 +70,6 @@ import {
// the async invite-atom population lands first and isn't mistaken for new invites.
const INVITE_NOTIFY_ARM_DELAY_MS = 3000;
function isInQuietHours(start: string, end: string): boolean {
const now = new Date();
const [sh, sm] = start.split(':').map(Number);
const [eh, em] = end.split(':').map(Number);
const cur = now.getHours() * 60 + now.getMinutes();
const s = sh! * 60 + (sm ?? 0);
const e = eh! * 60 + (em ?? 0);
// start===end means zero-length window → treat as disabled (no quiet hours)
if (s === e) return false;
return s < e ? cur >= s && cur < e : cur >= s || cur < e;
}
function SystemEmojiFeature() {
const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji');
@@ -259,7 +248,7 @@ function InviteNotifications() {
focusAssistActive ||
manualDnd ||
isSnoozeActive(snoozeUntil) ||
(quietHoursEnabled && isInQuietHours(quietHoursStart, quietHoursEnd));
(quietHoursEnabled && isWithinTimeWindow(quietHoursStart, quietHoursEnd));
if (quietActive) return;
if (showNotifications && notificationPermission('granted')) {
@@ -539,7 +528,7 @@ function MessageNotifications() {
focusAssistActive ||
manualDnd ||
isSnoozeActive(snoozeUntil) ||
(quietHoursEnabled && isInQuietHours(quietHoursStart, quietHoursEnd));
(quietHoursEnabled && isWithinTimeWindow(quietHoursStart, quietHoursEnd));
if (quietActive) return;
if (showNotifications && notificationPermission('granted')) {