Browse Source

Update string file determination and base64 strip out "data:image/webp;base64,"

Ruben 11 tháng trước cách đây
mục cha
commit
10e530cb4d

+ 22 - 19
src/PicView.Avalonia/Navigation/NavigationHelper.cs

@@ -279,15 +279,23 @@ public static class NavigationHelper
         {
             var check = ErrorHelper.CheckIfLoadableString(source);
 
-            switch (check)
+            if (check == null)
             {
-                default:
+                await ErrorHandling.ReloadAsync(vm).ConfigureAwait(false);
+                vm.IsLoading = false;
+                ArchiveExtraction.Cleanup();
+                return;
+            }
+
+            switch (check.Value.Type)
+            {
+                case ErrorHelper.LoadAbleFileType.File:
                     // Navigate to the image if it exists in the image iterator
                     if (vm.ImageIterator is not null)
                     {
-                        if (vm.ImageIterator.ImagePaths.Contains(check))
+                        if (vm.ImageIterator.ImagePaths.Contains(check.Value.Data))
                         {
-                            await vm.ImageIterator.IterateToIndex(vm.ImageIterator.ImagePaths.IndexOf(check),
+                            await vm.ImageIterator.IterateToIndex(vm.ImageIterator.ImagePaths.IndexOf(check.Value.Data),
                                     _cancellationTokenSource)
                                 .ConfigureAwait(false);
                             return;
@@ -295,39 +303,34 @@ public static class NavigationHelper
                     }
 
                     vm.CurrentView = vm.ImageViewer;
-                    await LoadPicFromFile(check, vm).ConfigureAwait(false);
+                    await LoadPicFromFile(check.Value.Data, vm).ConfigureAwait(false);
                     vm.IsLoading = false;
                     ArchiveExtraction.Cleanup();
                     return;
-
-                case "web":
+                case ErrorHelper.LoadAbleFileType.Directory:
                     vm.CurrentView = vm.ImageViewer;
-                    await LoadPicFromUrlAsync(source, vm).ConfigureAwait(false);
+                    await LoadPicFromDirectoryAsync(check.Value.Data, vm).ConfigureAwait(false);
                     vm.IsLoading = false;
                     ArchiveExtraction.Cleanup();
                     return;
-
-                case "base64":
+                case ErrorHelper.LoadAbleFileType.Web:
                     vm.CurrentView = vm.ImageViewer;
-                    await LoadPicFromBase64Async(source, vm).ConfigureAwait(false);
+                    await LoadPicFromUrlAsync(check.Value.Data, vm).ConfigureAwait(false);
                     vm.IsLoading = false;
                     ArchiveExtraction.Cleanup();
                     return;
-
-                case "directory":
+                case ErrorHelper.LoadAbleFileType.Base64:
                     vm.CurrentView = vm.ImageViewer;
-                    await LoadPicFromDirectoryAsync(source, vm).ConfigureAwait(false);
+                    await LoadPicFromBase64Async(check.Value.Data, vm).ConfigureAwait(false);
                     vm.IsLoading = false;
                     ArchiveExtraction.Cleanup();
                     return;
-
-                case "zip":
+                case ErrorHelper.LoadAbleFileType.Zip:
                     vm.CurrentView = vm.ImageViewer;
-                    await LoadPicFromArchiveAsync(source, vm).ConfigureAwait(false);
+                    await LoadPicFromArchiveAsync(check.Value.Data, vm).ConfigureAwait(false);
                     vm.IsLoading = false;
                     return;
-
-                case "":
+                default:
                     await ErrorHandling.ReloadAsync(vm).ConfigureAwait(false);
                     vm.IsLoading = false;
                     ArchiveExtraction.Cleanup();

+ 24 - 4
src/PicView.Core/ImageDecoding/Base64Helper.cs

@@ -6,15 +6,35 @@ public static class Base64Helper
     /// Determines whether a string is a valid Base64 string.
     /// </summary>
     /// <param name="base64">The string to check.</param>
-    /// <returns>True if the string is a valid Base64 string; otherwise, false.</returns>
-    public static bool IsBase64String(string base64)
+    /// <returns>String as a valid Base64 string; otherwise, "".</returns>
+    public static string IsBase64String(string base64)
     {
         if (string.IsNullOrEmpty(base64))
         {
-            return false;
+            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 _);
+        return Convert.TryFromBase64String(base64, buffer, out _) ? base64 : "";
     }
 }

+ 77 - 13
src/PicView.Core/Navigation/ErrorHelper.cs

@@ -6,33 +6,97 @@ namespace PicView.Core.Navigation;
 public static class ErrorHelper
 {
     /// <summary>
-    /// Determines the type of resource based on the provided string.
+    /// Represents a structure containing a loadable file type and its associated data.
     /// </summary>
-    /// <param name="s">The input string representing a URL, base64 data, file path, or directory path.</param>
+    /// <param name="type">The type of the loadable file.</param>
+    /// <param name="data">The data associated with the loadable file.</param>
+    public readonly struct FileTypeStruct(LoadAbleFileType type, string data)
+    {
+        /// <summary>
+        /// Gets the type of the loadable file.
+        /// </summary>
+        public LoadAbleFileType Type => type;
+        
+        /// <summary>
+        /// Gets the data associated with the loadable file.
+        /// </summary>
+        public string Data => data;
+    }
+
+    /// <summary>
+    /// Specifies the different types of loadable files.
+    /// </summary>
+    public enum LoadAbleFileType
+    {
+        /// <summary>
+        /// Represents a regular file.
+        /// </summary>
+        File,
+        
+        /// <summary>
+        /// Represents a directory.
+        /// </summary>
+        Directory,
+        
+        /// <summary>
+        /// Represents a web URL.
+        /// </summary>
+        Web,
+        
+        /// <summary>
+        /// Represents a Base64 encoded string.
+        /// </summary>
+        Base64,
+        
+        /// <summary>
+        /// Represents a zip archive.
+        /// </summary>
+        Zip
+    }
+    
+    /// <summary>
+    /// Checks if the provided string is a loadable file type and returns its type and associated data.
+    /// </summary>
+    /// <param name="s">The string to check.</param>
     /// <returns>
-    /// - If the input represents a web URL, returns "web".
-    /// - If the input represents base64-encoded data, returns "base64".
-    /// - If the input represents a valid file path, returns the file path.
-    /// - If the input represents a directory path, returns "directory".
-    /// - Otherwise, returns an empty string.
+    /// A <see cref="FileTypeStruct"/> containing the type and data of the loadable file if the string is loadable, otherwise null.
     /// </returns>
-    public static string CheckIfLoadableString(string s)
+    public static FileTypeStruct? CheckIfLoadableString(string s)
     {
+        if (s.StartsWith('"') && s.EndsWith('"'))
+        {
+            s = s[1..^1];
+        }
+        
         if (s.StartsWith("file:///"))
         {
             s = s.Replace("file:///", "");
             s = s.Replace("%20", " ");
         }
-        
+
         if (File.Exists(s))
-            return Path.GetExtension(s).IsArchive() ? "zip" : s;
+        {
+            var type = s.IsArchive() ? LoadAbleFileType.Zip : LoadAbleFileType.File;
+            return new FileTypeStruct(type, s);
+        }
 
         if (Directory.Exists(s))
-            return "directory";
+        {
+            return new FileTypeStruct(LoadAbleFileType.Directory, s);
+        }
 
         if (!string.IsNullOrWhiteSpace(s.GetURL()))
-            return "web";
+        {
+            return new FileTypeStruct(LoadAbleFileType.Web, s);
+        }
+
+        var base64String = Base64Helper.IsBase64String(s);
+
+        if (!string.IsNullOrEmpty(base64String))
+        {
+            return new FileTypeStruct(LoadAbleFileType.Base64, base64String);
+        }
 
-        return Base64Helper.IsBase64String(s) ? "base64" : string.Empty;
+        return null;
     }
 }