74 lines
2.1 KiB
C#
74 lines
2.1 KiB
C#
using Microsoft.Win32;
|
||
using System;
|
||
using System.Threading;
|
||
using System.Windows;
|
||
|
||
namespace Bedtimer
|
||
{
|
||
public sealed class OverlayManager : IDisposable
|
||
{
|
||
private Config _cfg = null!;
|
||
private OverlayWindow? _overlay;
|
||
private Thread? _cfgThread;
|
||
private string _cycleId = "";
|
||
|
||
public void Start()
|
||
{
|
||
_cfg = Config.LoadOrCreate();
|
||
BuildOverlay();
|
||
StartConfigListener();
|
||
|
||
// React to system time changes / DST
|
||
SystemEvents.TimeChanged += (_, __) => Application.Current.Dispatcher.Invoke(RecomputeSchedule);
|
||
}
|
||
|
||
private void BuildOverlay()
|
||
{
|
||
Application.Current.Dispatcher.Invoke(() =>
|
||
{
|
||
_overlay ??= new OverlayWindow();
|
||
_overlay.Show(); // safe: collapsed until T-60
|
||
RecomputeSchedule();
|
||
});
|
||
}
|
||
|
||
private void StartConfigListener()
|
||
{
|
||
_cfgThread = new Thread(() =>
|
||
{
|
||
using var ev = Signals.SubscribeConfigChanged();
|
||
while (true)
|
||
{
|
||
ev.WaitOne();
|
||
Application.Current.Dispatcher.Invoke(RecomputeSchedule);
|
||
}
|
||
});
|
||
_cfgThread.IsBackground = true;
|
||
_cfgThread.Start();
|
||
}
|
||
|
||
private void RecomputeSchedule()
|
||
{
|
||
_cfg = Config.LoadOrCreate();
|
||
|
||
var now = DateTime.Now;
|
||
var bedToday = now.Date.AddMinutes(_cfg.BedMinutes);
|
||
var bedT = (now <= bedToday) ? bedToday : bedToday.AddDays(1);
|
||
|
||
var warnT = bedT.AddMinutes(-_cfg.WarnLead);
|
||
var flashT = bedT.AddMinutes(-_cfg.FlashLead);
|
||
var lockT = bedT.AddMinutes(+_cfg.LockDelay);
|
||
|
||
// one lock per calendar day (next bedtime’s date)
|
||
_cycleId = bedT.ToString("yyyy-MM-dd");
|
||
|
||
_overlay!.SetSchedule(_cycleId, warnT, flashT, bedT, lockT);
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
// overlay lives/dies with app; nothing extra
|
||
}
|
||
}
|
||
}
|