feat: add force disconnect handling and improve user ban notifications

This commit is contained in:
HueByte
2026-02-19 22:09:54 +01:00
parent 7a8b5f02d3
commit 107152298e
3 changed files with 47 additions and 7 deletions
+15 -7
View File
@@ -830,25 +830,33 @@ public sealed class AppOrchestrator : IDisposable
InvokeUI(() => InvokeUI(() =>
{ {
_mainWindow.AddSystemMessage(channelName, $"{username} was kicked{reasonText}"); _mainWindow.AddSystemMessage(channelName, $"{username} was kicked{reasonText}");
if (username.Equals(_currentUsername, StringComparison.OrdinalIgnoreCase))
{
_mainWindow.AddSystemMessage(channelName, "You were kicked from this channel.");
}
}); });
}; };
connection.OnUserBanned += (username, reason) => connection.OnUserBanned += (username, reason) =>
{ {
var reasonText = reason is not null ? $" ({reason})" : "";
InvokeUI(() => InvokeUI(() =>
{ {
if (username.Equals(_currentUsername, StringComparison.OrdinalIgnoreCase)) // Show ban notification for other users in the channel
if (!username.Equals(_currentUsername, StringComparison.OrdinalIgnoreCase))
{ {
_mainWindow.ShowError("You have been banned from this server."); var channel = _mainWindow.CurrentChannel;
HandleDisconnect(); if (!string.IsNullOrEmpty(channel))
_mainWindow.AddSystemMessage(channel, $"{username} was banned{reasonText}");
} }
}); });
}; };
connection.OnForceDisconnect += reason =>
{
InvokeUI(() =>
{
_mainWindow.ShowError(reason);
HandleDisconnect();
});
};
connection.OnMessageDeleted += (channelName, messageId) => connection.OnMessageDeleted += (channelName, messageId) =>
{ {
InvokeUI(() => InvokeUI(() =>
@@ -18,6 +18,7 @@ public sealed class EchoHubConnection : IAsyncDisposable
public event Action<string, string?>? OnUserBanned; public event Action<string, string?>? OnUserBanned;
public event Action<string, Guid>? OnMessageDeleted; public event Action<string, Guid>? OnMessageDeleted;
public event Action<string>? OnChannelNuked; public event Action<string>? OnChannelNuked;
public event Action<string>? OnForceDisconnect;
public event Action<string>? OnError; public event Action<string>? OnError;
public event Action<string>? OnConnectionStateChanged; public event Action<string>? OnConnectionStateChanged;
public event Action? OnReconnected; public event Action? OnReconnected;
@@ -105,6 +106,11 @@ public sealed class EchoHubConnection : IAsyncDisposable
OnChannelNuked?.Invoke(channelName); OnChannelNuked?.Invoke(channelName);
}); });
_connection.On<string>(nameof(Core.Contracts.IEchoHubClient.ForceDisconnect), reason =>
{
OnForceDisconnect?.Invoke(reason);
});
_connection.On<string>(nameof(Core.Contracts.IEchoHubClient.Error), message => _connection.On<string>(nameof(Core.Contracts.IEchoHubClient.Error), message =>
{ {
OnError?.Invoke(message); OnError?.Invoke(message);
+26
View File
@@ -197,6 +197,7 @@ public sealed class MainWindow : Runnable
WordWrap = true WordWrap = true
}; };
_inputField.KeyDown += OnInputKeyDown; _inputField.KeyDown += OnInputKeyDown;
_inputField.ContentsChanged += OnInputContentsChanged;
_inputFrame.Add(_inputField); _inputFrame.Add(_inputField);
Add(_inputFrame); Add(_inputFrame);
@@ -388,6 +389,31 @@ public sealed class MainWindow : Runnable
} }
} }
private bool _suppressEmojiReplace;
private void OnInputContentsChanged(object? sender, ContentsChangedEventArgs e)
{
if (_suppressEmojiReplace)
return;
var text = _inputField.Text;
if (string.IsNullOrEmpty(text))
return;
var replaced = EmojiHelper.ReplaceEmoji(text);
if (replaced == text)
return;
// Calculate where cursor should land after replacement
var lengthDelta = replaced.Length - text.Length;
var newCol = Math.Max(0, _inputField.CurrentColumn + lengthDelta);
_suppressEmojiReplace = true;
_inputField.Text = replaced;
_inputField.InsertionPoint = new System.Drawing.Point(newCol, _inputField.CurrentRow);
_suppressEmojiReplace = false;
}
/// <summary> /// <summary>
/// Tab-complete slash commands in the input field. /// Tab-complete slash commands in the input field.
/// </summary> /// </summary>