Browse Source

Refactor/rename clean-up

Ruben 8 months ago
parent
commit
9171b1da89

+ 30 - 0
src/PicView.Avalonia/Converters/ConversionHelper.cs

@@ -1,4 +1,6 @@
 using ImageMagick;
+using PicView.Avalonia.Navigation;
+using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.FileHandling;
 using PicView.Core.ImageDecoding;
@@ -19,6 +21,20 @@ internal static class ConversionHelper
         var magickPercentage = new Percentage(percentage);
         return await SaveImageFileHelper.ResizeImageAsync(fileInfo, 0, 0, 100, magickPercentage).ConfigureAwait(false);
     }
+    
+    public static async Task ResizeImageByPercentage(int percentage, MainViewModel vm)
+    {
+        SetTitleHelper.SetLoadingTitle(vm);
+        var success = await ResizeImageByPercentage(vm.FileInfo, percentage);
+        if (success)
+        {
+            await NavigationManager.QuickReload();
+        }
+        else
+        {
+            SetTitleHelper.SetTitle(vm);
+        }
+    }
 
     internal static async Task<bool> ResizeByWidth(FileInfo fileInfo, double width)
     {
@@ -71,6 +87,20 @@ internal static class ConversionHelper
         return newPath;
     }
     
+    public static async Task ConvertFileExtension(int index, MainViewModel vm)
+    {
+        if (vm.FileInfo is null)
+        {
+            return;
+        }
+
+        var newPath = await ConvertTask(vm.FileInfo, index);
+        if (!string.IsNullOrWhiteSpace(newPath))
+        {
+            await NavigationManager.LoadPicFromStringAsync(newPath, vm);
+        }
+    }
+    
     public static void DetermineIfOptimizeImageShouldBeEnabled(MainViewModel vm)
     {
         if (vm.FileInfo is null)

+ 1 - 1
src/PicView.Avalonia/Input/MainKeyboardShortcuts.cs

@@ -68,7 +68,7 @@ public static class MainKeyboardShortcuts
             case Key.F12:
                 // Show Avalonia DevTools in DEBUG mode
                 return;
-            case Key.F8:
+            case Key.F7:
                 await FunctionsHelper.Invalidate();
                 return;
             case Key.F9:

+ 55 - 0
src/PicView.Avalonia/LockScreen/LockScreenHelper.cs

@@ -0,0 +1,55 @@
+using System.Diagnostics;
+using PicView.Avalonia.ImageHandling;
+using PicView.Avalonia.UI;
+using PicView.Avalonia.ViewModels;
+using PicView.Core.Localization;
+
+namespace PicView.Avalonia.LockScreen;
+
+public static class LockScreenHelper
+{
+    public static async Task SetAsLockScreenTask(string path, MainViewModel vm)
+    {
+        if (string.IsNullOrWhiteSpace(path))
+        {
+            return;
+        }
+        if (vm.PlatformService is null)
+        {
+            return;
+        }
+        
+        vm.IsLoading = true;
+
+        try
+        {
+            var file = await ImageFormatConverter.ConvertToCommonSupportedFormatAsync(path, vm).ConfigureAwait(false);
+
+            var process = new Process
+            {
+                StartInfo = new ProcessStartInfo
+                {
+                    Verb = "runas",
+                    UseShellExecute = true,
+                    FileName = "PicView.exe",
+                    Arguments = "lockscreen," + file,
+                    WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory
+                }
+            };
+            process.Start();
+            await TooltipHelper.ShowTooltipMessageAsync(TranslationHelper.Translation.Applying, true);
+            await process.WaitForExitAsync();
+        }
+        catch (Exception e)
+        {
+            await TooltipHelper.ShowTooltipMessageAsync(e.Message, true);
+#if DEBUG
+            Console.WriteLine(e);   
+#endif
+        }
+        finally
+        {
+            vm.IsLoading = false;
+        }
+    }
+}

+ 567 - 639
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -1,5 +1,4 @@
-using System.Diagnostics;
-using System.Reactive;
+using System.Reactive;
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls.Primitives;
@@ -13,6 +12,7 @@ using PicView.Avalonia.ImageEffects;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.ImageTransformations;
 using PicView.Avalonia.Interfaces;
+using PicView.Avalonia.LockScreen;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.Wallpaper;
@@ -21,7 +21,6 @@ using PicView.Core.Calculations;
 using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.Gallery;
-using PicView.Core.Localization;
 using PicView.Core.ProcessHandling;
 using ReactiveUI;
 using ImageViewer = PicView.Avalonia.Views.ImageViewer;
@@ -31,7 +30,310 @@ namespace PicView.Avalonia.ViewModels;
 public class MainViewModel : ViewModelBase
 {
     public readonly IPlatformSpecificService? PlatformService;
-    
+
+    public MainViewModel(IPlatformSpecificService? platformSpecificService)
+    {
+        FunctionsHelper.Vm = this;
+        PlatformService = platformSpecificService;
+
+        #region Window commands
+
+        ExitCommand = ReactiveCommand.CreateFromTask(WindowFunctions.Close);
+        MinimizeCommand = ReactiveCommand.CreateFromTask(WindowFunctions.Minimize);
+        MaximizeCommand = ReactiveCommand.CreateFromTask(WindowFunctions.MaximizeRestore);
+        RestoreCommand = ReactiveCommand.Create(WindowFunctions.Restore);
+        ToggleFullscreenCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleFullscreen);
+        NewWindowCommand = ReactiveCommand.Create(ProcessHelper.StartNewProcess);
+
+        ShowExifWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowExifWindow);
+        ShowSettingsWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowSettingsWindow);
+        ShowKeybindingsWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowKeybindingsWindow);
+        ShowAboutWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowAboutWindow);
+        ShowBatchResizeWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowBatchResizeWindow);
+        ShowSingleImageResizeWindowCommand =
+            ReactiveCommand.Create(platformSpecificService.ShowSingleImageResizeWindow);
+        ShowEffectsWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowEffectsWindow);
+
+        #endregion Window commands
+
+        #region Navigation Commands
+
+        NextCommand = ReactiveCommand.Create(() => { Task.Run(FunctionsHelper.Next); });
+
+        NextButtonCommand = ReactiveCommand.Create(() =>
+        {
+            var button = UIHelper.GetBottomBar?.NextButton;
+            if (button != null)
+            {
+                button.Interval =
+                    (int)TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
+            }
+
+            Task.Run(() =>
+                NavigationManager.NavigateAndPositionCursor(true, false, this)
+            );
+        });
+
+        NextArrowButtonCommand = ReactiveCommand.Create(() =>
+        {
+            var button = UIHelper.GetMainView?.ClickArrowRight?.PolyButton;
+            if (button != null)
+            {
+                button.Interval =
+                    (int)TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
+            }
+
+            Task.Run(() =>
+                NavigationManager.NavigateAndPositionCursor(true, true, this)
+            );
+        });
+
+        NextFolderCommand = ReactiveCommand.Create(() => { Task.Run(FunctionsHelper.NextFolder); });
+
+        PreviousCommand = ReactiveCommand.Create(() => { Task.Run(FunctionsHelper.Prev); });
+
+        PreviousButtonCommand = ReactiveCommand.Create(() =>
+        {
+            var button = UIHelper.GetBottomBar?.PreviousButton;
+            if (button != null)
+            {
+                button.Interval =
+                    (int)TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
+            }
+
+            Task.Run(() =>
+                NavigationManager.NavigateAndPositionCursor(false, false, this)
+            );
+        });
+
+        PreviousArrowButtonCommand = ReactiveCommand.Create(() =>
+        {
+            var button = UIHelper.GetMainView?.ClickArrowLeft?.PolyButton;
+            if (button != null)
+            {
+                button.Interval =
+                    (int)TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
+            }
+
+            Task.Run(() =>
+                NavigationManager.NavigateAndPositionCursor(false, true, this)
+            );
+        });
+
+        PreviousFolderCommand = ReactiveCommand.Create(() => { Task.Run(FunctionsHelper.PrevFolder); });
+
+        Skip10Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Next10);
+
+        Skip100Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Next100);
+
+        Prev10Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Prev10);
+
+        Prev100Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Prev100);
+
+        FirstCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.First);
+
+        LastCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Last);
+
+        ReloadCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Reload);
+
+        #endregion Navigation Commands
+
+        #region Sort Commands
+
+        SortFilesByNameCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesByName);
+
+        SortFilesByCreationTimeCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesByCreationTime);
+
+        SortFilesByLastAccessTimeCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesByLastAccessTime);
+
+        SortFilesBySizeCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesBySize);
+
+        SortFilesByExtensionCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesByExtension);
+
+        SortFilesRandomlyCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesRandomly);
+
+        SortFilesAscendingCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesAscending);
+
+        SortFilesDescendingCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesDescending);
+
+        #endregion Sort Commands
+
+        #region Menus
+
+        CloseMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.CloseMenus);
+
+        ToggleFileMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleFileMenu);
+
+        ToggleImageMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleImageMenu);
+
+        ToggleSettingsMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleSettingsMenu);
+
+        ToggleToolsMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleToolsMenu);
+
+        #endregion Menus
+
+        #region Image commands
+
+        RotateLeftCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.RotateLeft);
+        RotateLeftButtonCommand = ReactiveCommand.CreateFromTask(async () =>
+        {
+            await Rotation.RotateLeft(this, Rotation.RotationButton.RotateLeftButton);
+        });
+
+        RotateRightCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.RotateRight);
+        RotateRightButtonCommand = ReactiveCommand.CreateFromTask(async () =>
+        {
+            await Rotation.RotateRight(this, Rotation.RotationButton.RotateRightButton);
+        });
+
+        RotateRightWindowBorderButtonCommand = ReactiveCommand.CreateFromTask(async () =>
+        {
+            await Rotation.RotateRight(this, Rotation.RotationButton.WindowBorderButton);
+        });
+
+        FlipCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Flip);
+
+        StretchCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Stretch);
+
+        CropCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Crop);
+
+        ToggleScrollCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleScroll);
+
+        OptimizeImageCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OptimizeImage);
+
+        ChangeBackgroundCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ChangeBackground);
+
+        ShowSideBySideCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SideBySide);
+
+        #endregion Image commands
+
+        #region File commands
+
+        OpenFileCommand = ReactiveCommand.Create(() => { Task.Run(FunctionsHelper.Open); });
+
+        OpenLastFileCommand = ReactiveCommand.Create(() => { Task.Run(FunctionsHelper.OpenLastFile); });
+
+        SaveFileCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Save);
+
+        SaveFileAsCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SaveAs);
+
+        CopyFileCommand = ReactiveCommand.CreateFromTask<string>(CopyFileTask);
+
+        CopyFilePathCommand = ReactiveCommand.CreateFromTask<string>(CopyFilePathTask);
+
+        FilePropertiesCommand = ReactiveCommand.CreateFromTask<string>(ShowFilePropertiesTask);
+
+        CopyImageCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.CopyImage);
+
+        CopyBase64Command = ReactiveCommand.CreateFromTask<string>(CopyBase64Task);
+
+        CutCommand = ReactiveCommand.CreateFromTask<string>(CutFileTask);
+
+        PasteCommand = ReactiveCommand.Create(() => { Task.Run(FunctionsHelper.Paste); });
+
+        OpenWithCommand = ReactiveCommand.CreateFromTask<string>(OpenWithTask);
+
+        RenameCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Rename);
+
+        ResizeCommand = ReactiveCommand.CreateFromTask<int>(ResizeImageByPercentage);
+        ConvertCommand = ReactiveCommand.CreateFromTask<int>(ConvertFileExtension);
+
+        DuplicateFileCommand = ReactiveCommand.CreateFromTask<string>(DuplicateFileTask);
+
+        PrintCommand = ReactiveCommand.CreateFromTask<string>(PrintTask);
+
+        DeleteFileCommand = ReactiveCommand.CreateFromTask<string>(DeleteFileTask);
+
+        RecycleFileCommand = ReactiveCommand.CreateFromTask<string>(RecycleFileTask);
+
+        LocateOnDiskCommand = ReactiveCommand.CreateFromTask<string>(LocateOnDiskTask);
+
+        SetAsWallpaperCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperTask);
+        SetAsWallpaperTiledCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperTiledTask);
+        SetAsWallpaperStretchedCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperStretchedTask);
+        SetAsWallpaperCenteredCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperCenteredTask);
+        SetAsWallpaperFilledCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperFilledTask);
+
+        SetAsLockScreenCommand = ReactiveCommand.CreateFromTask<string>(SetAsLockScreenTask);
+
+        #endregion File commands
+
+        #region EXIF commands
+
+        SetExifRating0Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set0Star);
+        SetExifRating1Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set1Star);
+        SetExifRating2Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set2Star);
+        SetExifRating3Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set3Star);
+        SetExifRating4Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set4Star);
+        SetExifRating5Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set5Star);
+
+        OpenGoogleLinkCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OpenGoogleMaps);
+        OpenBingLinkCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OpenBingMaps);
+
+        #endregion EXIF commands
+
+        #region Gallery Commands
+
+        ToggleGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleGallery);
+
+        ToggleBottomGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OpenCloseBottomGallery);
+
+        CloseGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.CloseGallery);
+
+        GalleryItemStretchCommand = ReactiveCommand.Create<string>(SetGalleryItemStretch);
+
+        #endregion Gallery Commands
+
+        #region UI Commands
+
+        ToggleUICommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleInterface);
+
+        ToggleBottomNavBarCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleBottomToolbar);
+
+        ToggleBottomGalleryShownInHiddenUICommand = ReactiveCommand.CreateFromTask(async () =>
+        {
+            await HideInterfaceLogic.ToggleBottomGalleryShownInHiddenUI(this);
+        });
+
+        ToggleFadeInButtonsOnHoverCommand = ReactiveCommand.CreateFromTask(async () =>
+        {
+            await HideInterfaceLogic.ToggleFadeInButtonsOnHover(this);
+        });
+
+        ChangeCtrlZoomCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ChangeCtrlZoom);
+
+        ColorPickerCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ColorPicker);
+
+        SlideshowCommand = ReactiveCommand.CreateFromTask<int>(StartSlideShowTask);
+
+        ToggleTaskbarProgressCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleTaskbarProgress);
+
+        #endregion UI Commands
+
+        #region Settings commands
+
+        ChangeAutoFitCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.AutoFitWindow);
+
+        ChangeTopMostCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SetTopMost);
+
+        ToggleSubdirectoriesCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleSubdirectories);
+
+        ToggleLoopingCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleLooping);
+
+        ResetSettingsCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ResetSettings);
+
+        RestartCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Restart);
+
+        ToggleUsingTouchpadCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleUsingTouchpad);
+
+        #endregion Settings commands
+    }
+
+    public MainViewModel()
+    {
+        // Only use for unit test
+    }
+
     #region Image
 
     public object? ImageSource
