mirror of
https://github.com/BlossomiShymae/Needlework.Net.git
synced 2025-12-06 10:10:48 +01:00
refactor: use data source, remove data loading in ctor of view models
This commit is contained in:
@@ -40,8 +40,6 @@ public partial class App(IServiceProvider serviceProvider) : Application
|
||||
MainWindow = desktop.MainWindow;
|
||||
}
|
||||
|
||||
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
60
Needlework.Net/DataSource.cs
Normal file
60
Needlework.Net/DataSource.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.OpenApi.Readers;
|
||||
using Needlework.Net.Models;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Needlework.Net
|
||||
{
|
||||
public class DataSource
|
||||
{
|
||||
private readonly ILogger<DataSource> _logger;
|
||||
private readonly HttpClient _httpClient;
|
||||
private Document? _lcuSchemaDocument;
|
||||
private Document? _lolClientDocument;
|
||||
private readonly TaskCompletionSource<bool> _taskCompletionSource = new();
|
||||
|
||||
|
||||
public DataSource(HttpClient httpClient, ILogger<DataSource> logger)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<Document> GetLcuSchemaDocumentAsync()
|
||||
{
|
||||
await _taskCompletionSource.Task;
|
||||
return _lcuSchemaDocument ?? throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public async Task<Document> GetLolClientDocumentAsync()
|
||||
{
|
||||
await _taskCompletionSource.Task;
|
||||
return _lolClientDocument ?? throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var reader = new OpenApiStreamReader();
|
||||
var lcuSchemaStream = await _httpClient.GetStreamAsync("https://raw.githubusercontent.com/dysolix/hasagi-types/main/swagger.json");
|
||||
var lcuSchemaRaw = reader.Read(lcuSchemaStream, out var _);
|
||||
_lcuSchemaDocument = new Document(lcuSchemaRaw);
|
||||
|
||||
var lolClientStream = await _httpClient.GetStreamAsync("https://raw.githubusercontent.com/BlossomiShymae/poroschema/refs/heads/main/schemas/lolclient.json");
|
||||
var lolClientRaw = reader.Read(lolClientStream, out var _);
|
||||
_lolClientDocument = new Document(lolClientRaw);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to initialize DataSource");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_taskCompletionSource.SetResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Needlework.Net
|
||||
{
|
||||
@@ -16,7 +12,7 @@ namespace Needlework.Net
|
||||
{
|
||||
var logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo.File("Logs/debug-.log", rollingInterval: RollingInterval.Day, shared: true)
|
||||
.WriteTo.File("Logs/debug-", rollingInterval: RollingInterval.Day, shared: true)
|
||||
.CreateLogger();
|
||||
logger.Debug("NeedleworkDotNet version: {Version}", Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0.0.0.0");
|
||||
logger.Debug("OS description: {Description}", System.Runtime.InteropServices.RuntimeInformation.OSDescription);
|
||||
@@ -25,7 +21,7 @@ namespace Needlework.Net
|
||||
|
||||
public static void LogFatal(UnhandledExceptionEventArgs e)
|
||||
{
|
||||
File.WriteAllText($"Logs/fatal-{DateTime.Now:HHmmssfff}.log", e.ExceptionObject.ToString());
|
||||
File.WriteAllText($"Logs/fatal-{DateTime.Now:HHmmssfff}", e.ExceptionObject.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using Needlework.Net.Models;
|
||||
|
||||
namespace Needlework.Net.Messages
|
||||
{
|
||||
public class DataReadyMessage(OpenApiDocumentWrapper wrapper) : ValueChangedMessage<OpenApiDocumentWrapper>(wrapper)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using Needlework.Net.Models;
|
||||
|
||||
namespace Needlework.Net.Messages
|
||||
{
|
||||
public class DataRequestMessage : RequestMessage<OpenApiDocumentWrapper>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Needlework.Net.Messages
|
||||
{
|
||||
public class HostDocumentRequestMessage : RequestMessage<OpenApiDocument>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Needlework.Net.Models;
|
||||
|
||||
public class OpenApiDocumentWrapper
|
||||
public class Document
|
||||
{
|
||||
internal OpenApiDocument OpenApiDocument { get; }
|
||||
|
||||
@@ -14,7 +14,7 @@ public class OpenApiDocumentWrapper
|
||||
|
||||
public List<string> Paths => [.. OpenApiDocument.Paths.Keys];
|
||||
|
||||
public OpenApiDocumentWrapper(OpenApiDocument openApiDocument)
|
||||
public Document(OpenApiDocument openApiDocument)
|
||||
{
|
||||
OpenApiDocument = openApiDocument;
|
||||
var plugins = new SortedDictionary<string, List<PathOperation>>();
|
||||
@@ -6,10 +6,8 @@ using Needlework.Net.ViewModels.MainWindow;
|
||||
using Needlework.Net.ViewModels.Pages;
|
||||
using Projektanker.Icons.Avalonia;
|
||||
using Projektanker.Icons.Avalonia.FontAwesome;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Needlework.Net;
|
||||
|
||||
@@ -32,23 +30,32 @@ class Program
|
||||
{
|
||||
IconProvider.Current
|
||||
.Register<FontAwesomeIconProvider>();
|
||||
var services = BuildServices();
|
||||
Task.Run(async () => await InitializeDataSourceAsync(services));
|
||||
|
||||
return AppBuilder.Configure(() => new App(BuildServices()))
|
||||
return AppBuilder.Configure(() => new App(services))
|
||||
.UsePlatformDetect()
|
||||
.WithInterFont()
|
||||
.LogToTrace()
|
||||
.With(new Win32PlatformOptions
|
||||
{
|
||||
CompositionMode = [ Win32CompositionMode.WinUIComposition, Win32CompositionMode.DirectComposition ]
|
||||
CompositionMode = [Win32CompositionMode.WinUIComposition, Win32CompositionMode.DirectComposition]
|
||||
});
|
||||
}
|
||||
|
||||
private static async Task InitializeDataSourceAsync(IServiceProvider services)
|
||||
{
|
||||
var dataSource = services.GetRequiredService<DataSource>();
|
||||
await dataSource.InitializeAsync();
|
||||
}
|
||||
|
||||
private static IServiceProvider BuildServices()
|
||||
{
|
||||
var builder = new ServiceCollection();
|
||||
|
||||
builder.AddSingleton<MainWindowViewModel>();
|
||||
builder.AddSingleton<DialogService>();
|
||||
builder.AddSingleton<DataSource>();
|
||||
builder.AddSingletonsFromAssemblies<PageBase>();
|
||||
builder.AddHttpClient();
|
||||
builder.AddLogging(Logger.Setup);
|
||||
|
||||
@@ -19,20 +19,17 @@ using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
|
||||
namespace Needlework.Net.ViewModels.MainWindow;
|
||||
|
||||
public partial class MainWindowViewModel
|
||||
: ObservableObject, IRecipient<DataRequestMessage>, IRecipient<HostDocumentRequestMessage>, IRecipient<InfoBarUpdateMessage>, IRecipient<OopsiesDialogRequestedMessage>
|
||||
: ObservableObject, IRecipient<InfoBarUpdateMessage>, IRecipient<OopsiesDialogRequestedMessage>
|
||||
{
|
||||
public IAvaloniaReadOnlyList<NavigationViewItem> MenuItems { get; }
|
||||
[NotifyPropertyChangedFor(nameof(CurrentPage))]
|
||||
[ObservableProperty] private NavigationViewItem _selectedMenuItem;
|
||||
public PageBase CurrentPage => (PageBase)SelectedMenuItem.Tag!;
|
||||
[ObservableProperty] private PageBase _currentPage;
|
||||
|
||||
public string Version { get; } = Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0.0.0.0";
|
||||
[ObservableProperty] private bool _isUpdateShown = false;
|
||||
@@ -42,7 +39,7 @@ public partial class MainWindowViewModel
|
||||
|
||||
public HttpClient HttpClient { get; }
|
||||
public DialogService DialogService { get; }
|
||||
public OpenApiDocumentWrapper? OpenApiDocumentWrapper { get; set; }
|
||||
public Document? OpenApiDocumentWrapper { get; set; }
|
||||
public OpenApiDocument? HostDocument { get; set; }
|
||||
|
||||
[ObservableProperty] private bool _isBusy = true;
|
||||
@@ -78,14 +75,13 @@ public partial class MainWindowViewModel
|
||||
IconSource = new BitmapIconSource() { UriSource = new Uri($"avares://NeedleworkDotNet/Assets/Icons/{p.Icon}.png") }
|
||||
}));
|
||||
SelectedMenuItem = MenuItems[0];
|
||||
CurrentPage = (PageBase)MenuItems[0].Tag!;
|
||||
|
||||
HttpClient = httpClient;
|
||||
DialogService = dialogService;
|
||||
|
||||
WeakReferenceMessenger.Default.RegisterAll(this);
|
||||
|
||||
Task.Run(FetchDataAsync);
|
||||
|
||||
_latestUpdateTimer.Elapsed += OnLatestUpdateTimerElapsed;
|
||||
_schemaVersionTimer.Elapsed += OnSchemaVersionTimerElapsed;
|
||||
_latestUpdateTimer.Start();
|
||||
@@ -95,6 +91,18 @@ public partial class MainWindowViewModel
|
||||
|
||||
}
|
||||
|
||||
partial void OnSelectedMenuItemChanged(NavigationViewItem value)
|
||||
{
|
||||
if (value.Tag is PageBase page)
|
||||
{
|
||||
CurrentPage = page;
|
||||
if (!page.IsInitialized)
|
||||
{
|
||||
Task.Run(page.InitializeAsync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnSchemaVersionTimerElapsed(object? sender, ElapsedEventArgs? e)
|
||||
{
|
||||
if (OpenApiDocumentWrapper == null) return;
|
||||
@@ -177,34 +185,6 @@ public partial class MainWindowViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FetchDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var document = await Resources.GetOpenApiDocumentAsync(HttpClient);
|
||||
HostDocument = document;
|
||||
var handler = new OpenApiDocumentWrapper(document);
|
||||
OpenApiDocumentWrapper = handler;
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new DataReadyMessage(handler));
|
||||
IsBusy = false;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to fetch OpenAPI data");
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(DataRequestMessage message)
|
||||
{
|
||||
message.Reply(OpenApiDocumentWrapper!);
|
||||
}
|
||||
|
||||
public void Receive(HostDocumentRequestMessage message)
|
||||
{
|
||||
message.Reply(HostDocument!);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void OpenUrl(string url)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Needlework.Net.ViewModels.Pages;
|
||||
|
||||
@@ -13,6 +14,12 @@ public partial class AboutViewModel : PageBase
|
||||
HttpClient = httpClient;
|
||||
}
|
||||
|
||||
public override Task InitializeAsync()
|
||||
{
|
||||
IsInitialized = true;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void OpenUrl(string url)
|
||||
{
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Needlework.Net.Messages;
|
||||
using Needlework.Net.ViewModels.Shared;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Needlework.Net.ViewModels.Pages;
|
||||
|
||||
public partial class ConsoleViewModel : PageBase, IRecipient<DataReadyMessage>
|
||||
public partial class ConsoleViewModel : PageBase
|
||||
{
|
||||
public IAvaloniaReadOnlyList<string> RequestMethods { get; } = new AvaloniaList<string>(["GET", "POST", "PUT", "DELETE", "HEAD", "PATCH", "OPTIONS", "TRACE"]);
|
||||
public IAvaloniaList<string> RequestPaths { get; } = new AvaloniaList<string>();
|
||||
@@ -17,10 +16,24 @@ public partial class ConsoleViewModel : PageBase, IRecipient<DataReadyMessage>
|
||||
[ObservableProperty] private bool _isBusy = true;
|
||||
[ObservableProperty] private LcuRequestViewModel _lcuRequest;
|
||||
|
||||
public ConsoleViewModel(ILogger<LcuRequestViewModel> lcuRequestViewModelLogger) : base("Console", "terminal", -200)
|
||||
private readonly DataSource _dataSource;
|
||||
|
||||
public ConsoleViewModel(ILogger<LcuRequestViewModel> lcuRequestViewModelLogger, DataSource dataSource) : base("Console", "terminal", -200)
|
||||
{
|
||||
_lcuRequest = new(lcuRequestViewModelLogger);
|
||||
WeakReferenceMessenger.Default.Register<DataReadyMessage>(this);
|
||||
_dataSource = dataSource;
|
||||
}
|
||||
|
||||
public override async Task InitializeAsync()
|
||||
{
|
||||
var document = await _dataSource.GetLolClientDocumentAsync();
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
{
|
||||
RequestPaths.Clear();
|
||||
RequestPaths.AddRange(document.Paths);
|
||||
});
|
||||
IsBusy = false;
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -28,14 +41,4 @@ public partial class ConsoleViewModel : PageBase, IRecipient<DataReadyMessage>
|
||||
{
|
||||
await LcuRequest.ExecuteAsync();
|
||||
}
|
||||
|
||||
public void Receive(DataReadyMessage message)
|
||||
{
|
||||
Avalonia.Threading.Dispatcher.UIThread.Invoke(() =>
|
||||
{
|
||||
RequestPaths.Clear();
|
||||
RequestPaths.AddRange(message.Value.Paths);
|
||||
IsBusy = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using Avalonia.Collections;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Needlework.Net.Messages;
|
||||
using Needlework.Net.ViewModels.Shared;
|
||||
using System;
|
||||
using System.Linq;
|
||||
@@ -23,12 +21,10 @@ public partial class EndpointViewModel : ObservableObject
|
||||
|
||||
public event EventHandler<string>? PathOperationSelected;
|
||||
|
||||
public EndpointViewModel(string endpoint, ILogger<LcuRequestViewModel> lcuRequestViewModelLogger)
|
||||
public EndpointViewModel(string endpoint, ILogger<LcuRequestViewModel> lcuRequestViewModelLogger, Models.Document lcuSchemaDocument)
|
||||
{
|
||||
Endpoint = endpoint;
|
||||
|
||||
var handler = WeakReferenceMessenger.Default.Send<DataRequestMessage>().Response;
|
||||
PathOperations = new AvaloniaList<PathOperationViewModel>(handler.Plugins[endpoint].Select(x => new PathOperationViewModel(x, lcuRequestViewModelLogger)));
|
||||
PathOperations = new AvaloniaList<PathOperationViewModel>(lcuSchemaDocument.Plugins[endpoint].Select(x => new PathOperationViewModel(x, lcuRequestViewModelLogger, lcuSchemaDocument)));
|
||||
FilteredPathOperations = new AvaloniaList<PathOperationViewModel>(PathOperations);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ public partial class EndpointsNavigationViewModel : ObservableObject
|
||||
|
||||
private readonly Action<string?, Guid> _onEndpointNavigation;
|
||||
|
||||
public EndpointsNavigationViewModel(IAvaloniaList<string> plugins, Action<string?, Guid> onEndpointNavigation, ILogger<LcuRequestViewModel> lcuRequestViewModelLogger)
|
||||
public EndpointsNavigationViewModel(IAvaloniaList<string> plugins, Action<string?, Guid> onEndpointNavigation, ILogger<LcuRequestViewModel> lcuRequestViewModelLogger, Models.Document lcuSchemaDocument)
|
||||
{
|
||||
_activeViewModel = _endpointsViewModel = new EndpointsViewModel(plugins, OnClicked, lcuRequestViewModelLogger);
|
||||
_activeViewModel = _endpointsViewModel = new EndpointsViewModel(plugins, OnClicked, lcuRequestViewModelLogger, lcuSchemaDocument);
|
||||
_onEndpointNavigation = onEndpointNavigation;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@ using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Needlework.Net.Messages;
|
||||
using Needlework.Net.ViewModels.Shared;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Needlework.Net.ViewModels.Pages.Endpoints;
|
||||
|
||||
public partial class EndpointsTabViewModel : PageBase, IRecipient<DataReadyMessage>
|
||||
public partial class EndpointsTabViewModel : PageBase
|
||||
{
|
||||
public IAvaloniaList<string> Plugins { get; } = new AvaloniaList<string>();
|
||||
public IAvaloniaList<EndpointItem> Endpoints { get; } = new AvaloniaList<EndpointItem>();
|
||||
@@ -19,28 +19,31 @@ public partial class EndpointsTabViewModel : PageBase, IRecipient<DataReadyMessa
|
||||
[ObservableProperty] private bool _isBusy = true;
|
||||
|
||||
private readonly ILogger<LcuRequestViewModel> _lcuRequestViewModelLogger;
|
||||
private readonly DataSource _dataSource;
|
||||
|
||||
public EndpointsTabViewModel(ILogger<LcuRequestViewModel> lcuRequestViewModelLogger) : base("Endpoints", "list-alt", -500)
|
||||
public EndpointsTabViewModel(ILogger<LcuRequestViewModel> lcuRequestViewModelLogger, DataSource dataSource) : base("Endpoints", "list-alt", -500)
|
||||
{
|
||||
_lcuRequestViewModelLogger = lcuRequestViewModelLogger;
|
||||
_dataSource = dataSource;
|
||||
WeakReferenceMessenger.Default.RegisterAll(this);
|
||||
}
|
||||
|
||||
public void Receive(DataReadyMessage message)
|
||||
public override async Task InitializeAsync()
|
||||
{
|
||||
IsBusy = false;
|
||||
var document = await _dataSource.GetLcuSchemaDocumentAsync();
|
||||
Plugins.Clear();
|
||||
Plugins.AddRange(message.Value.Plugins.Keys);
|
||||
|
||||
Dispatcher.UIThread.Post(AddEndpoint);
|
||||
Plugins.AddRange(document.Plugins.Keys);
|
||||
await Dispatcher.UIThread.Invoke(AddEndpoint);
|
||||
IsBusy = false;
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void AddEndpoint()
|
||||
private async Task AddEndpoint()
|
||||
{
|
||||
var lcuSchemaDocument = await _dataSource.GetLcuSchemaDocumentAsync();
|
||||
Endpoints.Add(new()
|
||||
{
|
||||
Content = new EndpointsNavigationViewModel(Plugins, OnEndpointNavigation, _lcuRequestViewModelLogger),
|
||||
Content = new EndpointsNavigationViewModel(Plugins, OnEndpointNavigation, _lcuRequestViewModelLogger, lcuSchemaDocument),
|
||||
Selected = true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Needlework.Net.Models;
|
||||
using Needlework.Net.ViewModels.Shared;
|
||||
using System;
|
||||
using System.Linq;
|
||||
@@ -19,13 +20,15 @@ public partial class EndpointsViewModel : ObservableObject
|
||||
public Action<ObservableObject> OnClicked { get; }
|
||||
|
||||
private readonly ILogger<LcuRequestViewModel> _lcuRequestViewModelLogger;
|
||||
private readonly Document _lcuSchemaDocument;
|
||||
|
||||
public EndpointsViewModel(IAvaloniaList<string> plugins, Action<ObservableObject> onClicked, ILogger<LcuRequestViewModel> lcuRequestViewModelLogger)
|
||||
public EndpointsViewModel(IAvaloniaList<string> plugins, Action<ObservableObject> onClicked, ILogger<LcuRequestViewModel> lcuRequestViewModelLogger, Models.Document lcuSchemaDocument)
|
||||
{
|
||||
Plugins = new AvaloniaList<string>(plugins);
|
||||
Query = new AvaloniaList<string>(plugins);
|
||||
OnClicked = onClicked;
|
||||
_lcuRequestViewModelLogger = lcuRequestViewModelLogger;
|
||||
_lcuSchemaDocument = lcuSchemaDocument;
|
||||
}
|
||||
|
||||
partial void OnSearchChanged(string value)
|
||||
@@ -42,6 +45,6 @@ public partial class EndpointsViewModel : ObservableObject
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) return;
|
||||
|
||||
OnClicked.Invoke(new EndpointViewModel(value, _lcuRequestViewModelLogger));
|
||||
OnClicked.Invoke(new EndpointViewModel(value, _lcuRequestViewModelLogger, _lcuSchemaDocument));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using Avalonia.Collections;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Needlework.Net.Messages;
|
||||
using Needlework.Net.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
@@ -22,23 +21,23 @@ public partial class OperationViewModel : ObservableObject
|
||||
public IAvaloniaReadOnlyList<ParameterViewModel> QueryParameters { get; }
|
||||
public string? RequestTemplate { get; }
|
||||
|
||||
public OperationViewModel(OpenApiOperation operation)
|
||||
public OperationViewModel(OpenApiOperation operation, Models.Document lcuSchemaDocument)
|
||||
{
|
||||
Summary = operation.Summary ?? string.Empty;
|
||||
Description = operation.Description ?? string.Empty;
|
||||
IsRequestBody = operation.RequestBody != null;
|
||||
ReturnType = GetReturnType(operation.Responses);
|
||||
RequestClasses = GetRequestClasses(operation.RequestBody);
|
||||
ResponseClasses = GetResponseClasses(operation.Responses);
|
||||
RequestClasses = GetRequestClasses(operation.RequestBody, lcuSchemaDocument);
|
||||
ResponseClasses = GetResponseClasses(operation.Responses, lcuSchemaDocument);
|
||||
PathParameters = GetParameters(operation.Parameters, ParameterLocation.Path);
|
||||
QueryParameters = GetParameters(operation.Parameters, ParameterLocation.Query);
|
||||
RequestBodyType = GetRequestBodyType(operation.RequestBody);
|
||||
RequestTemplate = GetRequestTemplate(operation.RequestBody);
|
||||
RequestTemplate = GetRequestTemplate(operation.RequestBody, lcuSchemaDocument);
|
||||
}
|
||||
|
||||
private string? GetRequestTemplate(OpenApiRequestBody? requestBody)
|
||||
private string? GetRequestTemplate(OpenApiRequestBody? requestBody, Document lcuSchemaDocument)
|
||||
{
|
||||
var requestClasses = GetRequestClasses(requestBody);
|
||||
var requestClasses = GetRequestClasses(requestBody, lcuSchemaDocument);
|
||||
if (requestClasses.Count == 0)
|
||||
{
|
||||
var type = GetRequestBodyType(requestBody);
|
||||
@@ -133,12 +132,12 @@ public partial class OperationViewModel : ObservableObject
|
||||
return pathParameters;
|
||||
}
|
||||
|
||||
private AvaloniaList<PropertyClassViewModel> GetResponseClasses(OpenApiResponses responses)
|
||||
private AvaloniaList<PropertyClassViewModel> GetResponseClasses(OpenApiResponses responses, Document lcuSchemaDocument)
|
||||
{
|
||||
if (responses.TryGetValue("2XX", out var response)
|
||||
&& response.Content.TryGetValue("application/json", out var media))
|
||||
{
|
||||
var document = WeakReferenceMessenger.Default.Send(new HostDocumentRequestMessage()).Response;
|
||||
var document = lcuSchemaDocument.OpenApiDocument;
|
||||
var schema = media.Schema;
|
||||
AvaloniaList<PropertyClassViewModel> propertyClasses = [];
|
||||
WalkSchema(schema, propertyClasses, document);
|
||||
@@ -186,12 +185,12 @@ public partial class OperationViewModel : ObservableObject
|
||||
|| type.Contains("number"));
|
||||
}
|
||||
|
||||
private AvaloniaList<PropertyClassViewModel> GetRequestClasses(OpenApiRequestBody? requestBody)
|
||||
private AvaloniaList<PropertyClassViewModel> GetRequestClasses(OpenApiRequestBody? requestBody, Document lcuSchemaDocument)
|
||||
{
|
||||
if (requestBody == null) return [];
|
||||
if (requestBody.Content.TryGetValue("application/json", out var media))
|
||||
{
|
||||
var document = WeakReferenceMessenger.Default.Send(new HostDocumentRequestMessage()).Response;
|
||||
var document = lcuSchemaDocument.OpenApiDocument;
|
||||
var schema = media.Schema;
|
||||
if (schema == null) return [];
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Avalonia.Controls;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Needlework.Net.Models;
|
||||
@@ -20,10 +19,10 @@ public partial class PathOperationViewModel : ObservableObject
|
||||
[ObservableProperty] private bool _isBusy;
|
||||
[ObservableProperty] private Lazy<LcuRequestViewModel> _lcuRequest;
|
||||
|
||||
public PathOperationViewModel(PathOperation pathOperation, ILogger<LcuRequestViewModel> lcuRequestViewModelLogger)
|
||||
public PathOperationViewModel(PathOperation pathOperation, ILogger<LcuRequestViewModel> lcuRequestViewModelLogger, Document lcuSchemaDocument)
|
||||
{
|
||||
Path = pathOperation.Path;
|
||||
Operation = new OperationViewModel(pathOperation.Operation);
|
||||
Operation = new OperationViewModel(pathOperation.Operation, lcuSchemaDocument);
|
||||
LcuRequest = new(() => new LcuRequestViewModel(lcuRequestViewModelLogger)
|
||||
{
|
||||
Method = pathOperation.Method.ToUpper()
|
||||
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Needlework.Net.ViewModels.Pages;
|
||||
|
||||
@@ -14,6 +15,12 @@ public partial class HomeViewModel : PageBase
|
||||
|
||||
public HomeViewModel() : base("Home", "home", int.MinValue) { }
|
||||
|
||||
public override Task InitializeAsync()
|
||||
{
|
||||
IsInitialized = true;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void OpenUrl(string url)
|
||||
{
|
||||
@@ -23,4 +30,5 @@ public partial class HomeViewModel : PageBase
|
||||
};
|
||||
process.Start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Needlework.Net.ViewModels.Pages;
|
||||
|
||||
@@ -8,4 +9,7 @@ public abstract partial class PageBase(string displayName, string icon, int inde
|
||||
[ObservableProperty] private string _displayName = displayName;
|
||||
[ObservableProperty] private string _icon = icon;
|
||||
[ObservableProperty] private int _index = index;
|
||||
[ObservableProperty] private bool _isInitialized;
|
||||
|
||||
public abstract Task InitializeAsync();
|
||||
}
|
||||
@@ -59,6 +59,12 @@ public partial class WebsocketViewModel : PageBase
|
||||
});
|
||||
}
|
||||
|
||||
public override Task InitializeAsync()
|
||||
{
|
||||
IsInitialized = true;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task InitializeEventTypes()
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user