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>
|
/// <summary>
|
||||||
/// Shared color attributes for chat rendering (timestamps, system messages).
|
/// Shared color attributes for chat rendering (timestamps, system messages).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ChatColors
|
public static partial class ChatColors
|
||||||
{
|
{
|
||||||
public static readonly Attribute TimestampAttr = new(Color.DarkGray, Color.Black);
|
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 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 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>
|
/// <summary>
|
||||||
|
|||||||
@@ -872,12 +872,13 @@ public sealed class MainWindow : Runnable
|
|||||||
default:
|
default:
|
||||||
var contentLines = message.Content.Split('\n');
|
var contentLines = message.Content.Split('\n');
|
||||||
var firstLine = contentLines[0].TrimEnd('\r');
|
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
|
// Continuation lines indented to align with first line's content
|
||||||
var indent = new string(' ', $"[{time}] {senderName} ".Length);
|
var indent = new string(' ', $"[{time}] {senderName} ".Length);
|
||||||
for (int i = 1; i < contentLines.Length; i++)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@@ -913,4 +914,18 @@ public sealed class MainWindow : Runnable
|
|||||||
};
|
};
|
||||||
return new ChatLine(segments);
|
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