Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StorageFileHelper - Add GetFilesInDirectoryAsync #16341

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Uno.Extensions.Specialized;
using Windows.Storage;

namespace Uno.UI.RuntimeTests.Tests.Windows_Storage
Expand All @@ -8,6 +9,32 @@
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);

Check notice on line 33 in src/Uno.UI.RuntimeTests/Tests/Windows_Storage/Given_ApplicationStorage.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.RuntimeTests/Tests/Windows_Storage/Given_ApplicationStorage.cs#L33

Remove the unused local variable 'allFileExists'.

Assert.IsTrue(filteredFileExists.Count() == filteredFileExists.Where(e => e.ToString().EndsWith(".png")).Count());
}

[TestMethod]
public async Task When_FileDoesNotExistsInPackage()
{
Expand Down
23 changes: 23 additions & 0 deletions src/Uno.UI.Toolkit/Storage/StorageFileHelper.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Threading;
using Android.Content.Res;
using System.Threading.Tasks;
using System;

namespace Uno.UI.Toolkit;

Expand Down Expand Up @@ -88,5 +89,27 @@
return false;
}
}

/// <summary>
/// Retrieves the paths of assets within the current Android application package based on the specified filter predicate.
/// </summary>
/// <param name="predicate">A predicate function determining whether a file should be included in the result.</param>
/// <returns>Returns an array of strings containing the paths of the filtered assets.</returns>
private static Task<string[]> GetFilesInDirectory(Func<string, bool> predicate)
{
var context = global::Android.App.Application.Context;

Check notice on line 100 in src/Uno.UI.Toolkit/Storage/StorageFileHelper.Android.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.Toolkit/Storage/StorageFileHelper.Android.cs#L100

Remove the unused local variable 'context'.

if (_scannedFiles is null)
{
_scannedFiles = new List<string>();
_ = ScanPackageAssets(_scannedFiles);
}

var results = _scannedFiles?.Where(e => predicate(e))
.Select(e => e.Replace('\\', '/'))
.ToArray() ?? Array.Empty<string>();

return Task.FromResult(results);
}
}

36 changes: 36 additions & 0 deletions src/Uno.UI.Toolkit/Storage/StorageFileHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Uno.UI.Toolkit;

Expand All @@ -18,9 +19,20 @@ public partial class StorageFileHelper
/// <returns>A task that will complete with a result of true if file exists, otherwise with a result of false.</returns>
public static async Task<bool> ExistsInPackage(string fileName) => await FileExistsInPackage(fileName);

/// <summary>
/// This asynchronous method retrieves the paths of files within a directory based on a specified filter for file extensions.
/// </summary>
/// <param name="extensionsFilter">An array of strings representing the file extensions to filter the files.If null, all files in the directory are considered.</param>
/// <returns>An array of strings containing the paths of the filtered files within the directory.</returns>
public static async Task<string[]> GetFilesInDirectoryAsync(string[] extensionsFilter)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Folder instead of Directory to preserve WinUI convention

Copy link
Member

@jeromelaban jeromelaban Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rafael-rosa-knowcode By the look of the implementation, it means that you want all the files that GetFileFromApplicationUriAsync would provide. In this case, the method should be best called GetFilesFromApplicationAsync.

=> await GetFilesInDirectory(e => extensionsFilter == null || extensionsFilter.Any(filter => e.EndsWith(filter, StringComparison.OrdinalIgnoreCase)));

#if IS_UNIT_TESTS || __NETSTD_REFERENCE__
private static Task<bool> FileExistsInPackage(string fileName)
=> throw new NotImplementedException();

private static Task<string[]> GetFilesInDirectory(Func<string, bool> predicate)
=> throw new NotImplementedException();
#endif

#if __SKIA__ || WINDOWS || WINAPPSDK || WINDOWS_UWP || WINUI
Expand All @@ -39,5 +51,29 @@ private static Task<bool> FileExistsInPackage(string fileName)

return Task.FromResult(false);
}

/// <summary>
/// Retrieves the paths of assets within the current application based on the specified filter predicate.
/// </summary>
/// <param name="predicate">A predicate function determining whether a file should be included in the result.</param>
/// <returns>Returns an array of strings containing the paths of the filtered assets.</returns>
private static Task<string[]> GetFilesInDirectory(Func<string, bool> predicate)
{
List<string> assetsFiles = new();
string path = string.Empty;
var executingPath = Assembly.GetExecutingAssembly().Location;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is likely going to cause trouble when we'll run as a single file. Let's use the same APIs that:

public static IAsyncOperation<StorageFile> GetFileFromApplicationUriAsync(Uri uri)

is using.

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
}
17 changes: 17 additions & 0 deletions src/Uno.UI.Toolkit/Storage/StorageFileHelper.iOSmacOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,21 @@ private static Task<bool> FileExistsInPackage(string fileName)

return Task.FromResult(resourcePathname != null);
}

/// <summary>
/// Retrieves the paths of assets within the current application based on the specified filter predicate.
/// </summary>
/// <param name="predicate">A predicate function determining whether a file should be included in the result.</param>
/// <returns>Returns an array of strings containing the paths of the filtered assets.</returns>
private static Task<string[]> GetFilesInDirectory(Func<string, bool> predicate)
{
string rootPath = AppDomain.CurrentDomain.BaseDirectory;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, let's use the same APIs that GetFileFromApplicationUriAsync is using.

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<string>();

return Task.FromResult(results);
}
}
16 changes: 16 additions & 0 deletions src/Uno.UI.Toolkit/Storage/StorageFileHelper.wasm.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#nullable enable
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Windows.Storage.Helpers;
Expand All @@ -12,4 +14,18 @@ private static async Task<bool> FileExistsInPackage(string fileName)
var assets = await AssetsManager.Assets.Value;
return assets?.Contains(fileName) ?? false;
}

/// <summary>
/// Retrieves the paths of assets within the current application based on the specified filter predicate.
/// </summary>
/// <param name="predicate">A predicate function determining whether a file should be included in the result.</param>
/// <returns>Returns an array of strings containing the paths of the filtered assets.</returns>
private static async Task<string[]> GetFilesInDirectory(Func<string, bool> predicate)
{
var assets = await AssetsManager.Assets.Value;

return assets?.Where(e => predicate(e))
.Select(e => e.Replace('\\', '/'))
.ToArray() ?? Array.Empty<string>();
}
}
Loading