mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 16:46:08 +02:00
feat: enhance IRC support with display name handling, private channel tracking, and connection identification
This commit is contained in:
@@ -381,6 +381,9 @@ public sealed class ChatMessageManager
|
||||
private List<ChatLine> FormatMessage(MessageDto message)
|
||||
{
|
||||
var time = FormatTime(message.SentAt);
|
||||
// Show the display name, but keep color + click identity keyed to the username
|
||||
// so they stay consistent with the user list and profile lookups.
|
||||
var senderName = message.SenderDisplayName ?? message.SenderUsername;
|
||||
var senderColor = HexColorHelper.ParseHexColor(message.SenderNicknameColor)
|
||||
?? NickColorHelper.GetAttribute(message.SenderUsername);
|
||||
|
||||
@@ -394,7 +397,7 @@ public sealed class ChatMessageManager
|
||||
var displayContent = EmojiHelper.ReplaceEmoji(message.Content);
|
||||
var contentLines = displayContent.Split('\n');
|
||||
|
||||
var header = HeaderSegments(time, message.SenderUsername, senderColor);
|
||||
var header = HeaderSegments(time, senderName, senderColor);
|
||||
header.AddRange(ChatColors.SplitMentions(contentLines[0].TrimEnd('\r')));
|
||||
lines.Add(new ChatLine(header));
|
||||
|
||||
@@ -413,7 +416,7 @@ public sealed class ChatMessageManager
|
||||
1 => $"[{attachments[0].Kind.ToString().ToLowerInvariant()}]",
|
||||
_ => $"[{attachments.Count} attachments]",
|
||||
};
|
||||
var header = HeaderSegments(time, message.SenderUsername, senderColor);
|
||||
var header = HeaderSegments(time, senderName, senderColor);
|
||||
header.Add(new(summary, null));
|
||||
lines.Add(new ChatLine(header));
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ public class ChannelListSource : IListDataSource
|
||||
private readonly Dictionary<string, int> _unreadCounts = [];
|
||||
private readonly HashSet<string> _protectedChannels = [];
|
||||
private readonly HashSet<string> _mentionChannels = [];
|
||||
private readonly HashSet<string> _privateChannels = [];
|
||||
private string _activeChannel = string.Empty;
|
||||
|
||||
public event NotifyCollectionChangedEventHandler? CollectionChanged;
|
||||
@@ -32,7 +33,8 @@ public class ChannelListSource : IListDataSource
|
||||
private static readonly Attribute MentionAttr = new(new Color(230, 140, 60), Color.None);
|
||||
|
||||
public void Update(List<string> channels, Dictionary<string, int> unread, string activeChannel,
|
||||
IReadOnlySet<string>? protectedChannels = null, IReadOnlySet<string>? mentionChannels = null)
|
||||
IReadOnlySet<string>? protectedChannels = null, IReadOnlySet<string>? mentionChannels = null,
|
||||
IReadOnlySet<string>? privateChannels = null)
|
||||
{
|
||||
_channelNames.Clear();
|
||||
_channelNames.AddRange(channels);
|
||||
@@ -45,6 +47,9 @@ public class ChannelListSource : IListDataSource
|
||||
_mentionChannels.Clear();
|
||||
if (mentionChannels is not null)
|
||||
_mentionChannels.UnionWith(mentionChannels);
|
||||
_privateChannels.Clear();
|
||||
if (privateChannels is not null)
|
||||
_privateChannels.UnionWith(privateChannels);
|
||||
_activeChannel = activeChannel;
|
||||
MaxItemLength = channels.Count > 0 ? channels.Max(c => c.Length + 6) : 0;
|
||||
if (!SuspendCollectionChangedEvent)
|
||||
@@ -67,8 +72,12 @@ public class ChannelListSource : IListDataSource
|
||||
var normalAttr = listView.GetAttributeForRole(VisualRole.Normal);
|
||||
var focusAttr = listView.GetAttributeForRole(VisualRole.Focus);
|
||||
var prefix = isActive ? "> " : " ";
|
||||
// Trailing * marks password-protected (+k) channels
|
||||
var channelText = _protectedChannels.Contains(name) ? $"#{name}*" : $"#{name}";
|
||||
// Trailing * marks password-protected (+k) channels; ~ marks private (unlisted) ones
|
||||
var channelText = $"#{name}";
|
||||
if (_protectedChannels.Contains(name))
|
||||
channelText += "*";
|
||||
if (_privateChannels.Contains(name))
|
||||
channelText += "~";
|
||||
var badge = hasUnread ? $" ({unread})" : "";
|
||||
|
||||
// Resolve Transparent backgrounds to the view's actual background
|
||||
|
||||
@@ -1317,8 +1317,11 @@ public sealed partial class MainWindow : Runnable
|
||||
/// </summary>
|
||||
private void RefreshChannelList()
|
||||
{
|
||||
var privateChannels = _channelNames
|
||||
.Where(n => _channelPublic.TryGetValue(n, out var isPublic) && !isPublic)
|
||||
.ToHashSet();
|
||||
_channelListSource.Update(_channelNames, _messageManager.GetUnreadCounts(), _messageManager.CurrentChannel,
|
||||
_channelProtected, _messageManager.MentionChannels);
|
||||
_channelProtected, _messageManager.MentionChannels, privateChannels);
|
||||
_channelList.Source = _channelListSource;
|
||||
|
||||
// Restore selection to current channel
|
||||
@@ -1394,6 +1397,10 @@ public sealed partial class MainWindow : Runnable
|
||||
var text = roleTag.Length > 0
|
||||
? $"{statusIcon} {roleTag} {name}"
|
||||
: $"{statusIcon} {name}";
|
||||
// Users connected only via the IRC gateway get a tag — they lack client features
|
||||
// (encryption, attachments, profiles), which is useful context in conversation.
|
||||
if (u.IsIrc)
|
||||
text += " [irc]";
|
||||
// Fall back to the deterministic per-nick palette so user-list colors
|
||||
// match the same user's messages in chat.
|
||||
var nameColor = HexColorHelper.ParseHexColor(u.NicknameColor)
|
||||
|
||||
Reference in New Issue
Block a user