@@ -93,13 +395,13 @@ public class MainViewModel : ViewModelBase
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     } = double.NaN;
-    
+
     public double AspectRatio
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
-    
+
     public ImageEffectConfig? EffectConfig
     {
         get;
@@ -181,12 +483,16 @@ public class MainViewModel : ViewModelBase
 
             if (SettingsHelper.Settings.WindowProperties.Fullscreen)
             {
-                return SettingsHelper.Settings.Gallery.IsBottomGalleryShown ? GetBottomGalleryItemHeight + SizeDefaults.ScrollbarSize : 0;
+                return SettingsHelper.Settings.Gallery.IsBottomGalleryShown
+                    ? GetBottomGalleryItemHeight + SizeDefaults.ScrollbarSize
+                    : 0;
             }
+
             if (!SettingsHelper.Settings.Gallery.ShowBottomGalleryInHiddenUI && !IsUIShown)
             {
                 return 0;
             }
+
             return GetBottomGalleryItemHeight + SizeDefaults.ScrollbarSize;
         }
     }
@@ -219,16 +525,17 @@ public class MainViewModel : ViewModelBase
     {
         get => GalleryDefaults.MaxFullGalleryItemHeight;
     }
-    
+
     public double MinFullGalleryItemHeight
     {
         get => GalleryDefaults.MinFullGalleryItemHeight;
     }
