PlotDirector/PlotLine/ViewModels/OnboardingViewModels.cs

266 lines
10 KiB
C#

using System.ComponentModel.DataAnnotations;
using PlotLine.Models;
namespace PlotLine.ViewModels;
public sealed class OnboardingWizardViewModel
{
public string CurrentStep { get; set; } = OnboardingSteps.Welcome;
public int StepNumber { get; set; } = 1;
public int TotalSteps { get; set; } = 6;
public string? WritingJourney { get; set; }
public string? WritingSoftware { get; set; }
public int? ProjectID { get; set; }
public int? BookID { get; set; }
public string? SelectedProjectName { get; set; }
public string? SelectedBookTitle { get; set; }
public bool IsMicrosoftWordPath => string.Equals(WritingSoftware, WritingSoftwareValues.MicrosoftWord, StringComparison.Ordinal);
public CompanionPresenceViewModel CompanionPresence { get; set; } = new();
public ManuscriptScanStateViewModel ScanState { get; set; } = new();
public IReadOnlyList<OnboardingOptionViewModel> Options { get; set; } = [];
public IReadOnlyList<OnboardingProjectOptionViewModel> ProjectOptions { get; set; } = [];
public IReadOnlyList<OnboardingBookOptionViewModel> BookOptions { get; set; } = [];
public ProjectOnboardingForm ProjectForm { get; set; } = new();
public BookOnboardingForm BookForm { get; set; } = new();
}
public sealed class OnboardingOptionViewModel
{
public string Value { get; init; } = string.Empty;
public string Title { get; init; } = string.Empty;
public string Description { get; init; } = string.Empty;
public string? Badge { get; init; }
}
public sealed class WritingJourneyOnboardingForm
{
[Required(ErrorMessage = "Choose the closest writing stage before continuing.")]
public string? WritingJourney { get; set; }
}
public sealed class WritingSoftwareOnboardingForm
{
[Required(ErrorMessage = "Choose the software you write in before continuing.")]
public string? WritingSoftware { get; set; }
}
public static class OnboardingSelectionModes
{
public const string Create = "Create";
public const string Select = "Select";
}
public sealed class ProjectOnboardingForm
{
[Required]
public string Mode { get; set; } = OnboardingSelectionModes.Create;
public int? SelectedProjectID { get; set; }
[StringLength(200)]
public string? ProjectName { get; set; }
public string? Description { get; set; }
}
public sealed class BookOnboardingForm
{
[Required]
public string Mode { get; set; } = OnboardingSelectionModes.Create;
public int? SelectedBookID { get; set; }
[StringLength(200)]
public string? BookTitle { get; set; }
[StringLength(200)]
public string? Subtitle { get; set; }
[Range(1, int.MaxValue, ErrorMessage = "Target word count must be greater than zero.")]
public int? TargetWordCount { get; set; }
}
public sealed class OnboardingProjectOptionViewModel
{
public int ProjectID { get; init; }
public string ProjectName { get; init; } = string.Empty;
public string Description { get; init; } = string.Empty;
}
public sealed class OnboardingBookOptionViewModel
{
public int BookID { get; init; }
public string DisplayTitle { get; init; } = string.Empty;
public string Detail { get; init; } = string.Empty;
}
public sealed class OnboardingNudgeViewModel
{
public bool ShouldShow { get; init; }
public string ButtonText { get; init; } = "Start setup";
public string Title { get; init; } = "Set up PlotDirector around the way you write";
public string Description { get; init; } = "Answer a few quick questions so PlotDirector can guide your first project.";
public bool IsCompanionPresence { get; init; }
public bool CompanionConnected { get; init; }
}
public sealed class StoryIntelligenceOverviewViewModel
{
public int? ProjectID { get; init; }
public int? BookID { get; init; }
public string? SelectedProjectName { get; init; }
public string? SelectedBookTitle { get; init; }
public StoryIntelligenceJobProgress? ExistingJob { get; init; }
public bool CanStart => ProjectID.HasValue && BookID.HasValue && ExistingJob?.IsActive != true;
}
public sealed class StoryIntelligenceProgressViewModel
{
public StoryIntelligenceJobProgress Job { get; init; } = new();
public string? ProjectName { get; init; }
public string? BookTitle { get; init; }
}
public sealed class StoryIntelligenceCompletionViewModel
{
public StoryIntelligenceJobProgress Job { get; init; } = new();
public int ProjectID { get; init; }
public int BookID { get; init; }
public string? ProjectName { get; init; }
public string? BookTitle { get; init; }
}
public sealed class StoryIntelligenceDashboardViewModel
{
public bool ShouldShow { get; init; }
public string Title { get; init; } = "Story Intelligence available";
public string Description { get; init; } = "Prepare the optional analysis framework for your manuscript.";
public string ButtonText { get; init; } = "Set up Story Intelligence";
public StoryIntelligenceJobProgress? Job { get; init; }
}
public sealed class CompanionPresenceViewModel
{
public bool IsConnected { get; init; }
public bool DocumentOpen { get; init; }
public string Status { get; init; } = "Offline";
public string? CompanionVersion { get; init; }
public string? CurrentDocumentName { get; init; }
public DateTime? LastHeartbeatUtc { get; init; }
}
public sealed class ManuscriptScanStateViewModel
{
public string Status { get; init; } = ManuscriptScanStatuses.NotStarted;
public string ReviewStatus { get; init; } = ManuscriptScanReviewStatuses.ScanComplete;
public string Message { get; init; } = string.Empty;
public int? PercentComplete { get; init; }
public int ChapterCount { get; init; }
public int SceneCount { get; init; }
public int CharacterCandidateCount { get; init; }
public int TotalWordCount { get; init; }
public Guid? PreviewID { get; init; }
public bool IsRunning => string.Equals(Status, ManuscriptScanStatuses.Running, StringComparison.Ordinal);
public bool IsComplete => string.Equals(Status, ManuscriptScanStatuses.Complete, StringComparison.Ordinal);
public bool IsFailed => string.Equals(Status, ManuscriptScanStatuses.Failed, StringComparison.Ordinal);
}
public sealed class ManuscriptScanReviewViewModel
{
public Guid PreviewID { get; init; }
public string ReviewStatus { get; init; } = ManuscriptScanReviewStatuses.ScanComplete;
public string DocumentTitle { get; init; } = "Word manuscript";
public string SelectedProjectName { get; init; } = string.Empty;
public string SelectedBookTitle { get; init; } = string.Empty;
public int TotalWordCount { get; init; }
public int ChapterCount { get; init; }
public int SceneCount { get; init; }
public int CharacterCandidateCount { get; init; }
public int SelectedChapterCount { get; init; }
public int SelectedSceneCount { get; init; }
public int SelectedCharacterCount { get; init; }
public int SelectedWordCount { get; init; }
public IReadOnlyList<ManuscriptScanReviewChapterViewModel> Chapters { get; init; } = [];
public IReadOnlyList<ManuscriptScanReviewCharacterViewModel> CharacterCandidates { get; init; } = [];
public IReadOnlyList<ManuscriptScanExistingCharacterOptionViewModel> ExistingCharacterOptions { get; init; } = [];
}
public sealed class ManuscriptScanReviewChapterViewModel
{
public string TemporaryChapterKey { get; init; } = string.Empty;
public int ChapterNumber { get; init; }
public string Title { get; init; } = string.Empty;
public string ReviewTitle { get; init; } = string.Empty;
public bool Include { get; init; }
public int WordCount { get; init; }
public IReadOnlyList<ManuscriptScanReviewSceneViewModel> Scenes { get; init; } = [];
}
public sealed class ManuscriptScanReviewSceneViewModel
{
public string TemporarySceneKey { get; init; } = string.Empty;
public string TemporaryChapterKey { get; init; } = string.Empty;
public int SceneNumberWithinChapter { get; init; }
public string? Title { get; init; }
public string? ReviewTitle { get; init; }
public bool Include { get; init; }
public int WordCount { get; init; }
public string? OpeningTextPreview { get; init; }
}
public sealed class ManuscriptScanReviewCharacterViewModel
{
public string TemporaryCharacterKey { get; init; } = string.Empty;
public string Name { get; init; } = string.Empty;
public string ReviewName { get; init; } = string.Empty;
public bool Include { get; init; }
public int MentionCount { get; init; }
public int QualityScore { get; init; }
public string Category { get; init; } = "PossibleCharacter";
public string? Reason { get; init; }
public int? ExistingCharacterID { get; init; }
public string? ExistingCharacterName { get; init; }
public bool IsExistingCharacterMatch => ExistingCharacterID.HasValue;
}
public sealed class ManuscriptScanExistingCharacterOptionViewModel
{
public int CharacterID { get; init; }
public string CharacterName { get; init; } = string.Empty;
}
public sealed class ManuscriptScanReviewForm
{
public Guid PreviewID { get; set; }
public List<ManuscriptScanChapterReviewFormItem> Chapters { get; set; } = [];
public List<ManuscriptScanSceneReviewFormItem> Scenes { get; set; } = [];
public List<ManuscriptScanCharacterReviewFormItem> Characters { get; set; } = [];
}
public sealed class ManuscriptScanChapterReviewFormItem
{
public string TemporaryChapterKey { get; set; } = string.Empty;
public bool Include { get; set; }
public string Title { get; set; } = string.Empty;
public int ChapterNumber { get; set; }
}
public sealed class ManuscriptScanSceneReviewFormItem
{
public string TemporarySceneKey { get; set; } = string.Empty;
public string TemporaryChapterKey { get; set; } = string.Empty;
public bool Include { get; set; }
public string? Title { get; set; }
public int SceneNumberWithinChapter { get; set; }
public bool AllowZeroWords { get; set; }
}
public sealed class ManuscriptScanCharacterReviewFormItem
{
public string TemporaryCharacterKey { get; set; } = string.Empty;
public bool Include { get; set; }
public string Name { get; set; } = string.Empty;
public string Category { get; set; } = "PossibleCharacter";
public int? ExistingCharacterID { get; set; }
}