diff --git a/Needlework.Net/Needlework.Net.csproj b/Needlework.Net/Needlework.Net.csproj index b18e993..1a7beb8 100644 --- a/Needlework.Net/Needlework.Net.csproj +++ b/Needlework.Net/Needlework.Net.csproj @@ -11,7 +11,7 @@ False app.ico NeedleworkDotNet - 0.6.1.0 + 0.7.0.0 $(AssemblyVersion) False @@ -27,7 +27,7 @@ - + diff --git a/Needlework.Net/ViewLocator.cs b/Needlework.Net/ViewLocator.cs index 96e0e11..a4cfcaf 100644 --- a/Needlework.Net/ViewLocator.cs +++ b/Needlework.Net/ViewLocator.cs @@ -1,28 +1,40 @@ using Avalonia.Controls; using Avalonia.Controls.Templates; using System; +using System.Collections.Generic; using System.ComponentModel; namespace Needlework.Net { public class ViewLocator : IDataTemplate { - public Control? Build(object? param) - { - if (param is null) return new TextBlock { Text = "data was null" }; + private readonly Dictionary _controlCache = []; - var name = param.GetType().FullName! - .Replace("ViewModels", "Views") - .Replace("ViewModel", "View"); + public Control Build(object? data) + { + var fullName = data?.GetType().FullName; + if (fullName is null) + { + return new TextBlock { Text = "Data is null or has no name." }; + } + + var name = fullName.Replace("ViewModel", "View"); var type = Type.GetType(name); + if (type is null) + { + return new TextBlock { Text = $"No View For {name}." }; + } - if (type != null) return (Control)Activator.CreateInstance(type)!; - else return new TextBlock { Text = "Not Found: " + name }; + if (!_controlCache.TryGetValue(data!, out var res)) + { + res ??= (Control)Activator.CreateInstance(type)!; + _controlCache[data!] = res; + } + + res.DataContext = data; + return res; } - public bool Match(object? data) - { - return data is INotifyPropertyChanged; - } + public bool Match(object? data) => data is INotifyPropertyChanged; } } diff --git a/Needlework.Net/ViewModels/ConsoleViewModel.cs b/Needlework.Net/ViewModels/ConsoleViewModel.cs index abadfbd..8ac1fcb 100644 --- a/Needlework.Net/ViewModels/ConsoleViewModel.cs +++ b/Needlework.Net/ViewModels/ConsoleViewModel.cs @@ -51,10 +51,11 @@ namespace Needlework.Net.ViewModels _ => throw new Exception("Method is not selected."), }; - var processInfo = Connector.GetProcessInfo(); + var processInfo = ProcessFinder.Get(); var requestBody = WeakReferenceMessenger.Default.Send(new ContentRequestMessage(), "ConsoleRequestEditor").Response; var content = new StringContent(requestBody, new System.Net.Http.Headers.MediaTypeHeaderValue("application/json")); - var response = await Connector.SendAsync(method, RequestPath, content); + var client = Connector.GetLcuHttpClientInstance(); + var response = await client.SendAsync(new(method, RequestPath) { Content = content }); var riotAuthentication = new RiotAuthentication(processInfo.RemotingAuthToken); var responseBody = await response.Content.ReadAsByteArrayAsync(); diff --git a/Needlework.Net/ViewModels/PathOperationViewModel.cs b/Needlework.Net/ViewModels/PathOperationViewModel.cs index 2482058..aadd3c7 100644 --- a/Needlework.Net/ViewModels/PathOperationViewModel.cs +++ b/Needlework.Net/ViewModels/PathOperationViewModel.cs @@ -19,15 +19,12 @@ namespace Needlework.Net.ViewModels public SolidColorBrush Color { get; } public string Path { get; } public OperationViewModel Operation { get; } + public ProcessInfo? ProcessInfo { get; } [ObservableProperty] private bool _isBusy; - [ObservableProperty] private string? _responsePath; - [ObservableProperty] private string? _responseStatus; - [ObservableProperty] private string? _responseAuthentication; - [ObservableProperty] private string? _responseUsername; - [ObservableProperty] private string? _responsePassword; - [ObservableProperty] private string? _responseAuthorization; + + [ObservableProperty] private Lazy _response; public PathOperationViewModel(PathOperation pathOperation) { @@ -35,26 +32,7 @@ namespace Needlework.Net.ViewModels Color = new SolidColorBrush(GetColor(Method)); Path = pathOperation.Path; Operation = new OperationViewModel(pathOperation.Operation); - ProcessInfo = GetProcessInfo(); - if (ProcessInfo != null) - { - ResponsePath = $"https://127.0.0.1:{ProcessInfo.AppPort}{Path}"; - var riotAuth = new RiotAuthentication(ProcessInfo.RemotingAuthToken); - ResponseUsername = riotAuth.Username; - ResponsePassword = riotAuth.Password; - ResponseAuthorization = $"Basic {riotAuth.Value}"; - } - } - - private ProcessInfo? GetProcessInfo() - { - try - { - var processInfo = Connector.GetProcessInfo(); - return processInfo; - } - catch (Exception) { } - return null; + Response = new(() => new ResponseViewModel(pathOperation.Path)); } [RelayCommand] @@ -77,7 +55,7 @@ namespace Needlework.Net.ViewModels _ => throw new Exception("Method is missing.") }; - var processInfo = Connector.GetProcessInfo(); + var processInfo = ProcessFinder.Get(); var sb = new StringBuilder(Path); foreach (var pathParameter in Operation.PathParameters) { @@ -99,7 +77,8 @@ namespace Needlework.Net.ViewModels var requestBody = WeakReferenceMessenger.Default.Send(new ContentRequestMessage(), "EndpointRequestEditor").Response; var content = new StringContent(requestBody, new System.Net.Http.Headers.MediaTypeHeaderValue("application/json")); - var response = await Connector.SendAsync(method, uri, content); + var client = Connector.GetLcuHttpClientInstance(); + var response = await client.SendAsync(new(method, uri) { Content = content }); var riotAuthentication = new RiotAuthentication(processInfo.RemotingAuthToken); var responseBytes = await response.Content.ReadAsByteArrayAsync(); @@ -111,11 +90,11 @@ namespace Needlework.Net.ViewModels } else WeakReferenceMessenger.Default.Send(new EditorUpdateMessage(new(responseBody, "EndpointResponseEditor"))); - ResponseStatus = $"{(int)response.StatusCode} {response.StatusCode}"; - ResponsePath = $"https://127.0.0.1:{processInfo.AppPort}{uri}"; - ResponseAuthentication = $"Basic {riotAuthentication.Value}"; - ResponseUsername = riotAuthentication.Username; - ResponsePassword = riotAuthentication.Password; + Response.Value.Status = $"{(int)response.StatusCode} {response.StatusCode}"; + Response.Value.Path = $"https://127.0.0.1:{processInfo.AppPort}{uri}"; + Response.Value.Authentication = Response.Value.Authorization = $"Basic {riotAuthentication.Value}"; + Response.Value.Username = riotAuthentication.Username; + Response.Value.Password = riotAuthentication.Password; } catch (Exception ex) { diff --git a/Needlework.Net/ViewModels/ResponseViewModel.cs b/Needlework.Net/ViewModels/ResponseViewModel.cs new file mode 100644 index 0000000..815cb47 --- /dev/null +++ b/Needlework.Net/ViewModels/ResponseViewModel.cs @@ -0,0 +1,35 @@ +using BlossomiShymae.GrrrLCU; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Needlework.Net.ViewModels +{ + public partial class ResponseViewModel : ObservableObject + { + [ObservableProperty] private string? _path; + [ObservableProperty] private string? _status; + [ObservableProperty] private string? _authentication; + [ObservableProperty] private string? _username; + [ObservableProperty] private string? _password; + [ObservableProperty] private string? _authorization; + + public ResponseViewModel(string path) + { + Path = path; + var processInfo = GetProcessInfo(); + if (processInfo != null) + { + var riotAuthentication = new RiotAuthentication(processInfo.RemotingAuthToken); + Path = $"https://127.0.0.1:{processInfo.AppPort}{path}"; + Username = riotAuthentication.Username; + Password = riotAuthentication.Password; + Authorization = $"Basic {riotAuthentication.RawValue}"; + } + } + + private static ProcessInfo? GetProcessInfo() + { + if (ProcessFinder.IsActive()) return ProcessFinder.Get(); + return null; + } + } +} diff --git a/Needlework.Net/Views/ConsoleView.axaml.cs b/Needlework.Net/Views/ConsoleView.axaml.cs index 6aacf54..9aa5cae 100644 --- a/Needlework.Net/Views/ConsoleView.axaml.cs +++ b/Needlework.Net/Views/ConsoleView.axaml.cs @@ -1,6 +1,5 @@ using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Primitives; using Avalonia.Styling; using AvaloniaEdit; using CommunityToolkit.Mvvm.Messaging; @@ -31,9 +30,9 @@ public partial class ConsoleView : UserControl, IRecipient("ResponseEditor"); _requestEditor = this.FindControl("RequestEditor"); diff --git a/Needlework.Net/Views/EndpointView.axaml b/Needlework.Net/Views/EndpointView.axaml index 1bcc3bd..5135d79 100644 --- a/Needlework.Net/Views/EndpointView.axaml +++ b/Needlework.Net/Views/EndpointView.axaml @@ -95,7 +95,7 @@ + Text="{Binding SelectedPathOperation.Response.Value.Username}" /> + Text="{Binding SelectedPathOperation.Response.Value.Password}"/> + Text="{Binding SelectedPathOperation.Response.Value.Authorization}"/> @@ -304,22 +304,25 @@ FontSize="10" Padding="12 4 12 4" Classes="Flat" - Content="{Binding SelectedPathOperation.ResponseStatus}"/> + Content="{Binding SelectedPathOperation.Response.Value.Status}"/> - - - - - + + + + + + + diff --git a/Needlework.Net/Views/EndpointView.axaml.cs b/Needlework.Net/Views/EndpointView.axaml.cs index f436c95..3708d3b 100644 --- a/Needlework.Net/Views/EndpointView.axaml.cs +++ b/Needlework.Net/Views/EndpointView.axaml.cs @@ -1,6 +1,5 @@ using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Primitives; using Avalonia.Styling; using AvaloniaEdit; using CommunityToolkit.Mvvm.Messaging; @@ -21,9 +20,9 @@ public partial class EndpointView : UserControl, IRecipient InitializeComponent(); } - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { - base.OnApplyTemplate(e); + base.OnAttachedToVisualTree(e); var vm = (EndpointViewModel)DataContext!; _requestEditor = this.FindControl("EndpointRequestEditor");