mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 08:36:11 +02:00
feat: add @mention highlighting in chat lines with new SplitMentions method
This commit is contained in:
@@ -453,11 +453,40 @@ public class UserListSource : IListDataSource
|
||||
/// <summary>
|
||||
/// Shared color attributes for chat rendering (timestamps, system messages).
|
||||
/// </summary>
|
||||
public static class ChatColors
|
||||
public static partial class ChatColors
|
||||
{
|
||||
public static readonly Attribute TimestampAttr = new(Color.DarkGray, Color.Black);
|
||||
public static readonly Attribute SystemAttr = new(new Color(0, 180, 180), Color.Black);
|
||||
public static readonly Attribute MentionHighlightAttr = new(Color.White, new Color(80, 40, 0));
|
||||
public static readonly Attribute MentionTextAttr = new(new Color(255, 180, 50), Color.Black);
|
||||
|
||||
/// <summary>
|
||||
/// Split text around @mentions, giving each @word the MentionTextAttr accent color.
|
||||
/// Non-mention text uses the provided default color.
|
||||
/// </summary>
|
||||
public static List<ChatSegment> SplitMentions(string text, Attribute? defaultColor = null)
|
||||
{
|
||||
var segments = new List<ChatSegment>();
|
||||
int lastIndex = 0;
|
||||
|
||||
foreach (Match match in MentionRegex().Matches(text))
|
||||
{
|
||||
if (match.Index > lastIndex)
|
||||
segments.Add(new ChatSegment(text[lastIndex..match.Index], defaultColor));
|
||||
|
||||
segments.Add(new ChatSegment(match.Value, MentionTextAttr));
|
||||
lastIndex = match.Index + match.Length;
|
||||
}
|
||||
|
||||
if (lastIndex < text.Length)
|
||||
segments.Add(new ChatSegment(text[lastIndex..], defaultColor));
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
// Matches @username (letters, digits, underscores, hyphens — same as channel name chars)
|
||||
[GeneratedRegex(@"@[\w-]+")]
|
||||
private static partial Regex MentionRegex();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -872,12 +872,13 @@ public sealed class MainWindow : Runnable
|
||||
default:
|
||||
var contentLines = message.Content.Split('\n');
|
||||
var firstLine = contentLines[0].TrimEnd('\r');
|
||||
lines.Add(BuildChatLine(time, senderName, senderColor, $" {firstLine}"));
|
||||
lines.Add(BuildChatLineWithMentions(time, senderName, senderColor, $" {firstLine}"));
|
||||
// Continuation lines indented to align with first line's content
|
||||
var indent = new string(' ', $"[{time}] {senderName} ".Length);
|
||||
for (int i = 1; i < contentLines.Length; i++)
|
||||
{
|
||||
lines.Add(new ChatLine($"{indent}{contentLines[i].TrimEnd('\r')}"));
|
||||
var contText = $"{indent}{contentLines[i].TrimEnd('\r')}";
|
||||
lines.Add(new ChatLine(ChatColors.SplitMentions(contText)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -913,4 +914,18 @@ public sealed class MainWindow : Runnable
|
||||
};
|
||||
return new ChatLine(segments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a chat line with @mention highlighting in the suffix text.
|
||||
/// </summary>
|
||||
private static ChatLine BuildChatLineWithMentions(string time, string senderName, Attribute? senderColor, string suffix)
|
||||
{
|
||||
var segments = new List<ChatSegment>
|
||||
{
|
||||
new($"[{time}] ", ChatColors.TimestampAttr),
|
||||
new(senderName, senderColor),
|
||||
};
|
||||
segments.AddRange(ChatColors.SplitMentions(suffix));
|
||||
return new ChatLine(segments);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user