mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 08:36:11 +02:00
feat: enhance profile view dialog to render ASCII avatars with color tags
This commit is contained in:
@@ -136,20 +136,8 @@ public class CommandHandler
|
|||||||
if (string.IsNullOrWhiteSpace(args))
|
if (string.IsNullOrWhiteSpace(args))
|
||||||
return new CommandResult(true, "Usage: /send <filepath or URL> [-s|-m|-l]", IsError: true);
|
return new CommandResult(true, "Usage: /send <filepath or URL> [-s|-m|-l]", IsError: true);
|
||||||
|
|
||||||
// Parse optional size flag (-s, -m, -l)
|
// Extract optional size flag from end or start, respecting quoted paths
|
||||||
string? size = null;
|
var (target, size) = ParsePathAndSizeFlag(args);
|
||||||
var parts = args.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
|
||||||
var targetParts = new List<string>();
|
|
||||||
|
|
||||||
foreach (var part in parts)
|
|
||||||
{
|
|
||||||
if (part is "-s" or "-m" or "-l")
|
|
||||||
size = part[1..]; // "s", "m", or "l"
|
|
||||||
else
|
|
||||||
targetParts.Add(part);
|
|
||||||
}
|
|
||||||
|
|
||||||
var target = string.Join(' ', targetParts).Trim('"');
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(target))
|
if (string.IsNullOrWhiteSpace(target))
|
||||||
return new CommandResult(true, "Usage: /send <filepath or URL> [-s|-m|-l]", IsError: true);
|
return new CommandResult(true, "Usage: /send <filepath or URL> [-s|-m|-l]", IsError: true);
|
||||||
@@ -186,7 +174,7 @@ public class CommandHandler
|
|||||||
if (string.IsNullOrWhiteSpace(args))
|
if (string.IsNullOrWhiteSpace(args))
|
||||||
return new CommandResult(true, "Usage: /avatar <URL or filepath>", IsError: true);
|
return new CommandResult(true, "Usage: /avatar <URL or filepath>", IsError: true);
|
||||||
|
|
||||||
var target = args.Trim().Trim('"');
|
var target = StripQuotes(args.Trim());
|
||||||
|
|
||||||
if (OnSetAvatar is not null)
|
if (OnSetAvatar is not null)
|
||||||
await OnSetAvatar(target);
|
await OnSetAvatar(target);
|
||||||
@@ -362,6 +350,51 @@ public class CommandHandler
|
|||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extract a file path (possibly quoted) and an optional size flag (-s, -m, -l).
|
||||||
|
/// The flag can appear before or after the path.
|
||||||
|
/// </summary>
|
||||||
|
private static (string Path, string? Size) ParsePathAndSizeFlag(string args)
|
||||||
|
{
|
||||||
|
var trimmed = args.Trim();
|
||||||
|
string? size = null;
|
||||||
|
|
||||||
|
// Check for flag at the end: "path" -m or path -m
|
||||||
|
if (trimmed.Length > 3)
|
||||||
|
{
|
||||||
|
var suffix = trimmed[^2..];
|
||||||
|
if (suffix is "-s" or "-m" or "-l" && trimmed[^3] == ' ')
|
||||||
|
{
|
||||||
|
size = suffix[1..];
|
||||||
|
trimmed = trimmed[..^3].TrimEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for flag at the start: -m "path" or -m path
|
||||||
|
if (size is null && trimmed.Length > 3)
|
||||||
|
{
|
||||||
|
var prefix = trimmed[..2];
|
||||||
|
if (prefix is "-s" or "-m" or "-l" && trimmed[2] == ' ')
|
||||||
|
{
|
||||||
|
size = prefix[1..];
|
||||||
|
trimmed = trimmed[3..].TrimStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (StripQuotes(trimmed), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove matching surrounding quotes (double or single) from a string.
|
||||||
|
/// </summary>
|
||||||
|
private static string StripQuotes(string s)
|
||||||
|
{
|
||||||
|
if (s.Length >= 2 &&
|
||||||
|
((s[0] == '"' && s[^1] == '"') || (s[0] == '\'' && s[^1] == '\'')))
|
||||||
|
return s[1..^1];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool IsValidHex(string s) =>
|
private static bool IsValidHex(string s) =>
|
||||||
s.All(c => char.IsAsciiHexDigit(c));
|
s.All(c => char.IsAsciiHexDigit(c));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,12 +140,20 @@ public sealed class ProfileViewDialog
|
|||||||
dialog.Add(bioView);
|
dialog.Add(bioView);
|
||||||
row += 3;
|
row += 3;
|
||||||
|
|
||||||
// ASCII Avatar
|
// ASCII Avatar — render with color tags
|
||||||
if (!string.IsNullOrWhiteSpace(profile.AvatarAscii))
|
if (!string.IsNullOrWhiteSpace(profile.AvatarAscii))
|
||||||
{
|
{
|
||||||
row++;
|
row++;
|
||||||
var avatarLines = profile.AvatarAscii.Split('\n').Length;
|
var rawLines = profile.AvatarAscii.Split('\n');
|
||||||
var avatarHeight = Math.Min(avatarLines + 2, 6);
|
var avatarSource = new ChatListSource();
|
||||||
|
foreach (var line in rawLines)
|
||||||
|
{
|
||||||
|
avatarSource.Add(ChatLine.HasColorTags(line)
|
||||||
|
? ChatLine.FromColoredText(line)
|
||||||
|
: new ChatLine(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
var avatarHeight = Math.Min(rawLines.Length + 2, 24);
|
||||||
var avatarFrame = new FrameView
|
var avatarFrame = new FrameView
|
||||||
{
|
{
|
||||||
Title = "Avatar",
|
Title = "Avatar",
|
||||||
@@ -154,9 +162,22 @@ public sealed class ProfileViewDialog
|
|||||||
Width = Dim.Fill(2),
|
Width = Dim.Fill(2),
|
||||||
Height = avatarHeight
|
Height = avatarHeight
|
||||||
};
|
};
|
||||||
avatarFrame.Add(new Label { Text = profile.AvatarAscii, X = 0, Y = 0 });
|
var avatarList = new ListView
|
||||||
|
{
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Width = Dim.Fill(),
|
||||||
|
Height = Dim.Fill(),
|
||||||
|
Source = avatarSource
|
||||||
|
};
|
||||||
|
avatarFrame.Add(avatarList);
|
||||||
dialog.Add(avatarFrame);
|
dialog.Add(avatarFrame);
|
||||||
// Grow dialog to fit avatar
|
|
||||||
|
// Grow dialog to fit avatar + widen for art
|
||||||
|
var artWidth = rawLines.Max(l => ChatLine.HasColorTags(l)
|
||||||
|
? ChatLine.FromColoredText(l).TextLength
|
||||||
|
: l.Length);
|
||||||
|
dialog.Width = Math.Max(50, artWidth + 6);
|
||||||
dialog.Height = row + avatarHeight + 4;
|
dialog.Height = row + avatarHeight + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user