feat: add schemas page

This commit is contained in:
estrogen elf
2025-06-15 21:40:48 -05:00
parent cbc3c42116
commit a74c18ac39
8 changed files with 223 additions and 0 deletions

View File

@@ -29,6 +29,7 @@
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.3.0" /> <PackageReference Include="AvaloniaEdit.TextMate" Version="11.3.0" />
<PackageReference Include="BlossomiShymae.Briar" Version="0.2.0" /> <PackageReference Include="BlossomiShymae.Briar" Version="0.2.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="DebounceThrottle" Version="3.0.1" />
<PackageReference Include="FastCache.Cached" Version="1.8.2" /> <PackageReference Include="FastCache.Cached" Version="1.8.2" />
<PackageReference Include="FluentAvaloniaUI" Version="2.3.0" /> <PackageReference Include="FluentAvaloniaUI" Version="2.3.0" />
<PackageReference Include="Flurl" Version="4.0.0" /> <PackageReference Include="Flurl" Version="4.0.0" />

View File

@@ -10,6 +10,7 @@ using Needlework.Net.ViewModels.Pages.About;
using Needlework.Net.ViewModels.Pages.Console; using Needlework.Net.ViewModels.Pages.Console;
using Needlework.Net.ViewModels.Pages.Endpoints; using Needlework.Net.ViewModels.Pages.Endpoints;
using Needlework.Net.ViewModels.Pages.Home; using Needlework.Net.ViewModels.Pages.Home;
using Needlework.Net.ViewModels.Pages.Schemas;
using Needlework.Net.ViewModels.Pages.WebSocket; using Needlework.Net.ViewModels.Pages.WebSocket;
using Projektanker.Icons.Avalonia; using Projektanker.Icons.Avalonia;
using Projektanker.Icons.Avalonia.FontAwesome; using Projektanker.Icons.Avalonia.FontAwesome;
@@ -77,6 +78,7 @@ class Program
builder.AddSingleton<PageBase, ConsoleViewModel>(); builder.AddSingleton<PageBase, ConsoleViewModel>();
builder.AddSingleton<PageBase, EndpointsViewModel>(); builder.AddSingleton<PageBase, EndpointsViewModel>();
builder.AddSingleton<PageBase, WebSocketViewModel>(); builder.AddSingleton<PageBase, WebSocketViewModel>();
builder.AddSingleton<PageBase, SchemasViewModel>();
builder.AddSingleton<PageBase, AboutViewModel>(); builder.AddSingleton<PageBase, AboutViewModel>();
} }

View File

@@ -0,0 +1,22 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Needlework.Net.ViewModels.Pages.Endpoints;
using System.Collections.Generic;
namespace Needlework.Net.ViewModels.Pages.Schemas
{
public partial class SchemaItemViewModel : ObservableObject
{
public SchemaItemViewModel(PropertyClassViewModel vm)
{
Id = vm.Id;
PropertyFields = vm.PropertyFields;
PropertyEnums = vm.PropertyEnums;
}
public string Id { get; }
public List<PropertyFieldViewModel> PropertyFields { get; } = [];
public List<PropertyEnumViewModel> PropertyEnums { get; } = [];
}
}

View File