+
     public double MaxBottomGalleryItemHeight
     {
         get => GalleryDefaults.MaxBottomGalleryItemHeight;
     }
-    
+
     public double MinBottomGalleryItemHeight
     {
         get => GalleryDefaults.MinBottomGalleryItemHeight;
@@ -359,7 +666,7 @@ public class MainViewModel : ViewModelBase
     public ReactiveCommand<Unit, Unit>? ExitCommand { get; }
     public ReactiveCommand<Unit, Unit>? MinimizeCommand { get; }
     public ReactiveCommand<Unit, Unit>? MaximizeCommand { get; }
-    
+
     public ReactiveCommand<Unit, Unit>? RestoreCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleFullscreenCommand { get; }
     public ReactiveCommand<Unit, Unit>? NextCommand { get; }
@@ -418,7 +725,7 @@ public class MainViewModel : ViewModelBase
     public ReactiveCommand<Unit, Unit>? ChangeBackgroundCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleBottomNavBarCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleBottomGalleryShownInHiddenUICommand { get; }
-    
+
     public ReactiveCommand<Unit, Unit>? ToggleFadeInButtonsOnHoverCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleTaskbarProgressCommand { get; }
     public ReactiveCommand<Unit, Unit>? ShowExifWindowCommand { get; }
@@ -461,21 +768,21 @@ public class MainViewModel : ViewModelBase
     public ReactiveCommand<Unit, Unit>? ColorPickerCommand { get; }
 
     public ReactiveCommand<int, Unit>? SlideshowCommand { get; }
-    
+
     public ReactiveCommand<string, Unit>? SetAsWallpaperCommand { get; }
     public ReactiveCommand<string, Unit>? SetAsWallpaperFilledCommand { get; }
     public ReactiveCommand<string, Unit>? SetAsWallpaperStretchedCommand { get; }
     public ReactiveCommand<string, Unit>? SetAsWallpaperTiledCommand { get; }
     public ReactiveCommand<string, Unit>? SetAsWallpaperCenteredCommand { get; }
-    
+
     public ReactiveCommand<string, Unit>? SetAsLockScreenCommand { get; }
-    
+
     public ReactiveCommand<string, Unit>? GalleryItemStretchCommand { get; }
-    
+
     public ReactiveCommand<Unit, Unit>? ResetSettingsCommand { get; }
-    
+
     public ReactiveCommand<Unit, Unit>? ShowSideBySideCommand { get; }
-    
+
     public ReactiveCommand<Unit, Unit>? RestartCommand { get; }
 
     #endregion Commands
@@ -483,13 +790,13 @@ public class MainViewModel : ViewModelBase
     #region Fields
 
     #region Booleans
-    
+
     public bool ShouldCropBeEnabled
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
-    
+
     public bool ShouldOptimizeImageBeEnabled
     {
         get;
@@ -552,7 +859,7 @@ public class MainViewModel : ViewModelBase
             ShouldMaximizeBeShown = !IsFullscreen && !IsMaximized;
         }
     }
