Browse Source

Refactor core modules and file operations: restructure namespaces (`FileHandling` to `FileSorting`), replace `FileListHelper` with `FileSortHelper` and `FileListRetriever`, merge and relocate `Base64Helper` into `Base64Decoder`, remove unused custom controls, and update references across the project for clarity and consistency.

Ruben 4 months ago
parent
commit
0a23b59704
26 changed files with 155 additions and 305 deletions
  1. 2 1
      src/PicView.Avalonia.MacOS/App.axaml.cs
  2. 2 1
      src/PicView.Avalonia.Win32/App.axaml.cs
  3. 1 1
      src/PicView.Avalonia/Clipboard/ClipboardImageOperations.cs
  4. 5 5
      src/PicView.Avalonia/Converters/SortFilesByToBoolConverter.cs
  5. 1 1
      src/PicView.Avalonia/Crop/CropFunctions.cs
  6. 0 146
      src/PicView.Avalonia/CustomControls/PanAndZoomBorder.cs
  7. 1 1
      src/PicView.Avalonia/CustomControls/PicBox.cs
  8. 15 15
      src/PicView.Avalonia/Functions/FunctionsMapper.cs
  9. 10 10
      src/PicView.Avalonia/Navigation/FileListManager.cs
  10. 5 12
      src/PicView.Avalonia/Navigation/ImageIterator.cs
  11. 1 1
      src/PicView.Avalonia/Navigation/ImageLoader.cs
  12. 2 2
      src/PicView.Avalonia/ViewModels/MainViewModel.cs
  13. 2 1
      src/PicView.Avalonia/Views/BatchResizeView.axaml.cs
  14. 1 1
      src/PicView.Core.MacOS/FileAssociation/MacFileAssociationService.cs
  15. 1 1
      src/PicView.Core.WindowsNT/FileAssociation/WindowsFileAssociationService.cs
  16. 1 1
      src/PicView.Core/FileAssociations/IFileAssociationService.cs
  17. 1 0
      src/PicView.Core/FileHandling/FileAssociationManager.cs
  18. 4 59
      src/PicView.Core/FileSorting/FileListRetriever.cs
  19. 19 0
      src/PicView.Core/FileSorting/FileSortHelper.cs
  20. 41 0
      src/PicView.Core/FileSorting/SortFilesBy.cs
  21. 37 1
      src/PicView.Core/ImageDecoding/Base64Decoder.cs
  22. 0 40
      src/PicView.Core/ImageDecoding/Base64Helper.cs
  23. 1 1
      src/PicView.Core/ImageDecoding/ImageType.cs
  24. 0 1
      src/PicView.Core/Models/ImageModel.cs
  25. 1 1
      src/PicView.Core/Navigation/FileTypeResolver.cs
  26. 1 2
      src/PicView.Core/ViewModels/PicViewerModel.cs

+ 2 - 1
src/PicView.Avalonia.MacOS/App.axaml.cs

@@ -15,6 +15,7 @@ using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.WindowBehavior;
 using PicView.Core.FileHandling;
+using PicView.Core.FileSorting;
 using PicView.Core.Localization;
 using PicView.Core.MacOS;
 using PicView.Core.MacOS.FileAssociation;
@@ -122,7 +123,7 @@ public class App : Application, IPlatformSpecificService, IPlatformWindowService
 
     public List<string> GetFiles(FileInfo fileInfo)
     {
-        var files = FileListHelper.RetrieveFiles(fileInfo);
+        var files = FileListRetriever.RetrieveFiles(fileInfo);
         return FileListManager.SortIEnumerable(files, this);
     }
 

+ 2 - 1
src/PicView.Avalonia.Win32/App.axaml.cs

@@ -13,6 +13,7 @@ using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.Win32.Views;
 using PicView.Avalonia.Win32.WindowImpl;
 using PicView.Core.FileHandling;
+using PicView.Core.FileSorting;
 using PicView.Core.Localization;
 using PicView.Core.ProcessHandling;
 using PicView.Core.WindowsNT;
