diff --git a/Localizations/ar.json b/Localizations/ar.json index 93b148ec9..0ffe47280 100644 --- a/Localizations/ar.json +++ b/Localizations/ar.json @@ -1,4 +1,5 @@ { + "all": "الكل", "appreciation_message": "شكرًا لك على دعمك لـ AssetRipper!", "asset_ripper_free": "AssetRipper المجاني", "asset_ripper_premium": "AssetRipper بريميوم", @@ -116,5 +117,6 @@ "loading_step_locate_key_functions": "جارٍ مسح الملف الثنائي IL2Cpp للوظائف المكتبية", "export_primary_content": "تصدير المحتوى الأساسي", "export_unity_project": "تصدير مشروع Unity", - "c_sharp_langage_version_config_2": "C# 2" + "c_sharp_langage_version_config_2": "C# 2", + "filter": "تصفية" } diff --git a/Localizations/en_US.json b/Localizations/en_US.json index fb7c455c9..c8081b9ce 100644 --- a/Localizations/en_US.json +++ b/Localizations/en_US.json @@ -1,4 +1,5 @@ { + "all": "All", "an_error_occured_during_decompilation": "An error occurred during decompilation.", "appreciation_message": "Thank you for supporting AssetRipper!", "assembly_name": "Assembly Name", @@ -96,6 +97,7 @@ "file_id": "File ID", "format": "Format", "frequency": "Frequency", + "filter": "Filter", "game_object": "GameObject", "guid": "GUID", "height": "Height", diff --git a/Source/AssetRipper.GUI.Web/Pages/Collections/CollectionAPI.cs b/Source/AssetRipper.GUI.Web/Pages/Collections/CollectionAPI.cs index 3ab54de1b..0b79cf0f7 100644 --- a/Source/AssetRipper.GUI.Web/Pages/Collections/CollectionAPI.cs +++ b/Source/AssetRipper.GUI.Web/Pages/Collections/CollectionAPI.cs @@ -14,15 +14,31 @@ internal static class CollectionAPI public const string Count = Base + "/Count"; } - private const string Path = "Path"; + public const string Path = "Path"; + public const string Class = "Class"; + + public static string GetViewUrl(CollectionPath path, string? classFilter = null) + { + string url = $"{Urls.View}?{GetPathQuery(path)}"; + if (!string.IsNullOrEmpty(classFilter)) + { + url += $"&{Class}={classFilter.ToUrl()}"; + } + return url; + } - public static string GetViewUrl(CollectionPath path) => $"{Urls.View}?{GetPathQuery(path)}"; public static Task GetView(HttpContext context) { context.Response.DisableCaching(); if (TryGetCollectionFromQuery(context, out AssetCollection? collection, out CollectionPath path, out Task? failureTask)) { - return new ViewPage() { Collection = collection, Path = path }.WriteToResponse(context.Response); + string? classFilter = context.Request.Query[Class]; + return new ViewPage() + { + Collection = collection, + Path = path, + ClassFilter = string.IsNullOrWhiteSpace(classFilter) ? null : classFilter + }.WriteToResponse(context.Response); } else { diff --git a/Source/AssetRipper.GUI.Web/Pages/Collections/ViewPage.cs b/Source/AssetRipper.GUI.Web/Pages/Collections/ViewPage.cs index bc7fb11d2..2e675b629 100644 --- a/Source/AssetRipper.GUI.Web/Pages/Collections/ViewPage.cs +++ b/Source/AssetRipper.GUI.Web/Pages/Collections/ViewPage.cs @@ -9,6 +9,7 @@ public sealed class ViewPage : DefaultPage public required AssetCollection Collection { get; init; } public required CollectionPath Path { get; init; } + public string? ClassFilter { get; init; } public override string GetTitle() => Collection.Name; public override void WriteInnerContent(TextWriter writer) @@ -27,6 +28,40 @@ public sealed class ViewPage : DefaultPage if (Collection.Count > 0) { new H2(writer).Close(Localization.Assets); + using (new Form(writer).WithAction(CollectionAPI.Urls.View).WithMethod("get").End()) + { + new Input(writer) + .WithType("hidden") + .WithName(CollectionAPI.Path) + .WithValue(Path.ToJson().ToHtml()) + .Close(); + + new Label(writer).WithFor("classFilter").WithClass("me-2").Close(Localization.Class); + + using (new Select(writer) + .WithId("classFilter") + .WithName(CollectionAPI.Class) + .End()) + { + new Option(writer) + .WithValue(string.Empty) + .MaybeWithSelected(string.IsNullOrEmpty(ClassFilter)) + .Close(Localization.All); + + foreach (string cn in Collection + .Select(a => a.ClassName) + .Distinct() + .Order()) + { + new Option(writer) + .WithValue(cn) + .MaybeWithSelected(string.Equals(cn, ClassFilter, StringComparison.Ordinal)) + .Close(cn); + } + } + + new Button(writer).WithType("submit").WithClass("btn").Close(Localization.Filter); + } using (new Table(writer).WithClass("table").End()) { using (new Thead(writer).End()) @@ -42,6 +77,12 @@ public sealed class ViewPage : DefaultPage { foreach (IUnityObjectBase asset in Collection) { + if (!string.IsNullOrEmpty(ClassFilter) && + !string.Equals(asset.ClassName, ClassFilter, StringComparison.Ordinal)) + { + continue; + } + using (new Tr(writer).End()) { new Td(writer).Close(asset.PathID.ToString());