< Summary

Information
Class: MyNet.UI.ViewModels.FileHistory.RecentFileViewModel
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/FileHistory/RecentFileViewModel.cs
Tag: 323_28699572109
Line coverage
0%
Covered lines: 0
Uncovered lines: 61
Coverable lines: 61
Total lines: 220
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 22
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)0%7280%
set_DisplayName(...)100%210%
set_LastAccessDate(...)100%210%
set_ModificationDate(...)100%210%
set_IsPinned(...)100%210%
set_IsRecoveredFile(...)100%210%
set_Image(...)100%210%
FileExists()100%210%
LoadImageAsync()0%620%
OpenAsync()0%620%
OpenCopyAsync()100%210%
Update(...)0%2040%
RemoveFromListAsync()100%210%
RemoveFileAsync()0%2040%
SetPinnedAsync()0%620%
DisposeManagedResources()100%210%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/FileHistory/RecentFileViewModel.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="RecentFileViewModel.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Globalization;
 9using System.IO;
 10using System.Threading;
 11using System.Threading.Tasks;
 12using System.Windows.Input;
 13using MyNet.IO;
 14using MyNet.IO.FileHistory;
 15using MyNet.Primitives;
 16using MyNet.UI.Commands;
 17using MyNet.UI.Dialogs;
 18using MyNet.UI.Dialogs.MessageBox;
 19using MyNet.UI.Helpers;
 20using MyNet.UI.Notifications;
 21using MyNet.UI.Resources;
 22using MyNet.UI.Services;
 23using MyNet.UI.Services.FileHistory;
 24
 25namespace MyNet.UI.ViewModels.FileHistory;
 26
 27/// <summary>
 28/// View model for a single recent file entry.
 29/// </summary>
 30public sealed class RecentFileViewModel : ViewModelBase
 31{
 32    private readonly IRecentFilesOperations _recentFilesOperations;
 33    private readonly IRecentFileCommandsService _recentFileCommandsService;
 34    private readonly IDialogService _dialogService;
 35    private readonly INotificationPublisher _notificationPublisher;
 36
 37    /// <summary>
 38    /// Initializes a new instance of the <see cref="RecentFileViewModel"/> class.
 39    /// </summary>
 040    public RecentFileViewModel(
 041        RecentFile recentFile,
 042        IRecentFilesOperations recentFilesOperations,
 043        IRecentFileCommandsService recentFileCommandsService,
 044        IDialogService dialogService,
 045        INotificationPublisher notificationPublisher,
 046        ICommandFactory? commandFactory = null)
 47    {
 048        ArgumentNullException.ThrowIfNull(recentFile);
 49
 050        _recentFilesOperations = recentFilesOperations ?? throw new ArgumentNullException(nameof(recentFilesOperations))
 051        _recentFileCommandsService = recentFileCommandsService ?? throw new ArgumentNullException(nameof(recentFileComma
 052        _dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService));
 053        _notificationPublisher = notificationPublisher ?? throw new ArgumentNullException(nameof(notificationPublisher))
 54
 055        Path = recentFile.Path;
 056        Update(recentFile);
 57
 058        var commands = commandFactory.GetOrDefault();
 059        OpenCommand = commands.Create(OpenAsync, FileExists);
 60        OpenCopyCommand = commands.Create(OpenCopyAsync, () => !IsRecoveredFile && FileExists());
 61        OpenFolderLocationCommand = commands.Create(() => IoHelper.OpenFolderLocation(Path, _notificationPublisher), () 
 62        RemoveFromListCommand = commands.Create(RemoveFromListAsync, () => !IsRecoveredFile);
 063        RemoveFileCommand = commands.Create(RemoveFileAsync, FileExists);
 64        PinCommand = commands.Create(() => SetPinnedAsync(true), () => !IsPinned && !IsRecoveredFile);
 65        PinOffCommand = commands.Create(() => SetPinnedAsync(false), () => IsPinned && !IsRecoveredFile);
 066    }
 67
 68    /// <summary>
 69    /// Gets the file path.
 70    /// </summary>
 71    public string Path { get; }
 72
 73    /// <summary>
 74    /// Gets the display name.
 75    /// </summary>
 076    public string? DisplayName { get; private set => SetProperty(ref field, value); }
 77
 78    /// <summary>
 79    /// Gets the last access date.
 80    /// </summary>
 081    public DateTime? LastAccessDate { get; private set => SetProperty(ref field, value); }
 82
 83    /// <summary>
 84    /// Gets the last modification date.
 85    /// </summary>
 086    public DateTime? ModificationDate { get; private set => SetProperty(ref field, value); }
 87
 88    /// <summary>
 89    /// Gets a value indicating whether the file is pinned.
 90    /// </summary>
 091    public bool IsPinned { get; private set => SetProperty(ref field, value); }
 92
 93    /// <summary>
 94    /// Gets a value indicating whether the file is a recovered document.
 95    /// </summary>
 096    public bool IsRecoveredFile { get; private set => SetProperty(ref field, value); }
 97
 98    /// <summary>
 99    /// Gets the preview image bytes.
 100    /// </summary>
 0101    public byte[]? Image { get; private set => SetProperty(ref field, value); }
 102
 103    /// <summary>
 104    /// Gets the command that opens the file.
 105    /// </summary>
 106    public ICommand OpenCommand { get; }
 107
 108    /// <summary>
 109    /// Gets the command that opens a copy of the file.
 110    /// </summary>
 111    public ICommand OpenCopyCommand { get; }
 112
 113    /// <summary>
 114    /// Gets the command that opens the containing folder.
 115    /// </summary>
 116    public ICommand OpenFolderLocationCommand { get; }
 117
 118    /// <summary>
 119    /// Gets the command that removes the entry from the recent-files list.
 120    /// </summary>
 121    public ICommand RemoveFromListCommand { get; }
 122
 123    /// <summary>
 124    /// Gets the command that deletes the file from disk and removes it from the list.
 125    /// </summary>
 126    public ICommand RemoveFileCommand { get; }
 127
 128    /// <summary>
 129    /// Gets the command that pins the file.
 130    /// </summary>
 131    public ICommand PinCommand { get; }
 132
 133    /// <summary>
 134    /// Gets the command that unpins the file.
 135    /// </summary>
 136    public ICommand PinOffCommand { get; }
 137
 138    /// <summary>
 139    /// Gets a value indicating whether the file exists on disk.
 140    /// </summary>
 0141    public bool FileExists() => File.Exists(Path);
 142
 143    /// <summary>
 144    /// Loads the preview image asynchronously.
 145    /// </summary>
 146    public async Task LoadImageAsync(CancellationToken cancellationToken = default)
 147    {
 0148        if (!FileExists())
 0149            return;
 150
 0151        await ExecuteSafeAsync(
 0152            async _ => Image = await _recentFileCommandsService.GetImageAsync(Path).ConfigureAwait(false),
 0153            cancellationToken).ConfigureAwait(false);
 0154    }
 155
 156    /// <summary>
 157    /// Opens the file.
 158    /// </summary>
 159    public async Task OpenAsync()
 160    {
 0161        if (IsRecoveredFile)
 0162            await _recentFileCommandsService.OpenCopyAsync(Path).ConfigureAwait(false);
 163        else
 0164            await _recentFileCommandsService.OpenAsync(Path).ConfigureAwait(false);
 0165    }
 166
 167    /// <summary>
 168    /// Opens a copy of the file.
 169    /// </summary>
 0170    public async Task OpenCopyAsync() => await _recentFileCommandsService.OpenCopyAsync(Path).ConfigureAwait(false);
 171
 172    /// <summary>
 173    /// Updates the view model from the domain model.
 174    /// </summary>
 175    public void Update(RecentFile recentFile)
 176    {
 0177        ArgumentNullException.ThrowIfNull(recentFile);
 178
 0179        DisplayName = recentFile.Name;
 0180        LastAccessDate = recentFile.LastAccessedAt?.LocalDateTime;
 0181        ModificationDate = recentFile.LastModifiedAt?.LocalDateTime;
 0182        IsPinned = recentFile.IsPinned;
 0183        IsRecoveredFile = recentFile.IsRecovered;
 0184    }
 185
 0186    private async Task RemoveFromListAsync() => await _recentFilesOperations.RemoveAsync(Path).ConfigureAwait(false);
 187
 188    private async Task RemoveFileAsync()
 189    {
 0190        var result = await _dialogService
 0191            .ShowQuestionAsync(MessageResources.FileRemovingQuestion, UiResources.Removing)
 0192            .ConfigureAwait(false);
 193
 0194        if (result != MessageBoxResult.Yes)
 0195            return;
 196
 0197        if (FileHelper.TryDeleteFile(Path))
 198        {
 0199            await _recentFilesOperations.RemoveAsync(Path).ConfigureAwait(false);
 0200            _notificationPublisher.PublishSuccess(
 0201                MessageResources.FileXRemovedSuccess.FormatWith(CultureInfo.CurrentCulture, Path));
 202        }
 0203    }
 204
 205    private async Task SetPinnedAsync(bool isPinned)
 206    {
 0207        var updated = await _recentFilesOperations.SetPinnedAsync(Path, isPinned).ConfigureAwait(false);
 208
 0209        if (updated is not null)
 0210            Update(updated);
 0211    }
 212
 213    /// <inheritdoc />
 214    protected override void DisposeManagedResources()
 215    {
 0216        Image = null;
 0217        base.DisposeManagedResources();
 0218    }
 219}
 220