@@ -142,7 +143,7 @@ public class App : Application, IPlatformSpecificService, IPlatformWindowService
 
     public List<string> GetFiles(FileInfo fileInfo)
     {
-        var files = FileListHelper.RetrieveFiles(fileInfo);
+        var files = FileListRetriever.RetrieveFiles(fileInfo);
         return FileListManager.SortIEnumerable(files, this);
     }
 

+ 1 - 1
src/PicView.Avalonia/Clipboard/ClipboardImageOperations.cs

@@ -2,10 +2,10 @@ using System.Runtime.InteropServices;
 using Avalonia.Input;
 using Avalonia.Input.Platform;
 using Avalonia.Media.Imaging;
-using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.DebugTools;
+using PicView.Core.ImageDecoding;
 using PicView.Core.Localization;
 
 namespace PicView.Avalonia.Clipboard;

+ 5 - 5
src/PicView.Avalonia/Converters/SortFilesByToBoolConverter.cs

@@ -1,7 +1,7 @@
-using Avalonia.Data;
+using System.Globalization;
+using Avalonia.Data;
 using Avalonia.Data.Converters;
-using System.Globalization;
-using PicView.Core.FileHandling;
+using PicView.Core.FileSorting;
 
 namespace PicView.Avalonia.Converters;
 