-    
+
     public bool IsMaximized
     {
         get;
@@ -563,7 +870,7 @@ public class MainViewModel : ViewModelBase
             ShouldMaximizeBeShown = !IsFullscreen && !IsMaximized;
         }
     }
-    
+
     public bool ShouldRestore
     {
         get;
@@ -586,7 +893,7 @@ public class MainViewModel : ViewModelBase
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
-    } 
+    }
 
     public bool IsScrollingEnabled
     {
@@ -603,7 +910,7 @@ public class MainViewModel : ViewModelBase
             SettingsHelper.Settings.ImageScaling.StretchImage = value;
             WindowResizing.SetSize(this);
         }
-    } 
+    }
 
     public bool IsLooping
     {
@@ -636,7 +943,7 @@ public class MainViewModel : ViewModelBase
             SettingsHelper.Settings.UIProperties.OpenInSameWindow = value;
         }
     }
-    
+
     public bool IsShowingConfirmationOnEsc
     {
         get;
@@ -664,7 +971,7 @@ public class MainViewModel : ViewModelBase
     }
 
     #endregion Booleans
-    
+
     public Thickness TopScreenMargin
     {
         get;
@@ -676,13 +983,13 @@ public class MainViewModel : ViewModelBase
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
-    
+
     public CornerRadius BottomCornerRadius
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
-    
+
     public int BackgroundChoice
     {
         get;
@@ -691,23 +998,19 @@ public class MainViewModel : ViewModelBase
 
     public double WindowMinSize
     {
-        get
-        {
-            return SizeDefaults.WindowMinSize;
-        }
+        get { return SizeDefaults.WindowMinSize; }
     }
 
     public double TitlebarHeight
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
-    } 
+    }
 
     public double BottombarHeight
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
-        
     }
 
     // Used to flip the flip button
@@ -746,12 +1049,12 @@ public class MainViewModel : ViewModelBase
             this.RaiseAndSetIfChanged(ref field, roundedValue);
             SettingsHelper.Settings.UIProperties.SlideShowTimer = roundedValue;
         }
-    } 
+    }
 
     public double GetNavSpeed
     {
         get => Math.Round(field, 2);
-        set 
+        set
         {
             this.RaiseAndSetIfChanged(ref field, value);
             SettingsHelper.Settings.UIProperties.NavSpeed = value;
@@ -767,7 +1070,7 @@ public class MainViewModel : ViewModelBase
             this.RaiseAndSetIfChanged(ref field, roundedValue);
             SettingsHelper.Settings.Zoom.ZoomSpeed = roundedValue;
         }
-    } 
+    }
 
     #region strings
 
