PlotDirector/PlotLine/Services/AvatarHelper.cs
Nick Beckley 34a8d94cb4 Implemented the Visual Identity infrastructure pass.
Changed
Added image fields for Characters and Story Assets in models, view models, repositories, services, and save flows.
Added reusable avatar/initials rendering via [AvatarHelper.cs](C:/Source/PlotLine/PlotLine/Services/AvatarHelper.cs) and [_Avatar.cshtml](C:/Source/PlotLine/PlotLine/Views/Shared/_Avatar.cshtml).
Added upload/remove processing through existing upload storage in [VisualIdentityImageService.cs](C:/Source/PlotLine/PlotLine/Services/VisualIdentityImageService.cs).
Updated Character and Story Asset list/detail/edit views with thumbnails, initials fallback, upload, replace, and remove controls.
Added styling in [site.css](C:/Source/PlotLine/PlotLine/wwwroot/css/site.css) and refreshed site.min.css.
Database
Added new migration [079_VisualIdentityCharacterAssetImages.sql](C:/Source/PlotLine/PlotLine/Sql/079_VisualIdentityCharacterAssetImages.sql).
Adds nullable ImagePath and ThumbnailPath to Characters and StoryAssets.
Applied locally and confirmed the columns exist.
Stored Procedures
Updated active procedure definitions only:
Character_ListByProject
Character_Get
Character_Save
Character_UpdateImage
StoryAsset_ListByProject
StoryAsset_Get
StoryAsset_Save
StoryAsset_UpdateImage
2026-06-22 10:10:39 +01:00

57 lines
1.2 KiB
C#

using System.Text;
namespace PlotLine.Services;
public static class AvatarHelper
{
public static string Initials(string? displayName)
{
var words = SignificantWords(displayName).ToList();
if (words.Count >= 2)
{
return string.Concat(words.Take(2).Select(word => char.ToUpperInvariant(word[0])));
}
if (words.Count == 1)
{
return char.ToUpperInvariant(words[0][0]).ToString();
}
return "?";
}
private static IEnumerable<string> SignificantWords(string? displayName)
{
if (string.IsNullOrWhiteSpace(displayName))
{
yield break;
}
var builder = new StringBuilder();
foreach (var ch in displayName)
{
if (char.IsLetterOrDigit(ch))
{
builder.Append(ch);
continue;
}
if (ch is '\'' or '\u2019')
{
continue;
}
if (builder.Length > 0)
{
yield return builder.ToString();
builder.Clear();
}
}
if (builder.Length > 0)
{
yield return builder.ToString();
}
}
}