From 85989057dfc4408c889a94100c926230a1719812 Mon Sep 17 00:00:00 2001 From: Slavasil Date: Wed, 19 Nov 2025 02:27:04 +0300 Subject: [PATCH] refactor 'recent files' rename RecentVault to RecentFile and move it to Models create RecentFilesService to read and manipulate the recent file list inject RecentFilesService into MainWindowViewModel --- src/KeyKeeper/App.axaml.cs | 3 +- src/KeyKeeper/Models/RecentFile.cs | 25 +++++++ src/KeyKeeper/Services/IRecentFilesService.cs | 16 +++++ src/KeyKeeper/Services/RecentFilesService.cs | 50 ++++++++++++++ .../ViewModels/MainWindowViewModel.cs | 21 ++++++ src/KeyKeeper/Views/MainWindow.axaml | 24 ++++--- src/KeyKeeper/Views/MainWindow.axaml.cs | 68 ++++++------------- 7 files changed, 147 insertions(+), 60 deletions(-) create mode 100644 src/KeyKeeper/Models/RecentFile.cs create mode 100644 src/KeyKeeper/Services/IRecentFilesService.cs create mode 100644 src/KeyKeeper/Services/RecentFilesService.cs diff --git a/src/KeyKeeper/App.axaml.cs b/src/KeyKeeper/App.axaml.cs index 70fc81e..a55380a 100644 --- a/src/KeyKeeper/App.axaml.cs +++ b/src/KeyKeeper/App.axaml.cs @@ -6,6 +6,7 @@ using System.Linq; using Avalonia.Markup.Xaml; using KeyKeeper.ViewModels; using KeyKeeper.Views; +using KeyKeeper.Services; namespace KeyKeeper; @@ -25,7 +26,7 @@ public partial class App : Application DisableAvaloniaDataAnnotationValidation(); desktop.MainWindow = new MainWindow { - DataContext = new MainWindowViewModel(), + DataContext = new MainWindowViewModel(new RecentFilesService()), }; } diff --git a/src/KeyKeeper/Models/RecentFile.cs b/src/KeyKeeper/Models/RecentFile.cs new file mode 100644 index 0000000..c27e6f5 --- /dev/null +++ b/src/KeyKeeper/Models/RecentFile.cs @@ -0,0 +1,25 @@ +using System; + +namespace KeyKeeper.Models; + +public struct RecentFile +{ + public string Path { get; set; } = string.Empty; + public DateTime LastOpened { get; set; } + + public string DisplayPath => Path; + + public RecentFile(string path, DateTime lastOpened) + { + Path = path; + LastOpened = lastOpened; + } + + public RecentFile(string path): this(path, DateTime.Now) + {} + + public override string ToString() + { + return DisplayPath; + } +} \ No newline at end of file diff --git a/src/KeyKeeper/Services/IRecentFilesService.cs b/src/KeyKeeper/Services/IRecentFilesService.cs new file mode 100644 index 0000000..8621da8 --- /dev/null +++ b/src/KeyKeeper/Services/IRecentFilesService.cs @@ -0,0 +1,16 @@ +using System.Collections.ObjectModel; +using KeyKeeper.Models; + +namespace KeyKeeper.Services; + +public interface IRecentFilesService +{ + // files are stored in reverse chronological order + ObservableCollection RecentFiles { get; } + + void Remember(string filename); + void Forget(string filename); + void ForgetAll(); + + // TODO load and store +} \ No newline at end of file diff --git a/src/KeyKeeper/Services/RecentFilesService.cs b/src/KeyKeeper/Services/RecentFilesService.cs new file mode 100644 index 0000000..7ddc7e4 --- /dev/null +++ b/src/KeyKeeper/Services/RecentFilesService.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.ObjectModel; +using System.Linq; +using KeyKeeper.Models; + +namespace KeyKeeper.Services; + +internal class RecentFilesService : IRecentFilesService +{ + // files are stored in reverse chronological order + public ObservableCollection RecentFiles { get; } + private readonly int maxEntries = 8; + + public RecentFilesService() + { + RecentFiles = new ObservableCollection(); + } + + public void Remember(string filename) + { + RemoveIfExists(filename); + RecentFiles.Insert(0, new RecentFile(filename)); + if (RecentFiles.Count > maxEntries) + { + RecentFiles.RemoveAt(RecentFiles.Count - 1); + } + } + + public void Forget(string filename) + { + RemoveIfExists(filename); + } + + public void ForgetAll() + { + RecentFiles.Clear(); + } + + public void RemoveIfExists(string filename) + { + for (int i = 0; i < RecentFiles.Count; i++) + { + if (RecentFiles[i].Path == filename) + { + RecentFiles.RemoveAt(i); + break; + } + } + } +} \ No newline at end of file diff --git a/src/KeyKeeper/ViewModels/MainWindowViewModel.cs b/src/KeyKeeper/ViewModels/MainWindowViewModel.cs index ef7a791..6cc0439 100644 --- a/src/KeyKeeper/ViewModels/MainWindowViewModel.cs +++ b/src/KeyKeeper/ViewModels/MainWindowViewModel.cs @@ -3,11 +3,32 @@ using CommunityToolkit.Mvvm.Input; using KeyKeeper.Views; using Avalonia.Controls; using System.Threading.Tasks; +using KeyKeeper.Services; +using System.Collections.ObjectModel; +using KeyKeeper.Models; namespace KeyKeeper.ViewModels; public partial class MainWindowViewModel : ViewModelBase { public string Greeting { get; } = "Welcome to KeyKeeper!"; + public ObservableCollection RecentFiles => recentFilesService.RecentFiles; + + private IRecentFilesService recentFilesService; + + public MainWindowViewModel(IRecentFilesService recentFilesService) + { + this.recentFilesService = recentFilesService; + } + + public void OpenVault(string filename) + { + recentFilesService.Remember(filename); + } + + public void CreateVault(string filename) + { + recentFilesService.Remember(filename); + } [RelayCommand] private async Task OpenSettings() diff --git a/src/KeyKeeper/Views/MainWindow.axaml b/src/KeyKeeper/Views/MainWindow.axaml index 7c4b00f..868a266 100644 --- a/src/KeyKeeper/Views/MainWindow.axaml +++ b/src/KeyKeeper/Views/MainWindow.axaml @@ -1,6 +1,7 @@  - - -