@@ -777,879 +1080,504 @@ public class MainViewModel : ViewModelBase
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetIsShowingBottomToolbarTranslation
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetIsShowingFadingUIButtonsTranslation
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetIsUsingTouchpadTranslation
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetIsFlippedTranslation
-    {
-        get => ScaleX == -1 ? UnFlip : Flip;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetIsShowingBottomGalleryTranslation
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetIsLoopingTranslation
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetIsScrollingTranslation
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetIsCtrlZoomTranslation
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetPrintSizeInch
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetPrintSizeCm
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetSizeMp
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetResolution
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetBitDepth
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetAspectRatio
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetLatitude
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetLongitude
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetAltitude
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GoogleLink
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? BingLink
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetAuthors
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetDateTaken
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetCopyright
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetTitle
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetSubject
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetSoftware
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetResolutionUnit
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetColorRepresentation
-    {
-        get;
-        set => this.RaiseAndSetIfChanged(ref field, value);
-    }
-
-    public string? GetCompression
+    public string? GetIsShowingBottomToolbarTranslation
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetCompressedBitsPixel
+    public string? GetIsShowingFadingUIButtonsTranslation
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetCameraMaker
+    public string? GetIsUsingTouchpadTranslation
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetCameraModel
+    public string? GetIsFlippedTranslation
     {
-        get;
+        get => ScaleX == -1 ? UnFlip : Flip;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetExposureProgram
+    public string? GetIsShowingBottomGalleryTranslation
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetExposureTime
+    public string? GetIsLoopingTranslation
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetExposureBias
+    public string? GetIsScrollingTranslation
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetFNumber
+    public string? GetIsCtrlZoomTranslation
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetMaxAperture
+    public string? GetPrintSizeInch
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetDigitalZoom
+    public string? GetPrintSizeCm
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetFocalLength35Mm
+    public string? GetSizeMp
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetFocalLength
+    public string? GetResolution
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetISOSpeed
+    public string? GetBitDepth
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetMeteringMode
+    public string? GetAspectRatio
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetContrast
+    public string? GetLatitude
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetSaturation
+    public string? GetLongitude
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetSharpness
+    public string? GetAltitude
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetWhiteBalance
+    public string? GoogleLink
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetFlashMode
+    public string? BingLink
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetFlashEnergy
+    public string? GetAuthors
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetLightSource
+    public string? GetDateTaken
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetBrightness
+    public string? GetCopyright
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetPhotometricInterpretation
+    public string? GetTitle
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetOrientation
+    public string? GetSubject
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetExifVersion
+    public string? GetSoftware
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetLensModel
+    public string? GetResolutionUnit
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public string? GetLensMaker
+    public string? GetColorRepresentation
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    #endregion strings
-
-    #region Window Properties
-
-    public string? Title
+    public string? GetCompression
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
-    } = "Loading...";
+    }
 
-    public string? TitleTooltip
+    public string? GetCompressedBitsPixel
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
-    } = "Loading...";
+    }
 
-    public string? WindowTitle
+    public string? GetCameraMaker
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
-    } = "PicView";
+    }
 
-    public SizeToContent SizeToContent
+    public string? GetCameraModel
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public bool CanResize
+    public string? GetExposureProgram
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    #endregion Window Properties
-
-    #region Size
-
-    public double TitleMaxWidth
+    public string? GetExposureTime
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    #endregion Size
-
-    #region Zoom
-
-    public double RotationAngle
+    public string? GetExposureBias
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public double ZoomValue
+    public string? GetFNumber
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public ScrollBarVisibility ToggleScrollBarVisibility
+    public string? GetMaxAperture
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    #endregion Zoom
-
-    #region Menus
-
-    public bool IsFileMenuVisible
+    public string? GetDigitalZoom
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public bool IsImageMenuVisible
+    public string? GetFocalLength35Mm
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public bool IsSettingsMenuVisible
+    public string? GetFocalLength
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public bool IsToolsMenuVisible
+    public string? GetISOSpeed
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    #endregion Menus
-
-    #endregion Fields
-
-    #region Methods
-
-    #region Sorting Order
-
-    public FileListHelper.SortFilesBy SortOrder
+    public string? GetMeteringMode
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    public bool IsAscending
+    public string? GetContrast
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    #endregion Sorting Order
-
-    private async Task ResizeImageByPercentage(int percentage)
-    {
-        SetTitleHelper.SetLoadingTitle(this);
-        var success = await ConversionHelper.ResizeImageByPercentage(FileInfo, percentage);
-        if (success)
-        {
-            await NavigationManager.QuickReload();
-        }
-        else
-        {
-            SetTitleHelper.SetTitle(this);
-        }
-    }
-
-    private async Task ConvertFileExtension(int index)
+    public string? GetSaturation
     {
-        if (FileInfo is null)
-        {
-            return;
-        }
-
-        var newPath = await ConversionHelper.ConvertTask(FileInfo, index);
-        if (!string.IsNullOrWhiteSpace(newPath))
-        {
-            await NavigationManager.LoadPicFromStringAsync(newPath, this);
-        }
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
     }
-    
-    private async Task CopyFileTask(string path) => await ClipboardHelper.CopyFileToClipboard(path, this);
-    
-    private async Task CopyFilePathTask(string path) => await ClipboardHelper.CopyTextToClipboard(path);
-    
-    private async Task CopyBase64Task(string path) => await ClipboardHelper.CopyBase64ToClipboard(path, this);
-    
-    private async Task CutFileTask(string path) => await ClipboardHelper.CutFile(path, this);
-    
-    private async Task DeleteFileTask(string path)=> await Task.Run(() => FileDeletionHelper.DeleteFileWithErrorMsg(path, recycle: false));
-    
-    private static async Task RecycleFileTask(string path) => await Task.Run(() => FileDeletionHelper.DeleteFileWithErrorMsg(path, recycle: true));
 
