feat(night-light): optional auto-on schedule (time window)
Night Light was all-or-nothing. Add an optional schedule with From/To time inputs so the warm overlay only shows during set hours and toggles itself on/off automatically (the overlay re-checks every minute; no reload). Overnight windows that wrap midnight (e.g. 21:00 -> 07:00) are handled. Window logic is the pure, unit-tested isWithinTimeWindow/parseHHMM in utils/timeWindow.ts. New settings: nightLightSchedule/Start/End (default 21:00-07:00). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+18
-1
@@ -1,4 +1,4 @@
|
||||
import React, { ReactNode, useEffect } from 'react';
|
||||
import React, { ReactNode, useEffect, useState } from 'react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { Provider as JotaiProvider, useAtomValue } from 'jotai';
|
||||
import {
|
||||
@@ -23,6 +23,7 @@ import { createRouter } from './Router';
|
||||
import { ScreenSizeProvider, useScreenSize } from '../hooks/useScreenSize';
|
||||
import { useCompositionEndTracking } from '../hooks/useComposingCheck';
|
||||
import { settingsAtom } from '../state/settings';
|
||||
import { isWithinTimeWindow } from '../utils/timeWindow';
|
||||
import { LotusToastContainer } from '../features/toast/LotusToastContainer';
|
||||
import { useTauriNotificationBadge } from '../hooks/useTauriNotificationBadge';
|
||||
import { useTauriWindowChrome } from '../hooks/useTauriWindowChrome';
|
||||
@@ -128,7 +129,23 @@ function DesktopChrome({ children }: { children: ReactNode }) {
|
||||
|
||||
function NightLightOverlay() {
|
||||
const settings = useAtomValue(settingsAtom);
|
||||
const scheduled = settings.nightLightEnabled && settings.nightLightSchedule;
|
||||
// When scheduled, re-evaluate the active window every minute so the overlay
|
||||
// turns on/off automatically at the start/end times without a reload.
|
||||
const [, forceTick] = useState(0);
|
||||
useEffect(() => {
|
||||
if (!scheduled) return undefined;
|
||||
const id = setInterval(() => forceTick((n) => n + 1), 60_000);
|
||||
return () => clearInterval(id);
|
||||
}, [scheduled]);
|
||||
|
||||
if (!settings.nightLightEnabled) return null;
|
||||
if (
|
||||
settings.nightLightSchedule &&
|
||||
!isWithinTimeWindow(settings.nightLightStart, settings.nightLightEnd)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
aria-hidden="true"
|
||||
|
||||
Reference in New Issue
Block a user