diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_Storage/Given_ApplicationStorage.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_Storage/Given_ApplicationStorage.cs index 7b1ac14c76e6..451882c15f8e 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_Storage/Given_ApplicationStorage.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_Storage/Given_ApplicationStorage.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Uno.Extensions.Specialized; using Windows.Storage; namespace Uno.UI.RuntimeTests.Tests.Windows_Storage @@ -8,6 +9,32 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_Storage public class Given_ApplicationStorage { + [TestMethod] + public async Task When_ExistFilesInPackage() + { + var fileExists = await Uno.UI.Toolkit.StorageFileHelper.GetFilesInDirectoryAsync(null); + + Assert.IsTrue(fileExists.Any()); + } + + [TestMethod] + public async Task When_ExtensionsFilterCountDifferentFromAllInPackage() + { + var filteredFileExists = await Uno.UI.Toolkit.StorageFileHelper.GetFilesInDirectoryAsync([".png"]); + var allFileExists = await Uno.UI.Toolkit.StorageFileHelper.GetFilesInDirectoryAsync(null); + + Assert.IsFalse(allFileExists.Count() == filteredFileExists.Count()); + } + + [TestMethod] + public async Task When_ExtensionsFilterOnlyPathsForPngFiles() + { + var filteredFileExists = await Uno.UI.Toolkit.StorageFileHelper.GetFilesInDirectoryAsync([".png"]); + var allFileExists = await Uno.UI.Toolkit.StorageFileHelper.GetFilesInDirectoryAsync(null); + + Assert.IsTrue(filteredFileExists.Count() == filteredFileExists.Where(e => e.ToString().EndsWith(".png")).Count()); + } + [TestMethod] public async Task When_FileDoesNotExistsInPackage() { diff --git a/src/Uno.UI.Toolkit/Storage/StorageFileHelper.Android.cs b/src/Uno.UI.Toolkit/Storage/StorageFileHelper.Android.cs index ce0e005f0c0b..671953a77aec 100644 --- a/src/Uno.UI.Toolkit/Storage/StorageFileHelper.Android.cs +++ b/src/Uno.UI.Toolkit/Storage/StorageFileHelper.Android.cs @@ -5,6 +5,7 @@ using System.Threading; using Android.Content.Res; using System.Threading.Tasks; +using System; namespace Uno.UI.Toolkit; @@ -88,5 +89,27 @@ private static bool ScanPackageAssets(ICollection scannedFiles, string r return false; } } + + /// + /// Retrieves the paths of assets within the current Android application package based on the specified filter predicate. + /// + /// A predicate function determining whether a file should be included in the result. + /// Returns an array of strings containing the paths of the filtered assets. + private static Task GetFilesInDirectory(Func predicate) + { + var context = global::Android.App.Application.Context; + + if (_scannedFiles is null) + { + _scannedFiles = new List(); + _ = ScanPackageAssets(_scannedFiles); + } + + var results = _scannedFiles?.Where(e => predicate(e)) + .Select(e => e.Replace('\\', '/')) + .ToArray() ?? Array.Empty(); + + return Task.FromResult(results); + } } diff --git a/src/Uno.UI.Toolkit/Storage/StorageFileHelper.cs b/src/Uno.UI.Toolkit/Storage/StorageFileHelper.cs index 1c4d02f78baf..beceeeb0d7e7 100644 --- a/src/Uno.UI.Toolkit/Storage/StorageFileHelper.cs +++ b/src/Uno.UI.Toolkit/Storage/StorageFileHelper.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Collections.Generic; using System.IO; +using System.Linq; namespace Uno.UI.Toolkit; @@ -18,9 +19,20 @@ public partial class StorageFileHelper /// A task that will complete with a result of true if file exists, otherwise with a result of false. public static async Task ExistsInPackage(string fileName) => await FileExistsInPackage(fileName); + /// + /// This asynchronous method retrieves the paths of files within a directory based on a specified filter for file extensions. + /// + /// An array of strings representing the file extensions to filter the files.If null, all files in the directory are considered. + /// An array of strings containing the paths of the filtered files within the directory. + public static async Task GetFilesInDirectoryAsync(string[] extensionsFilter) + => await GetFilesInDirectory(e => extensionsFilter == null || extensionsFilter.Any(filter => e.EndsWith(filter, StringComparison.OrdinalIgnoreCase))); + #if IS_UNIT_TESTS || __NETSTD_REFERENCE__ private static Task FileExistsInPackage(string fileName) => throw new NotImplementedException(); + + private static Task GetFilesInDirectory(Func predicate) + => throw new NotImplementedException(); #endif #if __SKIA__ || WINDOWS || WINAPPSDK || WINDOWS_UWP || WINUI @@ -39,5 +51,29 @@ private static Task FileExistsInPackage(string fileName) return Task.FromResult(false); } + + /// + /// Retrieves the paths of assets within the current application based on the specified filter predicate. + /// + /// A predicate function determining whether a file should be included in the result. + /// Returns an array of strings containing the paths of the filtered assets. + private static Task GetFilesInDirectory(Func predicate) + { + List assetsFiles = new(); + string path = string.Empty; + var executingPath = Assembly.GetExecutingAssembly().Location; + if (!string.IsNullOrEmpty(executingPath)) + { + path = Path.GetDirectoryName(executingPath) + string.Empty; + if (!string.IsNullOrEmpty(path)) + { + assetsFiles = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories) + .Where(e => predicate(e)) + .Select(e => e.Replace(path, string.Empty).Replace('\\', '/').TrimStart('/')) + .ToList(); + } + } + return Task.FromResult(assetsFiles.ToArray()); + } #endif } diff --git a/src/Uno.UI.Toolkit/Storage/StorageFileHelper.iOSmacOS.cs b/src/Uno.UI.Toolkit/Storage/StorageFileHelper.iOSmacOS.cs index 6b45878d507a..6bcc8723f1b2 100644 --- a/src/Uno.UI.Toolkit/Storage/StorageFileHelper.iOSmacOS.cs +++ b/src/Uno.UI.Toolkit/Storage/StorageFileHelper.iOSmacOS.cs @@ -22,4 +22,21 @@ private static Task FileExistsInPackage(string fileName) return Task.FromResult(resourcePathname != null); } + + /// + /// Retrieves the paths of assets within the current application based on the specified filter predicate. + /// + /// A predicate function determining whether a file should be included in the result. + /// Returns an array of strings containing the paths of the filtered assets. + private static Task GetFilesInDirectory(Func predicate) + { + string rootPath = AppDomain.CurrentDomain.BaseDirectory; + string[] files = Directory.GetFiles(rootPath, "*", SearchOption.AllDirectories); + + var results = files?.Where(e => predicate(e)) + .Select(e => e.Replace(rootPath, string.Empty).Replace('\\', '/')) + .ToArray() ?? Array.Empty(); + + return Task.FromResult(results); + } } diff --git a/src/Uno.UI.Toolkit/Storage/StorageFileHelper.wasm.cs b/src/Uno.UI.Toolkit/Storage/StorageFileHelper.wasm.cs index 1afc322404e4..2d609aee99a4 100644 --- a/src/Uno.UI.Toolkit/Storage/StorageFileHelper.wasm.cs +++ b/src/Uno.UI.Toolkit/Storage/StorageFileHelper.wasm.cs @@ -1,4 +1,6 @@ #nullable enable +using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Windows.Storage.Helpers; @@ -12,4 +14,18 @@ private static async Task FileExistsInPackage(string fileName) var assets = await AssetsManager.Assets.Value; return assets?.Contains(fileName) ?? false; } + + /// + /// Retrieves the paths of assets within the current application based on the specified filter predicate. + /// + /// A predicate function determining whether a file should be included in the result. + /// Returns an array of strings containing the paths of the filtered assets. + private static async Task GetFilesInDirectory(Func predicate) + { + var assets = await AssetsManager.Assets.Value; + + return assets?.Where(e => predicate(e)) + .Select(e => e.Replace('\\', '/')) + .ToArray() ?? Array.Empty(); + } }