-    private async Task DuplicateFileTask(string path) => await FileManager.DuplicateFile(path, this).ConfigureAwait(false);
-    
-    private async Task ShowFilePropertiesTask(string path) => await FileManager.ShowFileProperties(path, this).ConfigureAwait(false);
-
-    private async Task PrintTask(string path) => await FileManager.Print(path, this).ConfigureAwait(false);
-    
-    private async Task OpenWithTask(string path) => await FileManager.Print(path, this).ConfigureAwait(false);
-    
-    private async Task LocateOnDiskTask(string path) => await FileManager.LocateOnDisk(path, this).ConfigureAwait(false);
-    
-    public async Task SetAsWallpaperTask(string path) => await SetAsWallpaperTask(path, WallpaperStyle.Fit).ConfigureAwait(false);
-    
-    public async Task SetAsWallpaperFilledTask(string path) => await SetAsWallpaperTask(path, WallpaperStyle.Fill).ConfigureAwait(false);
-    
-    public async Task SetAsWallpaperTiledTask(string path) => await SetAsWallpaperTask(path, WallpaperStyle.Tile).ConfigureAwait(false);
-    
-    public async Task SetAsWallpaperStretchedTask(string path) => await SetAsWallpaperTask(path, WallpaperStyle.Stretch).ConfigureAwait(false);
-    
-    public async Task SetAsWallpaperCenteredTask(string path) => await SetAsWallpaperTask(path, WallpaperStyle.Center).ConfigureAwait(false);
-
-    public async Task SetAsWallpaperTask(string path, WallpaperStyle style) =>
-        await WallpaperManager.SetAsWallpaper(path, style, this).ConfigureAwait(false);
-    
-    private async Task SetAsLockScreenTask(string path)
+    public string? GetSharpness
     {
-        if (string.IsNullOrWhiteSpace(path))
-        {
-            return;
-        }
-        if (PlatformService is null)
-        {
-            return;
-        }
-        
-        IsLoading = true;
-
-        try
-        {
-            var file = await ImageFormatConverter.ConvertToCommonSupportedFormatAsync(path, this).ConfigureAwait(false);
-
-            var process = new Process
-            {
-                StartInfo = new ProcessStartInfo
-                {
-                    Verb = "runas",
-                    UseShellExecute = true,
-                    FileName = "PicView.exe",
-                    Arguments = "lockscreen," + file,
-                    WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory
-                }
-            };
-            process.Start();
-            await TooltipHelper.ShowTooltipMessageAsync(TranslationHelper.Translation.Applying, true);
-            await process.WaitForExitAsync();
-        }
-        catch (Exception e)
-        {
-            await TooltipHelper.ShowTooltipMessageAsync(e.Message, true);
-#if DEBUG
-         Console.WriteLine(e);   
-#endif
-        }
-        finally
-        {
-            IsLoading = false;
-        }
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
     }
 
-    private void SetGalleryItemStretch(string value) => GalleryHelper.SetGalleryItemStretch(value, this);
-
-    public async Task StartSlideShowTask(int milliseconds) => await Avalonia.Navigation.Slideshow.StartSlideshow(this, milliseconds);
-
-    #endregion Methods
-
-    public MainViewModel(IPlatformSpecificService? platformSpecificService)
+    public string? GetWhiteBalance
     {
-        FunctionsHelper.Vm = this;
-        PlatformService = platformSpecificService;
-
-        #region Window commands
-
-        ExitCommand = ReactiveCommand.CreateFromTask(WindowFunctions.Close);
-        MinimizeCommand = ReactiveCommand.CreateFromTask(WindowFunctions.Minimize);
-        MaximizeCommand = ReactiveCommand.CreateFromTask(WindowFunctions.MaximizeRestore);
-        RestoreCommand = ReactiveCommand.Create(WindowFunctions.Restore);
-        ToggleFullscreenCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleFullscreen);
-        NewWindowCommand = ReactiveCommand.Create(ProcessHelper.StartNewProcess);
-
-        ShowExifWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowExifWindow);
-        ShowSettingsWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowSettingsWindow);
-        ShowKeybindingsWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowKeybindingsWindow);
-        ShowAboutWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowAboutWindow);
-        ShowBatchResizeWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowBatchResizeWindow);
-        ShowSingleImageResizeWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowSingleImageResizeWindow);
-        ShowEffectsWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowEffectsWindow);
-        #endregion Window commands
-
-        #region Navigation Commands
-
-        NextCommand = ReactiveCommand.Create(() =>
-        {
-            Task.Run(FunctionsHelper.Next);
-        });
-        
-        NextButtonCommand = ReactiveCommand.Create(() =>
-        {
-            var button = UIHelper.GetBottomBar?.NextButton;
-            if (button != null)
-            {
-                button.Interval =
-                    (int)TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
-            }
-
-            Task.Run(() =>
-               NavigationManager.NavigateAndPositionCursor(next: true, arrow: false, vm: this)
-            );
-        });
-        
-        NextArrowButtonCommand = ReactiveCommand.Create( () =>
-        {
-            var button = UIHelper.GetMainView?.ClickArrowRight?.PolyButton;
-            if (button != null)
-            {
-                button.Interval =
-                    (int)TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
-            }
-
-            Task.Run(() =>
-                NavigationManager.NavigateAndPositionCursor(next:true, arrow: true, vm: this)
-            );
-        });
-        
-        NextFolderCommand = ReactiveCommand.Create(() =>
-        {
-            Task.Run(FunctionsHelper.NextFolder);
-        });
-        
-        PreviousCommand = ReactiveCommand.Create(() =>
-        {
-            Task.Run(FunctionsHelper.Prev);
-        });
-        
-        PreviousButtonCommand = ReactiveCommand.Create( () =>
-        {
-            var button = UIHelper.GetBottomBar?.PreviousButton;
-            if (button != null)
-            {
-                button.Interval =
-                    (int)TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
-            }
-
-            Task.Run(() =>
-                NavigationManager.NavigateAndPositionCursor(next:false, arrow: false, vm: this)
-            );
-        });
-        
-        PreviousArrowButtonCommand = ReactiveCommand.Create( () =>
-        {
-            var button = UIHelper.GetMainView?.ClickArrowLeft?.PolyButton;
-            if (button != null)
-            {
-                button.Interval =
-                    (int)TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
-            }
-
-            Task.Run(() =>
-                NavigationManager.NavigateAndPositionCursor(next:false, arrow: true, vm: this)
-            );
-        });
-        
-        PreviousFolderCommand = ReactiveCommand.Create(() =>
-        {
-            Task.Run(FunctionsHelper.PrevFolder);
-        });
-        
-        Skip10Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Next10);
-
-        Skip100Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Next100);
-        
-        Prev10Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Prev10);
-
-        Prev100Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Prev100);
-
-        FirstCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.First);
-
-        LastCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Last);
-
-        ReloadCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Reload);
-
-        #endregion Navigation Commands
-
-        #region Sort Commands
-
-        SortFilesByNameCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesByName);
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        SortFilesByCreationTimeCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesByCreationTime);
+    public string? GetFlashMode
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        SortFilesByLastAccessTimeCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesByLastAccessTime);
+    public string? GetFlashEnergy
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        SortFilesBySizeCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesBySize);
+    public string? GetLightSource
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        SortFilesByExtensionCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesByExtension);
+    public string? GetBrightness
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        SortFilesRandomlyCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesRandomly);
+    public string? GetPhotometricInterpretation
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        SortFilesAscendingCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesAscending);
+    public string? GetOrientation
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        SortFilesDescendingCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SortFilesDescending);
+    public string? GetExifVersion
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        #endregion Sort Commands
+    public string? GetLensModel
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        #region Menus
+    public string? GetLensMaker
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        CloseMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.CloseMenus);
+    #endregion strings
 