@@ -9,8 +9,8 @@ public class SortFilesByToBoolConverter : IValueConverter
 {
     public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
     {
-        var sortOrder = FileListHelper.GetSortOrder();
-        if (Enum.TryParse<FileListHelper.SortFilesBy>(parameter as string, true, out var result))
+        var sortOrder = FileSortHelper.GetSortOrder();
+        if (Enum.TryParse<SortFilesBy>(parameter as string, true, out var result))
         {
             return sortOrder == result;
         }

+ 1 - 1
src/PicView.Avalonia/Crop/CropFunctions.cs

@@ -1,12 +1,12 @@
 using Avalonia;
 using Avalonia.Media.Imaging;
 using PicView.Avalonia.Functions;
-using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.Views.UC;
 using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Gallery;
+using PicView.Core.ImageDecoding;
 using PicView.Core.Localization;
 
 namespace PicView.Avalonia.Crop;

+ 0 - 146
src/PicView.Avalonia/CustomControls/PanAndZoomBorder.cs

@@ -1,146 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Media;
-
-namespace PicView.Avalonia.CustomControls;
-
-public class PanAndZoomBorder : Border
-{
-    protected override Type StyleKeyOverride => typeof(Border);
-    
-    private Point? _start;
-    private double _scale = 1.0;
-    
-    private TranslateTransform? _translateTransform;
-    private ScaleTransform? _scaleTransform;
-    
-    private Control? _parentControl;
-    private Control? _childControl;
-
-    public void Initialize(Control parentControl, Control childControl)
-    {
-        _parentControl = parentControl;
-        _childControl = childControl;
-        
-        _translateTransform = new TranslateTransform();
-        _scaleTransform = new ScaleTransform();
-        var transformGroup = new TransformGroup();
-        transformGroup.Children.Add(_scaleTransform);
-        transformGroup.Children.Add(_translateTransform);
-        RenderTransform = transformGroup;
-        
-        // Subscribe to pointer events for panning
-        PointerPressed += OnPointerPressed;
-        PointerMoved += OnPointerMoved;
-        PointerReleased += OnPointerReleased;
-
-        // Subscribe to mouse wheel event for zooming
-        _parentControl.AddHandler(PointerWheelChangedEvent, OnPointerWheelChanged, handledEventsToo: true);
-        _parentControl.PointerPressed += (_, e) =>
-        {
-            if (e.ClickCount == 2)
-            {
-                ResetZoom();
-            }
-        };
-    }
-    
-    private void OnPointerPressed(object? sender, PointerPressedEventArgs e)
-    {
-        if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
-        {
-            return;
-        }
-
-        if (e.ClickCount == 2)
-        {
-            ResetZoom();
-            return;
-        }
-        _start = e.GetPosition(this);
-        e.Pointer.Capture(this);
-    }
-
-    private void OnPointerMoved(object? sender, PointerEventArgs e)
-    {
-        if (!Equals(e.Pointer.Captured, this))
-        {
-            return;
-        }
-        Pan(e);
-    }
-
-    private void OnPointerReleased(object? sender, PointerReleasedEventArgs e)
-    {
-        if (Equals(e.Pointer.Captured, this))
-        {
-            e.Pointer.Capture(null);
-        }
-    }
-
-    private void OnPointerWheelChanged(object? sender, PointerWheelEventArgs e)
-    {
-        var animate = true; // TODO replace with setting one day
-        Zoom(e, animate);
-        e.Handled = true;
-    }
-
-    #region Pan
-
-    private void Pan(PointerEventArgs e)
-    {
-        var position = e.GetPosition(this);
-        var delta = position - _start;
-        if (!delta.HasValue)
-        {
-            return;
-        }
-        var x = _translateTransform.X + delta.Value.X;
-        var y =_translateTransform.Y + delta.Value.Y;
-        _start = position;
-        _translateTransform.X = x;
-        _translateTransform.Y = y;
-        InvalidateVisual();
-    }
-
-    #endregion
-
-    #region Zoom
-    
-    public void Zoom(PointerWheelEventArgs e, bool animate = true)
-    {
-        var delta = e.Delta.Y > 0 ? 1.1 : 1.0 / 1.1;
-
-        var position = e.GetPosition(_parentControl);
-        RenderTransformOrigin = new RelativePoint(position, RelativeUnit.Absolute);
-        var relativeX = position.X / Bounds.Width;
-        var relativeY = position.Y / Bounds.Height;
-
-        var newScale = _scale * delta;
-
-        // Prevent zooming out too much
-        if (newScale < 0.1) return;
-
-        _scale = newScale;
-        _scaleTransform.ScaleX = relativeX * Bounds.Width;
-        _scaleTransform.ScaleY = relativeY * Bounds.Height;
-        _scaleTransform.ScaleX = _scale;
-        _scaleTransform.ScaleY = _scale;
-        InvalidateVisual();
-    }
-
-    private void ResetZoom()
-    {
-        _scale = 1.0;
-        _scaleTransform.ScaleX = 1.0;
-        _scaleTransform.ScaleY = 1.0;
-        _translateTransform.X = 0;
-        _translateTransform.Y = 0;
-        InvalidateVisual();
-    }
-
-    #endregion
-
-    
-}

+ 1 - 1
src/PicView.Avalonia/CustomControls/PicBox.cs

@@ -11,11 +11,11 @@ using Avalonia.Rendering.Composition;
 using Avalonia.Svg.Skia;
 using ImageMagick;
 using PicView.Avalonia.AnimatedImage;
-using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.DebugTools;
+using PicView.Core.ImageDecoding;
 using ReactiveUI;
 using Vector = Avalonia.Vector;
 

+ 15 - 15
src/PicView.Avalonia/Functions/FunctionsMapper.cs

@@ -13,8 +13,8 @@ using PicView.Avalonia.SettingsManagement;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.WindowBehavior;
-using PicView.Core.FileHandling;
 using PicView.Core.FileHistory;
+using PicView.Core.FileSorting;
 using PicView.Core.ImageDecoding;
 using PicView.Core.Keybindings;
 using PicView.Core.ProcessHandling;
@@ -655,33 +655,33 @@ public static class FunctionsMapper
 
     #region Sorting
 
-    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileListHelper.SortFilesBy)" />
+    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileSortHelper.SortFilesBy)" />
     public static async Task SortFilesByName() =>
-        await FileListManager.UpdateFileList(Vm.PlatformService, Vm, FileListHelper.SortFilesBy.Name).ConfigureAwait(false);
+        await FileListManager.UpdateFileList(Vm.PlatformService, Vm, SortFilesBy.Name).ConfigureAwait(false);
 
-    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileListHelper.SortFilesBy)" />
+    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileSortHelper.SortFilesBy)" />
     public static async Task SortFilesByCreationTime() =>
-        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, FileListHelper.SortFilesBy.CreationTime).ConfigureAwait(false);
+        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, SortFilesBy.CreationTime).ConfigureAwait(false);
 
