| 1 | using AgentForge.Data.Entities; |
| 2 | using AgentForge.Services; |
| 3 | |
| 4 | namespace AgentForge.Plugin.View; |
| 5 | |
| 6 | public sealed record ForgeViewViewerContext( |
| 7 | string DisplayName, |
| 8 | string Initials, |
| 9 | string Href, |
| 10 | bool IsGuest); |
| 11 | |
| 12 | internal static class ForgeViewViewer |
| 13 | { |
| 14 | internal static ForgeViewViewerContext Resolve(HttpContext? http, ForgeAuthService? auth = null) |
| 15 | { |
| 16 | var token = auth is not null ? ForgeViewSession.TryGetToken(http, auth) : null; |
| 17 | if (token is not null) |
| 18 | { |
| 19 | var actor = ForgeActorResolver.NormalizeAgentIdentity(token.Name); |
| 20 | return FromActor(actor, isGuest: false, href: "/view/me"); |
| 21 | } |
| 22 | |
| 23 | return new ForgeViewViewerContext("Sign in", "?", "/view/login", IsGuest: true); |
| 24 | } |
| 25 | |
| 26 | private static ForgeViewViewerContext FromActor(string actor, bool isGuest, string href = "/view/login") |
| 27 | { |
| 28 | var display = actor.StartsWith(ForgeActorResolver.OarPrefix, StringComparison.OrdinalIgnoreCase) |
| 29 | ? actor[ForgeActorResolver.OarPrefix.Length..] |
| 30 | : actor.StartsWith("human:", StringComparison.OrdinalIgnoreCase) |
| 31 | ? actor[6..] |
| 32 | : actor; |
| 33 | return new(display, InitialsFrom(display), href, isGuest); |
| 34 | } |
| 35 | |
| 36 | private static string InitialsFrom(string name) |
| 37 | { |
| 38 | var parts = name.Split([' ', ':', '.', '-', '_'], StringSplitOptions.RemoveEmptyEntries); |
| 39 | if (parts.Length >= 2 && parts[0].Length > 0 && parts[1].Length > 0) |
| 40 | { |
| 41 | return string.Create(2, parts, static (span, value) => |
| 42 | { |
| 43 | span[0] = char.ToUpperInvariant(value[0][0]); |
| 44 | span[1] = char.ToUpperInvariant(value[1][0]); |
| 45 | }); |
| 46 | } |
| 47 | |
| 48 | if (name.Length >= 2) |
| 49 | return name[..2].ToUpperInvariant(); |
| 50 | |
| 51 | return name.Length == 1 |
| 52 | ? name.ToUpperInvariant() |
| 53 | : "?"; |
| 54 | } |
| 55 | } |
| 56 | |