-        ToggleFileMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleFileMenu);
+    #region Window Properties
 
-        ToggleImageMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleImageMenu);
+    public string? Title
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    } = "Loading...";
 
-        ToggleSettingsMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleSettingsMenu);
+    public string? TitleTooltip
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    } = "Loading...";
 
-        ToggleToolsMenuCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleToolsMenu);
+    public string? WindowTitle
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    } = "PicView";
 
-        #endregion Menus
+    public SizeToContent SizeToContent
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        #region Image commands
+    public bool CanResize
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        RotateLeftCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.RotateLeft);
-        RotateLeftButtonCommand = ReactiveCommand.CreateFromTask(async () =>
-        {
-            await Rotation.RotateLeft(this, Rotation.RotationButton.RotateLeftButton);
-        });
+    #endregion Window Properties
 
-        RotateRightCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.RotateRight);
-        RotateRightButtonCommand = ReactiveCommand.CreateFromTask(async () =>
-        {
-            await Rotation.RotateRight(this, Rotation.RotationButton.RotateRightButton);
-        });
-        
-        RotateRightWindowBorderButtonCommand = ReactiveCommand.CreateFromTask(async () =>
-        {
-            await Rotation.RotateRight(this, Rotation.RotationButton.WindowBorderButton);
-        });
+    #region Size
 
-        FlipCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Flip);
+    public double TitleMaxWidth
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        StretchCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Stretch);
+    #endregion Size
 
-        CropCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Crop);
+    #region Zoom
 
-        ToggleScrollCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleScroll);
+    public double RotationAngle
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        OptimizeImageCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OptimizeImage);
-        
-        ChangeBackgroundCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ChangeBackground);
-        
-        ShowSideBySideCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SideBySide);
+    public double ZoomValue
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        #endregion Image commands
+    public ScrollBarVisibility ToggleScrollBarVisibility
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        #region File commands
-        
-        OpenFileCommand = ReactiveCommand.Create( () =>
-        {
-            Task.Run(FunctionsHelper.Open);
-        });
-        
-        OpenLastFileCommand = ReactiveCommand.Create( () =>
-        {
-            Task.Run(FunctionsHelper.OpenLastFile);
-        });
+    #endregion Zoom
 
-        SaveFileCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Save);
+    #region Menus
 
-        SaveFileAsCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SaveAs);
+    public bool IsFileMenuVisible
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        CopyFileCommand = ReactiveCommand.CreateFromTask<string>(CopyFileTask);
+    public bool IsImageMenuVisible
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        CopyFilePathCommand = ReactiveCommand.CreateFromTask<string>(CopyFilePathTask);
-        
-        FilePropertiesCommand = ReactiveCommand.CreateFromTask<string>(ShowFilePropertiesTask);
+    public bool IsSettingsMenuVisible
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        CopyImageCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.CopyImage);
-        
-        CopyBase64Command = ReactiveCommand.CreateFromTask<string>(CopyBase64Task);
+    public bool IsToolsMenuVisible
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        CutCommand = ReactiveCommand.CreateFromTask<string>(CutFileTask);
-        
-        PasteCommand = ReactiveCommand.Create( () =>
-        {
-            Task.Run(FunctionsHelper.Paste);
-        });
+    #endregion Menus
 
-        OpenWithCommand = ReactiveCommand.CreateFromTask<string>(OpenWithTask);
+    #endregion Fields
 
-        RenameCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Rename);
+    #region Methods
 
-        ResizeCommand = ReactiveCommand.CreateFromTask<int>(ResizeImageByPercentage);
-        ConvertCommand = ReactiveCommand.CreateFromTask<int>(ConvertFileExtension);
+    #region Sorting Order
 
-        DuplicateFileCommand = ReactiveCommand.CreateFromTask<string>(DuplicateFileTask);
+    public FileListHelper.SortFilesBy SortOrder
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        PrintCommand = ReactiveCommand.CreateFromTask<string>(PrintTask);    
+    public bool IsAscending
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
-        DeleteFileCommand = ReactiveCommand.CreateFromTask<string>(DeleteFileTask);
+    #endregion Sorting Order
 
-        RecycleFileCommand = ReactiveCommand.CreateFromTask<string>(RecycleFileTask);
+    private async Task ResizeImageByPercentage(int percentage) =>
+        await ConversionHelper.ResizeImageByPercentage(percentage, this).ConfigureAwait(false);
 
