diff --git a/src/KeyKeeper/ViewModels/RepositoryWindowViewModel.cs b/src/KeyKeeper/ViewModels/RepositoryWindowViewModel.cs index 6626261..4db29c9 100644 --- a/src/KeyKeeper/ViewModels/RepositoryWindowViewModel.cs +++ b/src/KeyKeeper/ViewModels/RepositoryWindowViewModel.cs @@ -1,13 +1,19 @@ using System; using System.Threading.Tasks; +using Avalonia.Threading; using KeyKeeper.PasswordStore; namespace KeyKeeper.ViewModels; public partial class RepositoryWindowViewModel : ViewModelBase { + private static readonly TimeSpan LockTimeout = TimeSpan.FromMinutes(5); + private object currentPage; private IPassStore passStore; + private DispatcherTimer? _lockTimer; + private DateTime _timerStart; + private string _lockTimerDisplay = string.Empty; public Func ShowErrorPopup; @@ -17,6 +23,12 @@ public partial class RepositoryWindowViewModel : ViewModelBase set { currentPage = value; OnPropertyChanged(nameof(CurrentPage)); } } + public string LockTimerDisplay + { + get => _lockTimerDisplay; + private set { _lockTimerDisplay = value; OnPropertyChanged(nameof(LockTimerDisplay)); } + } + public RepositoryWindowViewModel(IPassStore store) { passStore = store; @@ -31,13 +43,70 @@ public partial class RepositoryWindowViewModel : ViewModelBase SwitchToLocked(); } + /// + /// Ñáðàñûâàåò òàéìåð áëîêèðîâêè (âûçûâàåòñÿ ïðè ëþáîé àêòèâíîñòè ïîëüçîâàòåëÿ). + /// + public void ResetLockTimer() + { + if (_lockTimer != null && _lockTimer.IsEnabled) + _timerStart = DateTime.UtcNow; + } + private void SwitchToUnlocked() { CurrentPage = new UnlockedRepositoryViewModel(passStore); + StartLockTimer(); } private void SwitchToLocked() { + StopLockTimer(); CurrentPage = new LockedRepositoryViewModel(passStore, this); } + + private void StartLockTimer() + { + StopLockTimer(); + _timerStart = DateTime.UtcNow; + _lockTimer = new DispatcherTimer + { + Interval = TimeSpan.FromSeconds(1) + }; + _lockTimer.Tick += OnLockTimerTick; + _lockTimer.Start(); + UpdateTimerDisplay(); + } + + private void StopLockTimer() + { + if (_lockTimer != null) + { + _lockTimer.Tick -= OnLockTimerTick; + _lockTimer.Stop(); + _lockTimer = null; + } + LockTimerDisplay = string.Empty; + } + + private void OnLockTimerTick(object? sender, EventArgs e) + { + var elapsed = DateTime.UtcNow - _timerStart; + var remaining = LockTimeout - elapsed; + + if (remaining <= TimeSpan.Zero) + { + StopLockTimer(); + passStore.Lock(); + UpdateLockStatus(); + return; + } + + UpdateTimerDisplay(remaining); + } + + private void UpdateTimerDisplay(TimeSpan? remaining = null) + { + var r = remaining ?? LockTimeout; + LockTimerDisplay = $"{r:mm\\:ss}"; + } } \ No newline at end of file diff --git a/src/KeyKeeper/Views/RepositoryWindow.axaml b/src/KeyKeeper/Views/RepositoryWindow.axaml index 1bf3b0d..7aaaf65 100644 --- a/src/KeyKeeper/Views/RepositoryWindow.axaml +++ b/src/KeyKeeper/Views/RepositoryWindow.axaml @@ -25,7 +25,30 @@ FontSize="32" FontWeight="Bold" HorizontalAlignment="Left" - Margin="0,0,0,20"/> + Margin="0,0,0,8"/> + + + + + + + + +