@@ -0,0 +1,87 @@
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using DebounceThrottle;
using Needlework.Net.Helpers;
using Needlework.Net.Models;
using Needlework.Net.ViewModels.Pages.Endpoints;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Needlework.Net.ViewModels.Pages.Schemas
{
public partial class SchemasViewModel : PageBase
{
private readonly DebounceDispatcher _debounceDispatcher = new(TimeSpan.FromMilliseconds(500));
private readonly DocumentService _documentService;
public record SchemaTab(string Key, Tab Tab);
private List<SchemaTab> _schemas = [];
public SchemasViewModel(DocumentService documentService) : base("Schemas", "fa-solid fa-file-lines")
{
_documentService = documentService;
}
[ObservableProperty]
private bool _isBusy = true;
[ObservableProperty]
private string? _search;
[ObservableProperty]
private List<SchemaItemViewModel> _schemaItems = [];
partial void OnSearchChanged(string? value)
{
_debounceDispatcher.Debounce(() =>
{
if (string.IsNullOrEmpty(value))
{
SchemaItems = [];
return;
}
Task.Run(async () =>
{
var lcuSchemaDocument = await _documentService.GetLcuSchemaDocumentAsync();
var lolClientDocument = await _documentService.GetLolClientDocumentAsync();
var items = _schemas.Where(schema => schema.Key.Contains(value, StringComparison.OrdinalIgnoreCase))
.Select((schema) => ToSchemaItemViewModel(schema, lcuSchemaDocument, lolClientDocument))
.ToList();
Dispatcher.UIThread.Invoke(() => { SchemaItems = items; });
});
});
}
private SchemaItemViewModel ToSchemaItemViewModel(SchemaTab schema, Document lcuSchemaDocument, Document lolClientDocument)
{
var document = schema.Tab switch
{
Tab.LCU => lcuSchemaDocument.OpenApiDocument,
Tab.GameClient => lolClientDocument.OpenApiDocument,
_ => throw new NotImplementedException()
};
var vm = OpenApiHelpers.WalkSchema(document.Components.Schemas[schema.Key], document);
return new SchemaItemViewModel(vm);
}
public override async Task InitializeAsync()
{
var lcuSchemaDocument = await _documentService.GetLcuSchemaDocumentAsync();
var lolClientDocument = await _documentService.GetLolClientDocumentAsync();
Dispatcher.UIThread.Invoke(() =>
{
_schemas = Enumerable.Concat(
lcuSchemaDocument.OpenApiDocument.Components.Schemas.Keys.Select(key => new SchemaTab(key, Tab.LCU)),
lolClientDocument.OpenApiDocument.Components.Schemas.Keys.Select(key => new SchemaTab(key, Tab.GameClient))
).ToList();
IsBusy = false;
});
}
}
}

View File

@@ -0,0 +1,46 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:Needlework.Net.ViewModels.Pages.Schemas"
xmlns:controls="using:Needlework.Net.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Needlework.Net.Views.Pages.Schemas.SchemaItemView"
x:DataType="vm:SchemaItemViewModel">
<UserControl.Styles>
<Style Selector="DataGrid">
<Setter Property="HorizontalGridLinesBrush" Value="{DynamicResource ControlElevationBorderBrush}"/>
</Style>
<Style Selector="DataGridColumnHeader TextBlock">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}"/>
</Style>
<Style Selector="DataGridRow DataGridCell">
<Setter Property="FontSize" Value="12"></Setter>
</Style>
<Style Selector="DataGridRow">
<Setter Property="Margin" Value="0 0 0 4"></Setter>
</Style>
</UserControl.Styles>
<Expander>
<Expander.Header>
<TextBlock FontSize="12"
FontWeight="DemiBold"
Text="{Binding Id}"/>
</Expander.Header>
<StackPanel>
<DataGrid IsVisible="{Binding PropertyFields, Converter={StaticResource EnumerableToVisibilityConverter}}"
ItemsSource="{Binding PropertyFields}"
AutoGenerateColumns="True"
IsReadOnly="True"
GridLinesVisibility="Horizontal">
</DataGrid>
<DataGrid IsVisible="{Binding PropertyEnums, Converter={StaticResource EnumerableToVisibilityConverter}}"
Margin="0 0 0 8"
ItemsSource="{Binding PropertyEnums}"
AutoGenerateColumns="True"
IsReadOnly="True"
GridLinesVisibility="Horizontal">
</DataGrid>
</StackPanel>
</Expander>
</UserControl>

View File

@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace Needlework.Net.Views.Pages.Schemas;
public partial class SchemaItemView : UserControl
{
public SchemaItemView()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,43 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:Needlework.Net.ViewModels.Pages.Schemas"
xmlns:views="using:Needlework.Net.Views.Pages.Schemas"
xmlns:controls="using:Needlework.Net.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Needlework.Net.Views.Pages.Schemas.SchemasView"
x:DataType="vm:SchemasViewModel">
<controls:BusyArea IsBusy="{Binding IsBusy}"
BusyText="Loading...">
<Grid Margin="16"
ColumnDefinitions="*"
RowDefinitions="auto,*">
<TextBox Text="{Binding Search}"
Watermark="Search schemas"
Margin="0 0 0 8"
Grid.Row="0"
Grid.Column="0"/>
<ScrollViewer Grid.Row="1"
Grid.Column="0">
<ItemsControl ItemsSource="{Binding SchemaItems}">
<ItemsControl.Styles>
<Style Selector="views|SchemaItemView">
<Setter Property="Margin" Value="0 0 0 8"/>
</Style>
</ItemsControl.Styles>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</controls:BusyArea>
</UserControl>

View File

@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace Needlework.Net.Views.Pages.Schemas;
public partial class SchemasView : UserControl
{
public SchemasView()
{
InitializeComponent();
}
}