diff --git a/src/Nonemm.App/Windows/TelnetWindow.axaml.cs b/src/Nonemm.App/Windows/TelnetWindow.axaml.cs index 36729db..099b097 100644 --- a/src/Nonemm.App/Windows/TelnetWindow.axaml.cs +++ b/src/Nonemm.App/Windows/TelnetWindow.axaml.cs @@ -107,8 +107,15 @@ public sealed partial class TelnetWindow : RefreshableWindow cluster.ConnectionChanged -= OnConnectionChanged; } - private void OnLineArrived(object? sender, string line) + /// The cluster raises its events on a socket thread, and a brush belongs to + /// the thread that made it, so the colour is chosen on the window thread. + private void OnLineArrived(object? sender, string line) => + Dispatcher.UIThread.Post(() => ShowArrived(line)); + + private void ShowArrived(string line) { + // nodes end a spot with the bell character, which draws as a box + line = line.Replace("\a", ""); if (line.StartsWith("***", StringComparison.Ordinal)) { Show(line, NoticeColour); @@ -128,7 +135,8 @@ public sealed partial class TelnetWindow : RefreshableWindow session.Settings.SpotFilter.PreferredSpotters.Any(one => one.Length > 0 && spotter.StartsWith(one, StringComparison.OrdinalIgnoreCase)); - private void OnLineSent(object? sender, string line) => Show($"> {line}", SentColour); + private void OnLineSent(object? sender, string line) => + Dispatcher.UIThread.Post(() => Show($"> {line}", SentColour)); private void OnConnectionChanged(object? sender, bool connected) => Dispatcher.UIThread.Post(Refresh); diff --git a/src/Nonemm.Spotting/ClusterClient.cs b/src/Nonemm.Spotting/ClusterClient.cs index 6806f6a..c162b0f 100644 --- a/src/Nonemm.Spotting/ClusterClient.cs +++ b/src/Nonemm.Spotting/ClusterClient.cs @@ -170,6 +170,12 @@ public sealed class ClusterClient : IDisposable catch (OperationCanceledException) { } + catch (Exception e) + { + // anything else would end the loop with nothing on the screen + Notice($"*** {Host}:{Port} stopped: {e}"); + SetConnected(false); + } } private async Task SessionAsync(CancellationToken cancellation)