Files
AX-Copilot-Codex/.decompiledproj/AxCopilot/Services/WorktimeReminderService.cs

237 lines
5.2 KiB
C#

using System;
using System.Timers;
using System.Windows.Threading;
using AxCopilot.Models;
using AxCopilot.Views;
using Microsoft.Win32;
namespace AxCopilot.Services;
public sealed class WorktimeReminderService : IDisposable
{
private readonly SettingsService _settings;
private readonly Dispatcher _dispatcher;
private readonly object _lock = new object();
private DateTime _sessionStart;
private TimeSpan _todayTotal;
private DateTime _lastDate;
private DateTime _lastShownAt;
private Timer? _periodicTimer;
private volatile bool _disposed;
public WorktimeReminderService(SettingsService settings, Dispatcher dispatcher)
{
_settings = settings;
_dispatcher = dispatcher;
_sessionStart = DateTime.Now;
_lastDate = DateTime.Today;
_lastShownAt = DateTime.MinValue;
try
{
int todayActiveSeconds = UsageStatisticsService.GetTodayActiveSeconds();
if (todayActiveSeconds > 0)
{
_todayTotal = TimeSpan.FromSeconds(todayActiveSeconds);
LogService.Info($"이전 세션 누적 시간 복원: {_todayTotal}");
}
}
catch (Exception ex)
{
LogService.Warn("이전 세션 시간 복원 실패: " + ex.Message);
}
SystemEvents.SessionSwitch += OnSessionSwitch;
LogService.Info("WorktimeReminderService 초기화 완료.");
ReminderSettings reminder = _settings.Settings.Reminder;
if (!reminder.Enabled)
{
return;
}
_dispatcher.BeginInvoke((Delegate)(Action)delegate
{
if (!_disposed)
{
ShowPopup();
}
}, (DispatcherPriority)2, Array.Empty<object>());
StartPeriodicTimer();
}
private void OnSessionSwitch(object sender, SessionSwitchEventArgs e)
{
if (_disposed)
{
return;
}
LogService.Info($"SessionSwitch 이벤트: {e.Reason}");
lock (_lock)
{
switch (e.Reason)
{
case SessionSwitchReason.SessionLock:
AccumulateSession();
StopPeriodicTimer();
LogService.Info($"세션 잠금. 누적 시간: {_todayTotal}");
break;
case SessionSwitchReason.SessionLogon:
case SessionSwitchReason.SessionUnlock:
{
ResetForNewDayIfNeeded();
_sessionStart = DateTime.Now;
ReminderSettings reminder = _settings.Settings.Reminder;
if (!reminder.Enabled)
{
LogService.Info("알림 비활성화 상태. 팝업 생략.");
break;
}
int num = Math.Max(1, reminder.IntervalMinutes);
double totalMinutes = (DateTime.Now - _lastShownAt).TotalMinutes;
LogService.Info($"알림 간격 확인: 경과={totalMinutes:F1}분, 설정={num}분");
if (totalMinutes >= (double)num)
{
ShowPopup();
}
StartPeriodicTimer();
break;
}
case SessionSwitchReason.SessionLogoff:
break;
}
}
}
private void AccumulateSession()
{
ResetForNewDayIfNeeded();
_todayTotal += DateTime.Now - _sessionStart;
_sessionStart = DateTime.Now;
}
private void ResetForNewDayIfNeeded()
{
if (DateTime.Today == _lastDate)
{
return;
}
DateTime today = DateTime.Today;
_sessionStart = today;
_lastDate = DateTime.Today;
_lastShownAt = DateTime.MinValue;
try
{
int todayActiveSeconds = UsageStatisticsService.GetTodayActiveSeconds();
_todayTotal = ((todayActiveSeconds > 0) ? TimeSpan.FromSeconds(todayActiveSeconds) : TimeSpan.Zero);
}
catch
{
_todayTotal = TimeSpan.Zero;
}
}
public TimeSpan GetTodayUsage()
{
lock (_lock)
{
ResetForNewDayIfNeeded();
return _todayTotal + (DateTime.Now - _sessionStart);
}
}
private void StartPeriodicTimer()
{
StopPeriodicTimer();
int num = Math.Max(1, _settings.Settings.Reminder.IntervalMinutes);
_periodicTimer = new Timer(num * 60000);
_periodicTimer.Elapsed += OnPeriodicTimerElapsed;
_periodicTimer.AutoReset = true;
_periodicTimer.Start();
LogService.Info($"격려 알림 주기 타이머 시작: {num}분 간격");
}
private void StopPeriodicTimer()
{
if (_periodicTimer != null)
{
_periodicTimer.Elapsed -= OnPeriodicTimerElapsed;
_periodicTimer.Stop();
_periodicTimer.Dispose();
_periodicTimer = null;
}
}
private void OnPeriodicTimerElapsed(object? sender, ElapsedEventArgs e)
{
if (_disposed)
{
return;
}
ReminderSettings reminder = _settings.Settings.Reminder;
if (!reminder.Enabled)
{
StopPeriodicTimer();
return;
}
lock (_lock)
{
ResetForNewDayIfNeeded();
ShowPopup();
}
}
public void RestartTimer()
{
ReminderSettings reminder = _settings.Settings.Reminder;
if (reminder.Enabled)
{
StartPeriodicTimer();
}
else
{
StopPeriodicTimer();
}
}
private void ShowPopup()
{
_lastShownAt = DateTime.Now;
TimeSpan usage = GetTodayUsage();
var (text, author) = QuoteService.GetRandom(_settings?.Settings.Reminder.EnabledCategories);
_dispatcher.BeginInvoke((Delegate)(Action)delegate
{
if (_disposed)
{
return;
}
try
{
if (_settings != null)
{
ReminderPopupWindow reminderPopupWindow = new ReminderPopupWindow(text, author, usage, _settings);
reminderPopupWindow.Show();
}
}
catch (Exception ex)
{
LogService.Warn("알림 팝업 표시 실패: " + ex.Message);
}
}, (DispatcherPriority)9, Array.Empty<object>());
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
StopPeriodicTimer();
SystemEvents.SessionSwitch -= OnSessionSwitch;
}
}
}