bug fix in WebsocketView, optimization and others

This commit is contained in:
AoshiW
2024-08-16 08:17:43 +02:00
parent b0b5476c48
commit 3a7d39971a
10 changed files with 71 additions and 52 deletions

View File

@@ -12,7 +12,7 @@
<ApplicationIcon>app.ico</ApplicationIcon>
<AssemblyName>NeedleworkDotNet</AssemblyName>
<AssemblyVersion>0.4.1.0</AssemblyVersion>
<FileVersion>0.4.1.0</FileVersion>
<FileVersion>$(AssemblyVersion)</FileVersion>
<AvaloniaXamlVerboseExceptions>False</AvaloniaXamlVerboseExceptions>
</PropertyGroup>

View File

@@ -16,10 +16,10 @@ namespace Needlework.Net.Desktop.ViewModels
public partial class ConsoleViewModel : PageBase, IRecipient<DataReadyMessage>
{
public IAvaloniaReadOnlyList<string> RequestMethods { get; } = new AvaloniaList<string>(["GET", "POST", "PUT", "DELETE", "HEAD", "PATCH", "OPTIONS", "TRACE"]);
public IAvaloniaList<string> RequestPaths { get; } = new AvaloniaList<string>();
[ObservableProperty] private bool _isBusy = true;
[ObservableProperty] private bool _isRequestBusy = false;
[ObservableProperty] private IAvaloniaReadOnlyList<string> _requestPaths = new AvaloniaList<string>();
[ObservableProperty] private string? _requestMethodSelected = "GET";
[ObservableProperty] private string? _requestPath = null;
[ObservableProperty] private string? _requestBody = null;
@@ -60,11 +60,18 @@ namespace Needlework.Net.Desktop.ViewModels
var processInfo = Connector.GetProcessInfo();
var requestBody = WeakReferenceMessenger.Default.Send(new ContentRequestMessage(), "ConsoleRequestEditor").Response;
var content = new StringContent(Regex.Replace(requestBody, @"\s+", ""), new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
var response = await Connector.SendAsync(method, RequestPath, content) ?? throw new Exception("Response is null.");
var response = await Connector.SendAsync(method, RequestPath, content);
var riotAuthentication = new RiotAuthentication(processInfo.RemotingAuthToken);
var body = await response.Content.ReadAsStringAsync();
var responseBody =
#if DEBUG
await response.Content.ReadAsStringAsync();
#else
await response.Content.ReadAsByteArrayAsync();
#endif
body = !string.IsNullOrEmpty(body) ? JsonSerializer.Serialize(JsonSerializer.Deserialize<object>(body), App.JsonSerializerOptions) : string.Empty;
var body = responseBody.Length > 0
? JsonSerializer.Serialize(JsonSerializer.Deserialize<object>(responseBody), App.JsonSerializerOptions)
: string.Empty;
if (body.Length >= App.MaxCharacters)
{
WindowService.ShowOopsiesWindow(body);
@@ -94,7 +101,8 @@ namespace Needlework.Net.Desktop.ViewModels
{
Avalonia.Threading.Dispatcher.UIThread.Invoke(() =>
{
RequestPaths = new AvaloniaList<string>([.. message.Value.Paths]);
RequestPaths.Clear();
RequestPaths.AddRange(message.Value.Paths);
IsBusy = false;
});
}

View File

@@ -2,6 +2,8 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Needlework.Net.Desktop.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Needlework.Net.Desktop.ViewModels
@@ -12,11 +14,11 @@ namespace Needlework.Net.Desktop.ViewModels
public string Title => Endpoint;
[ObservableProperty] private IAvaloniaReadOnlyList<PathOperationViewModel> _pathOperations;
public IAvaloniaReadOnlyList<PathOperationViewModel> PathOperations { get; }
[ObservableProperty] private PathOperationViewModel? _selectedPathOperation;
[ObservableProperty] private string? _search;
[ObservableProperty] private IAvaloniaReadOnlyList<PathOperationViewModel> _filteredPathOperations;
public IAvaloniaList<PathOperationViewModel> FilteredPathOperations { get; }
public EndpointViewModel(string endpoint)
{
@@ -29,13 +31,14 @@ namespace Needlework.Net.Desktop.ViewModels
partial void OnSearchChanged(string? value)
{
FilteredPathOperations.Clear();
if (string.IsNullOrWhiteSpace(value))
{
FilteredPathOperations = new AvaloniaList<PathOperationViewModel>(PathOperations);
FilteredPathOperations.AddRange(PathOperations);
return;
}
FilteredPathOperations = new AvaloniaList<PathOperationViewModel>(PathOperations.Where(o => o.Path.ToLower().Contains(value.ToLower())));
FilteredPathOperations.AddRange(PathOperations.Where(o => o.Path.Contains(value, StringComparison.InvariantCultureIgnoreCase)));
}
partial void OnSelectedPathOperationChanged(PathOperationViewModel? value)

View File

@@ -15,11 +15,11 @@ namespace Needlework.Net.Desktop.ViewModels
public string Title => "Endpoints";
public Action<ObservableObject> OnClicked;
public IAvaloniaList<string> Plugins { get; } = new AvaloniaList<string>();
public IAvaloniaList<string> Query { get; } = new AvaloniaList<string>();
[ObservableProperty] private IAvaloniaReadOnlyList<string> _plugins = new AvaloniaList<string>();
[ObservableProperty] private bool _isBusy = true;
[ObservableProperty] private string _search = string.Empty;
[ObservableProperty] private IAvaloniaReadOnlyList<string> _query = new AvaloniaList<string>();
[ObservableProperty] private string? _selectedQuery = string.Empty;
public EndpointsViewModel(HttpClient httpClient, Action<ObservableObject> onClicked)
@@ -33,16 +33,19 @@ namespace Needlework.Net.Desktop.ViewModels
public void Receive(DataReadyMessage message)
{
IsBusy = false;
Plugins = new AvaloniaList<string>([.. message.Value.Plugins.Keys]);
Query = new AvaloniaList<string>([.. Plugins]);
Plugins.Clear();
Plugins.AddRange(message.Value.Plugins.Keys);
Query.Clear();
Query.AddRange(Plugins);
}
partial void OnSearchChanged(string value)
{
Query.Clear();
if (!string.IsNullOrEmpty(Search))
Query = new AvaloniaList<string>(Plugins.Where(x => x.Contains(value)));
Query.AddRange(Plugins.Where(x => x.Contains(value, StringComparison.InvariantCultureIgnoreCase)));
else
Query = Plugins;
Query.AddRange(Plugins);
}
[RelayCommand]

View File

@@ -63,7 +63,7 @@ namespace Needlework.Net.Desktop.ViewModels
private void ProcessEvents(object? obj)
{
while (true)
while (!IsUpdateShown)
{
Task.Run(CheckLatestVersionAsync);
@@ -84,7 +84,7 @@ namespace Needlework.Net.Desktop.ViewModels
var currentVersion = int.Parse(Version.Replace(".", ""));
if (release.IsLatest(currentVersion) && !IsUpdateShown)
if (release.IsLatest(currentVersion))
{
Avalonia.Threading.Dispatcher.UIThread.Post(async () =>
{

View File

@@ -7,6 +7,7 @@ using Needlework.Net.Core;
using Needlework.Net.Desktop.Messages;
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -32,14 +33,18 @@ namespace Needlework.Net.Desktop.ViewModels
public PathOperationViewModel(PathOperation pathOperation)
{
Method = pathOperation.Method.ToUpper();
Color = new SolidColorBrush(GetColor(pathOperation.Method.ToUpper()));
Color = new SolidColorBrush(GetColor(Method));
Path = pathOperation.Path;
Operation = new OperationViewModel(pathOperation.Operation);
ProcessInfo = GetProcessInfo();
ResponsePath = ProcessInfo != null ? $"https://127.0.0.1:{ProcessInfo.AppPort}{Path}" : null;
ResponseUsername = ProcessInfo != null ? new RiotAuthentication(ProcessInfo.RemotingAuthToken).Username : null;
ResponsePassword = ProcessInfo != null ? new RiotAuthentication(ProcessInfo.RemotingAuthToken).Password : null;
ResponseAuthorization = ProcessInfo != null ? $"Basic {new RiotAuthentication(ProcessInfo.RemotingAuthToken).Value}" : null;
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()
@@ -60,7 +65,7 @@ namespace Needlework.Net.Desktop.ViewModels
{
IsBusy = true;
var method = Method.ToUpper() switch
var method = Method switch
{
"GET" => HttpMethod.Get,
"POST" => HttpMethod.Post,
@@ -74,26 +79,28 @@ namespace Needlework.Net.Desktop.ViewModels
};
var processInfo = Connector.GetProcessInfo();
var path = Path;
var sb = new StringBuilder(Path);
foreach (var pathParameter in Operation.PathParameters)
{
path = path.Replace($"{{{pathParameter.Name}}}", pathParameter.Value);
sb.Replace($"{{{pathParameter.Name}}}", pathParameter.Value);
}
var query = "";
var firstQueryAdded = false;
foreach (var queryParameter in Operation.QueryParameters)
{
if (query.Length != 0 && !string.IsNullOrWhiteSpace(queryParameter.Value))
query += $"&{queryParameter.Name}={Uri.EscapeDataString(queryParameter.Value)}";
else if (query.Length == 0 && !string.IsNullOrWhiteSpace(queryParameter.Value))
query += $"?{queryParameter.Name}={Uri.EscapeDataString(queryParameter.Value)}";
if (!string.IsNullOrWhiteSpace(queryParameter.Value))
{
sb.Append(firstQueryAdded ? '&' : '?');
firstQueryAdded = true;
sb.Append($"{queryParameter.Name}={Uri.EscapeDataString(queryParameter.Value)}");
}
}
var uri = $"{path}{query}";
var uri = sb.ToString();
var requestBody = WeakReferenceMessenger.Default.Send(new ContentRequestMessage(), "EndpointRequestEditor").Response;
var content = new StringContent(Regex.Replace(requestBody, @"\s+", ""), new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
var response = await Connector.SendAsync(method, $"{uri}", content) ?? throw new Exception("Response is null.");
var response = await Connector.SendAsync(method, uri, content) ?? throw new Exception("Response is null.");
var riotAuthentication = new RiotAuthentication(processInfo.RemotingAuthToken);
var responseBody = await response.Content.ReadAsStringAsync();

View File

@@ -17,8 +17,7 @@ namespace Needlework.Net.Desktop.ViewModels
{
public partial class WebsocketViewModel : PageBase
{
[NotifyPropertyChangedFor(nameof(FilteredEventLog))]
[ObservableProperty] private ObservableCollection<string> _eventLog = [];
public ObservableCollection<string> EventLog { get; } = [];
[NotifyPropertyChangedFor(nameof(FilteredEventLog))]
[ObservableProperty] private string _search = string.Empty;
[ObservableProperty] private bool _isAttach = true;
@@ -31,12 +30,12 @@ namespace Needlework.Net.Desktop.ViewModels
public WindowService WindowService { get; }
public List<string> FilteredEventLog => string.IsNullOrWhiteSpace(Search) ? [.. EventLog] : [.. EventLog.Where(x => x.ToLower().Contains(Search.ToLower()))];
public IReadOnlyList<string> FilteredEventLog => string.IsNullOrWhiteSpace(Search) ? EventLog : [.. EventLog.Where(x => x.Contains(Search, StringComparison.InvariantCultureIgnoreCase))];
public WebsocketViewModel(WindowService windowService) : base("Event Viewer", "plug", -100)
{
WindowService = windowService;
EventLog.CollectionChanged += (s, e) => OnPropertyChanged(nameof(FilteredEventLog));
var thread = new Thread(InitializeWebsocket) { IsBackground = true };
thread.Start();
}
@@ -65,7 +64,8 @@ namespace Needlework.Net.Desktop.ViewModels
[RelayCommand]
private void Clear()
{
EventLog = [];
_events.Clear();
EventLog.Clear();
}
partial void OnSelectedEventLogChanged(string? value)
@@ -99,25 +99,21 @@ namespace Needlework.Net.Desktop.ViewModels
if (!IsAttach) return;
var line = $"{DateTime.Now:HH:mm:ss.fff} {message.Data?.EventType.ToUpper()} {message.Data?.Uri}";
var log = EventLog.ToList();
Trace.WriteLine($"Message: {line}");
if (log.Count < 1000)
if (EventLog.Count < 1000)
{
log.Add(line);
EventLog.Add(line);
_events[line] = message;
}
else
{
var key = $"{log[0]}";
log.RemoveAt(0);
var key = EventLog[0];
EventLog.RemoveAt(0);
_events.Remove(key);
log.Add(line);
EventLog.Add(line);
_events[line] = message;
}
EventLog = []; // This is a hack needed to update for ListBox
EventLog = new ObservableCollection<string>(log);
});
}
}

View File

@@ -55,6 +55,7 @@
<Grid
RowDefinitions="*"
ColumnDefinitions="auto,*">
<!-- TODO change button to sometnig else or disabled "highlighting"-->
<Button
VerticalAlignment="Center"
Classes="Flat"

View File

@@ -82,6 +82,7 @@
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Border Margin="4">
<!-- TODO add some background to InfoBar (currently it is (probably) transparent and you can see other things under it) -->
<ui:InfoBar
Title="{Binding Title}"
IsOpen="{Binding IsOpen}"

View File

@@ -31,7 +31,7 @@ public partial class WebsocketView : UserControl, IRecipient<ResponseUpdatedMess
var vm = (WebsocketViewModel)DataContext!;
var viewer = this.FindControl<ListBox>("EventViewer");
viewer!.PropertyChanged += (s, e) => { if (vm.IsTail) viewer.ScrollIntoView(vm.EventLog.Count - 1); };
vm.EventLog.CollectionChanged += (s, e) => { if (vm.IsTail) viewer!.ScrollIntoView(vm.EventLog.Count - 1); };
_responseEditor = this.FindControl<TextEditor>("ResponseEditor");
_responseEditor?.ApplyJsonEditorSettings();