-        LocateOnDiskCommand = ReactiveCommand.CreateFromTask<string>(LocateOnDiskTask);
-        
-        SetAsWallpaperCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperTask);
-        SetAsWallpaperTiledCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperTiledTask);
-        SetAsWallpaperStretchedCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperStretchedTask);
-        SetAsWallpaperCenteredCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperCenteredTask);
-        SetAsWallpaperFilledCommand = ReactiveCommand.CreateFromTask<string>(SetAsWallpaperFilledTask);
-        
-        SetAsLockScreenCommand = ReactiveCommand.CreateFromTask<string>(SetAsLockScreenTask);
+    private async Task ConvertFileExtension(int index) =>
+        await ConversionHelper.ConvertFileExtension(index, this).ConfigureAwait(false);
 
-        #endregion File commands
+    private async Task CopyFileTask(string path) => await ClipboardHelper.CopyFileToClipboard(path, this);
 
-        #region EXIF commands
+    private static async Task CopyFilePathTask(string path) => await ClipboardHelper.CopyTextToClipboard(path);
 
-        SetExifRating0Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set0Star);
-        SetExifRating1Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set1Star);
-        SetExifRating2Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set2Star);
-        SetExifRating3Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set3Star);
-        SetExifRating4Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set4Star);
-        SetExifRating5Command = ReactiveCommand.CreateFromTask(FunctionsHelper.Set5Star);
+    private async Task CopyBase64Task(string path) => await ClipboardHelper.CopyBase64ToClipboard(path, this);
 
-        OpenGoogleLinkCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OpenGoogleMaps);
-        OpenBingLinkCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OpenBingMaps);
+    private async Task CutFileTask(string path) => await ClipboardHelper.CutFile(path, this);
 
-        #endregion EXIF commands
+    private async Task DeleteFileTask(string path) =>
+        await Task.Run(() => FileDeletionHelper.DeleteFileWithErrorMsg(path, false));
 
-        #region Gallery Commands
+    private static async Task RecycleFileTask(string path) =>
+        await Task.Run(() => FileDeletionHelper.DeleteFileWithErrorMsg(path, true));
 
-        ToggleGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleGallery);
+    private async Task DuplicateFileTask(string path) =>
+        await FileManager.DuplicateFile(path, this).ConfigureAwait(false);
 
-        ToggleBottomGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OpenCloseBottomGallery);
-        
-        CloseGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.CloseGallery);
-        
-        GalleryItemStretchCommand = ReactiveCommand.Create<string>(SetGalleryItemStretch);
+    private async Task ShowFilePropertiesTask(string path) =>
+        await FileManager.ShowFileProperties(path, this).ConfigureAwait(false);
 
-        #endregion Gallery Commands
+    private async Task PrintTask(string path) => await FileManager.Print(path, this).ConfigureAwait(false);
 
-        #region UI Commands
+    private async Task OpenWithTask(string path) => await FileManager.Print(path, this).ConfigureAwait(false);
 
-        ToggleUICommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleInterface);
+    private async Task LocateOnDiskTask(string path) =>
+        await FileManager.LocateOnDisk(path, this).ConfigureAwait(false);
 
-        ToggleBottomNavBarCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleBottomToolbar);
-        
-        ToggleBottomGalleryShownInHiddenUICommand = ReactiveCommand.CreateFromTask(async() =>
-        {
-            await HideInterfaceLogic.ToggleBottomGalleryShownInHiddenUI(this);
-        });
-        
-        ToggleFadeInButtonsOnHoverCommand = ReactiveCommand.CreateFromTask(async() =>
-        {
-            await HideInterfaceLogic.ToggleFadeInButtonsOnHover(this);
-        });
+    private async Task SetAsWallpaperTask(string path) =>
+        await SetAsWallpaperTask(path, WallpaperStyle.Fit).ConfigureAwait(false);
 
-        ChangeCtrlZoomCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ChangeCtrlZoom);
-        
-        ColorPickerCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ColorPicker);
-        
-        SlideshowCommand = ReactiveCommand.CreateFromTask<int>(StartSlideShowTask);
-        
-        ToggleTaskbarProgressCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleTaskbarProgress);
+    private async Task SetAsWallpaperFilledTask(string path) =>
+        await SetAsWallpaperTask(path, WallpaperStyle.Fill).ConfigureAwait(false);
 
-        #endregion UI Commands
+    private async Task SetAsWallpaperTiledTask(string path) =>
+        await SetAsWallpaperTask(path, WallpaperStyle.Tile).ConfigureAwait(false);
 
-        #region Settings commands
+    private async Task SetAsWallpaperStretchedTask(string path) =>
+        await SetAsWallpaperTask(path, WallpaperStyle.Stretch).ConfigureAwait(false);
 
-        ChangeAutoFitCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.AutoFitWindow);
+    private async Task SetAsWallpaperCenteredTask(string path) =>
+        await SetAsWallpaperTask(path, WallpaperStyle.Center).ConfigureAwait(false);
 
-        ChangeTopMostCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SetTopMost);
+    private async Task SetAsWallpaperTask(string path, WallpaperStyle style) =>
+        await WallpaperManager.SetAsWallpaper(path, style, this).ConfigureAwait(false);
 
-        ToggleSubdirectoriesCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleSubdirectories);
+    private async Task SetAsLockScreenTask(string path) =>
+        await LockScreenHelper.SetAsLockScreenTask(path, this).ConfigureAwait(false);
 
-        ToggleLoopingCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleLooping);
-        
-        ResetSettingsCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ResetSettings);
-        
-        RestartCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Restart);
-        
-        ToggleUsingTouchpadCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleUsingTouchpad);
+    private void SetGalleryItemStretch(string value) => GalleryHelper.SetGalleryItemStretch(value, this);
 
-        #endregion Settings commands
-    }
+    public async Task StartSlideShowTask(int milliseconds) =>
+        await Avalonia.Navigation.Slideshow.StartSlideshow(this, milliseconds);
 
-    public MainViewModel()
-    {
-        // Only use for unit test
-    }
-}
+    #endregion Methods
+}