-    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileListHelper.SortFilesBy)" />
+    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileSortHelper.SortFilesBy)" />
     public static async Task SortFilesByLastAccessTime() =>
-        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, FileListHelper.SortFilesBy.LastAccessTime).ConfigureAwait(false);
+        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, SortFilesBy.LastAccessTime).ConfigureAwait(false);
 
-    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileListHelper.SortFilesBy)" />
+    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileSortHelper.SortFilesBy)" />
     public static async Task SortFilesByLastWriteTime() =>
-        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, FileListHelper.SortFilesBy.LastWriteTime).ConfigureAwait(false);
+        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, SortFilesBy.LastWriteTime).ConfigureAwait(false);
 
-    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileListHelper.SortFilesBy)" />
+    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileSortHelper.SortFilesBy)" />
     public static async Task SortFilesBySize() =>
-        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, FileListHelper.SortFilesBy.FileSize).ConfigureAwait(false);
+        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, SortFilesBy.FileSize).ConfigureAwait(false);
 
-    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileListHelper.SortFilesBy)" />
+    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileSortHelper.SortFilesBy)" />
     public static async Task SortFilesByExtension() =>
-        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, FileListHelper.SortFilesBy.Extension).ConfigureAwait(false);
+        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, SortFilesBy.Extension).ConfigureAwait(false);
 
-    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileListHelper.SortFilesBy)" />
+    /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, FileSortHelper.SortFilesBy)" />
     public static async Task SortFilesRandomly() =>
-        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, FileListHelper.SortFilesBy.Random).ConfigureAwait(false);
+        await FileListManager.UpdateFileList(Vm?.PlatformService, Vm, SortFilesBy.Random).ConfigureAwait(false);
 
     /// <inheritdoc cref="FileListManager.UpdateFileList(PicView.Avalonia.Interfaces.IPlatformSpecificService, MainViewModel, bool)" />
     public static async Task SortFilesAscending() =>

+ 10 - 10
src/PicView.Avalonia/Navigation/FileListManager.cs

@@ -2,7 +2,7 @@
 using PicView.Avalonia.Interfaces;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
-using PicView.Core.FileHandling;
+using PicView.Core.FileSorting;
 
 namespace PicView.Avalonia.Navigation;
 
