namespace PlotLine.Models; public static class WritingWorkspaceRoles { public const string None = "None"; public const string Launcher = "Launcher"; public const string Context = "Context"; public const string Intent = "Intent"; public static string Normalise(string? role) { var value = (role ?? string.Empty).Trim(); return value.Equals(Launcher, StringComparison.OrdinalIgnoreCase) ? Launcher : value.Equals(Context, StringComparison.OrdinalIgnoreCase) ? Context : value.Equals(Intent, StringComparison.OrdinalIgnoreCase) ? Intent : None; } } public sealed class WritingWorkspaceScope { public int? ProjectID { get; init; } public int? BookID { get; init; } } public sealed class WritingWindowRegistration { public string? BrowserWindowID { get; init; } public int? ProjectID { get; init; } public int? BookID { get; init; } public string? CurrentRoute { get; init; } public string? WritingRole { get; init; } public string? DisplayLabel { get; init; } } public sealed class WritingWindowHeartbeat { public string? BrowserWindowID { get; init; } public int? ProjectID { get; init; } public int? BookID { get; init; } public string? CurrentRoute { get; init; } public string? WritingRole { get; init; } public string? DisplayLabel { get; init; } } public sealed class WritingWindowPresence { public string BrowserWindowID { get; init; } = string.Empty; public int UserID { get; init; } public int? ProjectID { get; init; } public int? BookID { get; init; } public string CurrentRoute { get; init; } = string.Empty; public string WritingRole { get; init; } = WritingWorkspaceRoles.None; public string? DisplayLabel { get; init; } public bool IsActive { get; init; } public DateTime ConnectedUtc { get; init; } public DateTime LastSeenUtc { get; init; } } public sealed class WritingWorkspaceStatus { public int UserID { get; init; } public int? ProjectID { get; init; } public int? BookID { get; init; } public bool WordCompanionConnected { get; init; } public bool WordDocumentOpen { get; init; } public int? WordProjectID { get; init; } public int? WordBookID { get; init; } public StoryPosition? CurrentStoryPosition { get; init; } public IReadOnlyList Windows { get; init; } = []; public WritingWindowPresence? Launcher { get; init; } public WritingWindowPresence? Context { get; init; } public WritingWindowPresence? Intent { get; init; } public bool ContextOpen => Context?.IsActive == true; public bool IntentOpen => Intent?.IsActive == true; }