livia-test/Livia/Models/IdleTimer.cs
2025-03-28 14:31:53 +08:00

84 lines
2.4 KiB
C#

using System.Windows.Threading;
using CommunityToolkit.Mvvm.Messaging;
using Livia.Models.Data;
using Livia.Properties;
using Livia.Utility;
using Livia.Views.Utility;
using Microsoft.Extensions.Logging;
namespace Livia.Models;
public interface IIdleTimer
{
void ResetTimer();
}
public class IdleTimerTickMessage(IIdleTimer idleTimer)
{
public readonly IIdleTimer IdleTimer = idleTimer;
}
public class IdleTimer : IIdleTimer
{
private DateTime _lastActiveTime = DateTime.Now;
private readonly TimeSpan _lockAfter = TimeSpan.FromMinutes(Settings.Default.LogoutAfter);
private readonly ILogger _logger;
private readonly IServerHandler _serverHandler;
private readonly IWarningSystem _warningSystem;
private static readonly TimeSpan TickInterval = new(0, 0, 5);
private static readonly TimeSpan SnackBarWarningTime = new(0, 1, 0);
public IdleTimer(ILogger logger, IServerHandler serverHandler, IWarningSystem warningSystem)
{
_logger = logger;
_serverHandler = serverHandler;
_warningSystem = warningSystem;
if (Settings.Default.LogoutAfter <= 0)
return;
DispatcherTimer dispatcherTimer = new();
dispatcherTimer.Tick += Tick;
dispatcherTimer.Interval = TickInterval;
dispatcherTimer.Start();
}
private void Tick(object? sender, EventArgs? e)
{
//sent tick message, any busy module will reset timer when receives this message
WeakReferenceMessenger.Default.Send(new IdleTimerTickMessage(this));
//no access, do not lock again
if (!_serverHandler.IsLoggedIn)
{
ResetTimer();
return;
}
TimeSpan idleTime = DateTime.Now - _lastActiveTime;
TimeSpan timeToLock = _lockAfter - idleTime;
if (timeToLock <= TimeSpan.Zero)
{
_logger.LogInformation("Idle time up");
_warningSystem.AddSnackbarMessage("IdleTimeout");
ResetTimer();
WeakReferenceMessenger.Default.Send(new LogoutMessage());
}
else if (timeToLock <= SnackBarWarningTime)
{
_warningSystem.AddSnackbarMessage(TickInterval - TimeSpan.FromSeconds(0.7), "IdleTimeoutWarning", (int)Math.Ceiling(timeToLock.TotalSeconds));
}
//waiting
}
public void ResetTimer()
{
//_logger.LogInformation("Timer reset");
_lastActiveTime = DateTime.Now;
}
}