Cootz_PasswordManager/PasswordManager/ViewModel/RecentViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PasswordManager.Model.DB.Schema;
using PasswordManager.Services;
using PasswordManager.View;
using Realms;
using SharpHook;
using SharpHook.Native;

namespace PasswordManager.ViewModel;

public partial class RecentViewModel : ObservableObject
{
    private IQueryable<ProfileInfo> profiles;

    public IQueryable<ProfileInfo> Profiles
    {
        get
        {
            return !string.IsNullOrEmpty(SearchText) && SearchText.Length > 2
                ? profiles.Filter(
                    $"{nameof(ProfileInfo.Service)}.{nameof(ServiceInfo.Name)} CONTAINS[c] $0"
                    + $"|| {nameof(ProfileInfo.Username)} CONTAINS[c] $0", SearchText)
                : profiles;
        }
        set
        {
            profiles = value;
            OnPropertyChanged();
        }
    }

    private string searchText = string.Empty;

    public string SearchText
    {
        get => searchText;
        set
        {
            searchText = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(Profiles));
        }
    }

    private readonly DatabaseService db;
    private readonly INavigationService navigationService;
    private readonly IAlertService alertService;

    public RecentViewModel(DatabaseService databaseService, INavigationService navigationService, IGlobalHook globalHook, IAlertService alertService)
    {
        db = databaseService;
        this.navigationService = navigationService;
        this.alertService = alertService;

        globalHook.KeyReleased += OnKeyReleased;

        Profiles = db.Select<ProfileInfo>();
    }

    private void OnKeyReleased(object sender, KeyboardHookEventArgs e)
    {
        if (e.Data.KeyCode == KeyCode.VcEscape)
            MainThread.BeginInvokeOnMainThread(() => navigationService.PopAsync());
    }

    [RelayCommand]
    private async Task AddNote()
    {
        await navigationService.NavigateToAsync(nameof(AddPage));
    }

    [RelayCommand]
    private async Task DeleteNote(ProfileInfo sender)
    {
        bool confirmed = await alertService.ShowConfirmationAsync("Delete profile", "This profile will be permanently deleted. Continue?");

        if (confirmed)
            await db.Remove(sender);
    }

    [RelayCommand]
    private async Task ShowNoteInfo(ProfileInfo sender)
    {
        Dictionary<string, object> routeParams = new()
        {
            { "profile", sender }
        };

        await navigationService.NavigateToAsync(nameof(ProfilePage), routeParams);
    }
}