@@ -21,12 +21,12 @@ public static class FileListManager
     /// <returns>A sorted list of file paths.</returns>
     public static List<string> SortIEnumerable(IEnumerable<string> files, IPlatformSpecificService? platformService)
     {
-        var sortFilesBy = FileListHelper.GetSortOrder();
+        var sortFilesBy = FileSortHelper.GetSortOrder();
 
         switch (sortFilesBy)
         {
             default:
-            case FileListHelper.SortFilesBy.Name: // Alphanumeric sort
+            case SortFilesBy.Name: // Alphanumeric sort
                 var list = files.ToList();
                 if (Settings.Sorting.Ascending)
                 {
@@ -39,38 +39,38 @@ public static class FileListManager
 
                 return list;
 
-            case FileListHelper.SortFilesBy.FileSize: // Sort by file size
+            case SortFilesBy.FileSize: // Sort by file size
                 var fileInfoList = files.Select(f => new FileInfo(f)).ToList();
                 var sortedBySize = Settings.Sorting.Ascending
                     ? fileInfoList.OrderBy(f => f.Length)
                     : fileInfoList.OrderByDescending(f => f.Length);
                 return sortedBySize.Select(f => f.FullName).ToList();
 
-            case FileListHelper.SortFilesBy.Extension: // Sort by file extension
+            case SortFilesBy.Extension: // Sort by file extension
                 var sortedByExtension = Settings.Sorting.Ascending
                     ? files.OrderBy(Path.GetExtension)
                     : files.OrderByDescending(Path.GetExtension);
                 return sortedByExtension.ToList();
 
-            case FileListHelper.SortFilesBy.CreationTime: // Sort by file creation time
+            case SortFilesBy.CreationTime: // Sort by file creation time
                 var sortedByCreationTime = Settings.Sorting.Ascending
                     ? files.OrderBy(f => new FileInfo(f).CreationTime)
                     : files.OrderByDescending(f => new FileInfo(f).CreationTime);
                 return sortedByCreationTime.ToList();
 
-            case FileListHelper.SortFilesBy.LastAccessTime: // Sort by file last access time
+            case SortFilesBy.LastAccessTime: // Sort by file last access time
                 var sortedByLastAccessTime = Settings.Sorting.Ascending
                     ? files.OrderBy(f => new FileInfo(f).LastAccessTime)
                     : files.OrderByDescending(f => new FileInfo(f).LastAccessTime);
                 return sortedByLastAccessTime.ToList();
 
-            case FileListHelper.SortFilesBy.LastWriteTime: // Sort by file last write time
+            case SortFilesBy.LastWriteTime: // Sort by file last write time
                 var sortedByLastWriteTime = Settings.Sorting.Ascending
                     ? files.OrderBy(f => new FileInfo(f).LastWriteTime)
                     : files.OrderByDescending(f => new FileInfo(f).LastWriteTime);
                 return sortedByLastWriteTime.ToList();
 
-            case FileListHelper.SortFilesBy.Random: // Sort files randomly
+            case SortFilesBy.Random: // Sort files randomly
                 return files.OrderBy(f => Guid.NewGuid()).ToList();
         }
     }
@@ -81,7 +81,7 @@ public static class FileListManager
     /// <param name="platformSpecificService">Platform-specific service for file retrieval and sorting.</param>
     /// <param name="vm">The main view model instance.</param>
     /// <param name="sortFilesBy">The sort order to apply.</param>
-    public static async Task UpdateFileList(IPlatformSpecificService? platformSpecificService, MainViewModel vm, FileListHelper.SortFilesBy sortFilesBy)
+    public static async Task UpdateFileList(IPlatformSpecificService? platformSpecificService, MainViewModel vm, SortFilesBy sortFilesBy)
     {
         Settings.Sorting.SortPreference = (int)sortFilesBy;
         if (!NavigationManager.CanNavigate(vm))

+ 5 - 12
src/PicView.Avalonia/Navigation/ImageIterator.cs

@@ -8,6 +8,7 @@ using PicView.Avalonia.ViewModels;
 using PicView.Core.DebugTools;
 using PicView.Core.FileHandling;
 using PicView.Core.FileHistory;
+using PicView.Core.FileSorting;
 using PicView.Core.Gallery;
 using PicView.Core.Models;
 using PicView.Core.Navigation;
@@ -216,10 +217,7 @@ public class ImageIterator : IAsyncDisposable
         }
         catch (Exception exception)
         {
-#if DEBUG
-            Console.WriteLine(
-                $"{nameof(ImageIterator)}.{nameof(OnFileAdded)} {exception.Message} \n{exception.StackTrace}");
-#endif
+            DebugHelper.LogDebug(nameof(ImageIterator), nameof(OnFileAdded), exception);
         }
         finally
         {
@@ -249,9 +247,7 @@ public class ImageIterator : IAsyncDisposable
 
             if (!ImagePaths.Remove(e.FullPath))
             {
-#if DEBUG
-                Console.WriteLine($"Failed to remove {e.FullPath}");
-#endif
+                DebugHelper.LogDebug(nameof(ImageIterator), nameof(OnFileDeleted), $"Failed to remove {e.FullPath}");
                 return;
             }
 
@@ -305,10 +301,7 @@ public class ImageIterator : IAsyncDisposable
         }
         catch (Exception exception)
         {
-#if DEBUG
-            Console.WriteLine(
-                $"{nameof(ImageIterator)}.{nameof(OnFileDeleted)} {exception.Message} \n{exception.StackTrace}");
-#endif
+            DebugHelper.LogDebug(nameof(ImageIterator), nameof(OnFileDeleted), exception);
         }
         finally
         {
@@ -344,7 +337,7 @@ public class ImageIterator : IAsyncDisposable
             var sourceFileInfo = Settings.Sorting.IncludeSubDirectories
                 ? new FileInfo(_watcher.Path)
                 : fileInfo;
-            var newList = FileListHelper.RetrieveFiles(sourceFileInfo).ToList();
+            var newList = FileListRetriever.RetrieveFiles(sourceFileInfo).ToList();
             if (newList.Count == 0)
             {
                 return;

+ 1 - 1
src/PicView.Avalonia/Navigation/ImageLoader.cs

@@ -405,7 +405,7 @@ public static class ImageLoader
         {
             try
             {
-                var magickImage = ImageDecoder.Base64ToMagickImage(base64);
+                var magickImage = Base64Decoder.Base64ToMagickImage(base64);
                 magickImage.Format = MagickFormat.Png;
                 var bitmap = magickImage.ToWriteableBitmap();
                 var imageModel = new ImageModel

+ 2 - 2
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -16,7 +16,7 @@ using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.Wallpaper;
 using PicView.Avalonia.WindowBehavior;
-using PicView.Core.FileHandling;
+using PicView.Core.FileSorting;
 using PicView.Core.Gallery;
 using PicView.Core.ProcessHandling;
 using PicView.Core.Sizing;
@@ -691,7 +691,7 @@ public class MainViewModel : ReactiveObject
     
     #region Sorting Order
 
-    public FileListHelper.SortFilesBy SortOrder
+    public SortFilesBy SortOrder
     {
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);

+ 2 - 1
src/PicView.Avalonia/Views/BatchResizeView.axaml.cs

@@ -12,6 +12,7 @@ using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.Extensions;
 using PicView.Core.FileHandling;
+using PicView.Core.FileSorting;
 using PicView.Core.ImageDecoding;
 using PicView.Core.Localization;
 using PicView.Core.Titles;
@@ -262,7 +263,7 @@ public partial class BatchResizeView : UserControl
             _isRunning = true;
 
             var files = await Task.FromResult(
-                    FileListHelper.RetrieveFiles(new FileInfo(SourceFolderTextBox.Text)))
+                    FileListRetriever.RetrieveFiles(new FileInfo(SourceFolderTextBox.Text)))
                 .ConfigureAwait(true);
 
             if (!Directory.Exists(OutputFolderTextBox.Text))

+ 1 - 1
src/PicView.Core.MacOS/FileAssociation/MacFileAssociationService.cs

@@ -1,4 +1,4 @@
-using PicView.Core.FileHandling;
+using PicView.Core.FileAssociations;
 
 namespace PicView.Core.MacOS.FileAssociation;
 

+ 1 - 1
src/PicView.Core.WindowsNT/FileAssociation/WindowsFileAssociationService.cs

@@ -1,4 +1,4 @@
-using PicView.Core.FileHandling;
+using PicView.Core.FileAssociations;
 
 namespace PicView.Core.WindowsNT.FileAssociation;
 

+ 1 - 1
src/PicView.Core/FileHandling/IFileAssociationService.cs → src/PicView.Core/FileAssociations/IFileAssociationService.cs

@@ -1,4 +1,4 @@
-namespace PicView.Core.FileHandling;
+namespace PicView.Core.FileAssociations;
 
 /// <summary>
 /// Interface for handling platform-specific file associations

+ 1 - 0
src/PicView.Core/FileHandling/FileAssociationManager.cs

@@ -1,4 +1,5 @@
 using PicView.Core.DebugTools;
+using PicView.Core.FileAssociations;
 
 namespace PicView.Core.FileHandling;
 

+ 4 - 59
src/PicView.Core/FileHandling/FileListHelper.cs → src/PicView.Core/FileSorting/FileListRetriever.cs

@@ -1,65 +1,10 @@
 using PicView.Core.DebugTools;
+using PicView.Core.FileHandling;
 
-namespace PicView.Core.FileHandling;
+namespace PicView.Core.FileSorting;
 
-public static class FileListHelper
+public static class FileListRetriever
 {
-    /// <summary>
-    /// Enumeration of different options to sort files by.
-    /// </summary>
-    public enum SortFilesBy
-    {
-        /// <summary>
-        /// Sort files by name.
-        /// </summary>
-        Name = 0,
-
-        /// <summary>
-        /// Sort files by file size.
-        /// </summary>
-        FileSize = 1,
-
-        /// <summary>
-        /// Sort files by creation time.
-        /// </summary>
-        CreationTime = 2,
-
-        /// <summary>
-        /// Sort files by extension.
-        /// </summary>
-        Extension = 3,
-
-        /// <summary>
-        /// Sort files by last access time.
-        /// </summary>
-        LastAccessTime = 4,
-
-        /// <summary>
-        /// Sort files by last write time.
-        /// </summary>
-        LastWriteTime = 5,
-
-        /// <summary>
-        /// Sort files randomly.
-        /// </summary>
-        Random = 6
-    }
-
-    public static SortFilesBy GetSortOrder()
-    {
-        return Settings.Sorting.SortPreference switch
-        {
-            0 => SortFilesBy.Name,
-            1 => SortFilesBy.FileSize,
-            2 => SortFilesBy.CreationTime,
-            3 => SortFilesBy.Extension,
-            4 => SortFilesBy.LastAccessTime,
-            5 => SortFilesBy.LastWriteTime,
-            6 => SortFilesBy.Random,
-            _ => SortFilesBy.Name,
-        };
-    }
-
     public static IEnumerable<string> RetrieveFiles(FileInfo fileInfo)
     {
         if (fileInfo == null)
@@ -102,7 +47,7 @@ public static class FileListHelper
         }
         catch (Exception exception)
         {
-            DebugHelper.LogDebug(nameof(FileListHelper), nameof(RetrieveFiles), exception);
+            DebugHelper.LogDebug(nameof(FileSortHelper), nameof(RetrieveFiles), exception);
             return new List<string>();
         }
 

+ 19 - 0
src/PicView.Core/FileSorting/FileSortHelper.cs

@@ -0,0 +1,19 @@
+namespace PicView.Core.FileSorting;
+
+public static class FileSortHelper
+{
+    public static SortFilesBy GetSortOrder()
+    {
+        return Settings.Sorting.SortPreference switch
+        {
+            0 => SortFilesBy.Name,
+            1 => SortFilesBy.FileSize,
+            2 => SortFilesBy.CreationTime,
+            3 => SortFilesBy.Extension,
+            4 => SortFilesBy.LastAccessTime,
+            5 => SortFilesBy.LastWriteTime,
+            6 => SortFilesBy.Random,
+            _ => SortFilesBy.Name,
+        };
+    }
+}

+ 41 - 0
src/PicView.Core/FileSorting/SortFilesBy.cs

@@ -0,0 +1,41 @@
+namespace PicView.Core.FileSorting;
+/// <summary>
+/// Enumeration of different options to sort files by.
+/// </summary>
+public enum SortFilesBy
+{
+    /// <summary>
+    /// Sort files by name.
+    /// </summary>
+    Name = 0,
+
+    /// <summary>
+    /// Sort files by file size.
+    /// </summary>
+    FileSize = 1,
+
+    /// <summary>
+    /// Sort files by creation time.
+    /// </summary>
+    CreationTime = 2,
+
+    /// <summary>
+    /// Sort files by extension.
+    /// </summary>
+    Extension = 3,
+
+    /// <summary>
+    /// Sort files by last access time.
+    /// </summary>
+    LastAccessTime = 4,
+
+    /// <summary>
+    /// Sort files by last write time.
+    /// </summary>
+    LastWriteTime = 5,
+
+    /// <summary>
+    /// Sort files randomly.
+    /// </summary>
+    Random = 6
+}

+ 37 - 1
src/PicView.Core/ImageDecoding/ImageDecoder.cs → src/PicView.Core/ImageDecoding/Base64Decoder.cs

@@ -6,7 +6,7 @@ namespace PicView.Core.ImageDecoding;
 /// <summary>
 ///     Provides methods for decoding various image formats.
 /// </summary>
-public static class ImageDecoder
+public static class Base64Decoder
 {
     public static MagickImage? Base64ToMagickImage(string base64)
     {
@@ -42,4 +42,40 @@ public static class ImageDecoder
         var base64String = await File.ReadAllTextAsync(fileInfo.FullName).ConfigureAwait(false);
         return Base64ToMagickImage(base64String);
     }
+    
+    /// <summary>
+    /// Determines whether a string is a valid Base64 string.
+    /// </summary>
+    /// <param name="base64">The string to check.</param>
+    /// <returns>String as a valid Base64 string; otherwise, "".</returns>
+    public static string IsBase64String(string base64)
+    {
+        if (string.IsNullOrEmpty(base64))
+        {
+            return "";
+        }
+
+        if (base64.StartsWith("data:image/webp;base64,"))
+        {
+            base64 = base64["data:image/webp;base64,".Length..];
+        }
+
+        if (base64.StartsWith("data:image/jpeg;base64,"))
+        {
+            base64 = base64["data:image/jpeg;base64,".Length..];
+        }
+        
+        if (base64.StartsWith("data:image/png;base64,"))
+        {
+            base64 = base64["data:image/png;base64,".Length..];
+        }
+        
+        if (base64.StartsWith("data:image/gif;base64,"))
+        {
+            base64 = base64["data:image/gif;base64,".Length..];
+        }
+
+        var buffer = new Span<byte>(new byte[base64.Length]);
+        return Convert.TryFromBase64String(base64, buffer, out _) ? base64 : "";
+    }
 }

+ 0 - 40
src/PicView.Core/ImageDecoding/Base64Helper.cs

@@ -1,40 +0,0 @@
-namespace PicView.Core.ImageDecoding;
-
-public static class Base64Helper
-{
-    /// <summary>
-    /// Determines whether a string is a valid Base64 string.
-    /// </summary>
-    /// <param name="base64">The string to check.</param>
-    /// <returns>String as a valid Base64 string; otherwise, "".</returns>
-    public static string IsBase64String(string base64)
-    {
-        if (string.IsNullOrEmpty(base64))
-        {
-            return "";
-        }
-
-        if (base64.StartsWith("data:image/webp;base64,"))
-        {
-            base64 = base64["data:image/webp;base64,".Length..];
-        }
-
-        if (base64.StartsWith("data:image/jpeg;base64,"))
-        {
-            base64 = base64["data:image/jpeg;base64,".Length..];
-        }
-        
-        if (base64.StartsWith("data:image/png;base64,"))
-        {
-            base64 = base64["data:image/png;base64,".Length..];
-        }
-        
-        if (base64.StartsWith("data:image/gif;base64,"))
-        {
-            base64 = base64["data:image/gif;base64,".Length..];
-        }
-
-        var buffer = new Span<byte>(new byte[base64.Length]);
-        return Convert.TryFromBase64String(base64, buffer, out _) ? base64 : "";
-    }
-}

+ 1 - 1
src/PicView.Core/ImageDecoding/ImageType.cs

@@ -1,4 +1,4 @@
-namespace PicView.Avalonia.ImageHandling;
+namespace PicView.Core.ImageDecoding;
 
 public enum ImageType
 {

+ 0 - 1
src/PicView.Core/Models/ImageModel.cs

@@ -1,5 +1,4 @@
 using ImageMagick;
-using PicView.Avalonia.ImageHandling;
 using PicView.Core.ImageDecoding;
 
 namespace PicView.Core.Models;

+ 1 - 1
src/PicView.Core/Navigation/FileTypeResolver.cs

@@ -94,7 +94,7 @@ public static class FileTypeResolver
             return new FileTypeStruct(LoadAbleFileType.Web, s);
         }
 
-        var base64String = Base64Helper.IsBase64String(s);
+        var base64String = Base64Decoder.IsBase64String(s);
 
         if (!string.IsNullOrEmpty(base64String))
         {

+ 1 - 2
src/PicView.Core/ViewModels/PicViewerModel.cs

@@ -1,5 +1,4 @@
-using PicView.Avalonia.ImageHandling;
-using PicView.Core.ImageDecoding;
+using PicView.Core.ImageDecoding;
 using PicView.Core.ImageEffects;
 using ReactiveUI;