From 0ffcc4c4e071ceaa61ead080ce5272b7876b0285 Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 10 Jun 2026 22:42:31 +0100 Subject: [PATCH] Fixed Clear Line issue --- .../Components/Pages/SerialTerminal.razor | 23 ++++++++++++++++++- .../Components/Pages/SerialTerminal.razor.js | 4 ++++ .../Services/ISerialPortService.cs | 3 +++ .../Services/SerialPortService.cs | 6 +++++ 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 IOModuleTestBlazor/Components/Pages/SerialTerminal.razor.js diff --git a/IOModuleTestBlazor/Components/Pages/SerialTerminal.razor b/IOModuleTestBlazor/Components/Pages/SerialTerminal.razor index 022349d..df2137d 100644 --- a/IOModuleTestBlazor/Components/Pages/SerialTerminal.razor +++ b/IOModuleTestBlazor/Components/Pages/SerialTerminal.razor @@ -4,6 +4,7 @@ @using IOModuleTestBlazor.Services @inject ISerialPortService SerialService +@inject IJSRuntime JS Serial Terminal @@ -122,6 +123,8 @@ private string? _connectError; private List _availablePorts = new(); private List _displayLines = new(); + private IJSObjectReference? _jsModule; + private bool _scrollPending = false; private static readonly (string Label, string Cmd)[] _quickCommands = [ @@ -188,15 +191,30 @@ InvokeAsync(() => { RefreshLines(); + _scrollPending = true; StateHasChanged(); }); } + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + _jsModule = await JS.InvokeAsync( + "import", "./Components/Pages/SerialTerminal.razor.js"); + + if (_scrollPending && _jsModule is not null) + { + _scrollPending = false; + await _jsModule.InvokeVoidAsync("scrollToBottom", "terminal-output"); + } + } + private void RefreshLines() => _displayLines = SerialService.GetLines().ToList(); private void ClearTerminal() { + SerialService.ClearLines(); _displayLines.Clear(); StateHasChanged(); } @@ -205,5 +223,8 @@ => string.Join("\n", _displayLines); public void Dispose() - => SerialService.DataReceived -= OnDataReceived; + { + SerialService.DataReceived -= OnDataReceived; + _jsModule?.DisposeAsync(); + } } diff --git a/IOModuleTestBlazor/Components/Pages/SerialTerminal.razor.js b/IOModuleTestBlazor/Components/Pages/SerialTerminal.razor.js new file mode 100644 index 0000000..7dd5524 --- /dev/null +++ b/IOModuleTestBlazor/Components/Pages/SerialTerminal.razor.js @@ -0,0 +1,4 @@ +export function scrollToBottom(elementId) { + const el = document.getElementById(elementId); + if (el) el.scrollTop = el.scrollHeight; +} diff --git a/IOModuleTestBlazor/Services/ISerialPortService.cs b/IOModuleTestBlazor/Services/ISerialPortService.cs index e0c8939..fc8d2ba 100644 --- a/IOModuleTestBlazor/Services/ISerialPortService.cs +++ b/IOModuleTestBlazor/Services/ISerialPortService.cs @@ -21,6 +21,9 @@ public interface ISerialPortService /// Each line is prefixed with "> " (sent) or "< " (received). IReadOnlyList GetLines(); + /// Clears the line buffer. + void ClearLines(); + /// Fired on the SerialPort receive thread when new lines arrive. event Action? DataReceived; } diff --git a/IOModuleTestBlazor/Services/SerialPortService.cs b/IOModuleTestBlazor/Services/SerialPortService.cs index b033b4c..e5585da 100644 --- a/IOModuleTestBlazor/Services/SerialPortService.cs +++ b/IOModuleTestBlazor/Services/SerialPortService.cs @@ -97,6 +97,12 @@ public sealed class SerialPortService : ISerialPortService, IDisposable return _lines.ToList(); } + public void ClearLines() + { + lock (_lock) + _lines.Clear(); + } + private void OnDataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort? port;