86 lines
8.6 KiB
Plaintext
86 lines
8.6 KiB
Plaintext
@model StoryPointSnapshot
|
|
@using System.Globalization
|
|
@if (Model is null)
|
|
{
|
|
<p class="text-muted">No scenes are available in this project.</p>
|
|
}
|
|
else
|
|
{
|
|
var scene = Model.Scene;
|
|
var exactTime = scene.TimeModeName is "Exact DateTime" or "Exact Date and Time";
|
|
<article class="story-point" data-scene-id="@scene.SceneID">
|
|
<header class="story-point-header">
|
|
<p class="eyebrow">@Model.Book.BookDisplayTitle · Chapter @Model.Chapter.ChapterNumber.ToString("g") · Scene @scene.SceneNumber.ToString("g")</p>
|
|
<h2>@scene.SceneTitle</h2>
|
|
<p class="story-point-date">
|
|
@if (scene.StartDateTime.HasValue)
|
|
{ <span>@scene.StartDateTime.Value.ToString("dddd, d MMMM yyyy", CultureInfo.GetCultureInfo("en-GB"))</span>
|
|
@if (exactTime) { <span> · @scene.StartDateTime.Value.ToString("h:mm tt", CultureInfo.GetCultureInfo("en-GB"))</span> }
|
|
}
|
|
else { <span>Story date unknown</span> }
|
|
@if (!string.IsNullOrWhiteSpace(scene.RelativeTimeText)) { <span> · @scene.RelativeTimeText</span> }
|
|
<small class="text-muted"> · @scene.TimeModeName</small>
|
|
</p>
|
|
<p>POV: <strong>@(scene.POVCharacterName ?? "Not recorded")</strong> · Location: <strong>@(Model.Location?.LocationPath ?? scene.PrimaryLocationName ?? "Not recorded")</strong></p>
|
|
<div class="d-flex flex-wrap gap-2">
|
|
<a class="btn btn-sm btn-outline-primary" asp-controller="Scenes" asp-action="Edit" asp-route-id="@scene.SceneID">Open Scene</a>
|
|
<a class="btn btn-sm btn-outline-secondary" asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.ProjectID" asp-route-bookId="@Model.Book.BookID" asp-route-selectedSceneId="@scene.SceneID">Timeline</a>
|
|
@if (scene.StartDateTime.HasValue) { <a class="btn btn-sm btn-outline-secondary" asp-controller="StoryCalendar" asp-action="Index" asp-route-projectId="@Model.ProjectID" asp-route-bookId="@Model.Book.BookID" asp-route-date="@scene.StartDateTime.Value.ToString("yyyy-MM-dd")" asp-route-month="@scene.StartDateTime.Value.ToString("yyyy-MM")">Calendar</a> }
|
|
</div>
|
|
</header>
|
|
<div class="story-point-grid">
|
|
<section class="story-point-section story-point-wide"><h3>Characters present <small>@Model.Characters.Count</small></h3>
|
|
@if (Model.Characters.Count == 0) { <p class="text-muted">No characters attached to this scene.</p> }
|
|
else { <div class="table-responsive"><table class="table table-sm align-middle"><thead><tr><th>Character</th><th>Age at this point</th><th>Known location</th><th>Previous appearance</th></tr></thead><tbody>
|
|
@foreach (var person in Model.Characters) { <tr><td><a asp-controller="Characters" asp-action="Edit" asp-route-id="@person.Appearance.CharacterID">@person.Appearance.CharacterName</a>
|
|
<small class="d-block text-muted">@person.Appearance.RoleInSceneTypeName @person.Appearance.PresenceTypeName</small></td>
|
|
<td>@(person.Age.DisplayText ?? "Unknown") @if (!person.Age.HasExactAge && person.Age.DisplayText is not null) { <small class="d-block text-muted">Approximate</small> }</td>
|
|
<td>@(person.State?.CurrentLocation ?? "Unknown")<small class="d-block text-muted">@(person.State?.State == "Inferred" ? "Last known" : "")</small></td>
|
|
<td>@if (person.PreviousAppearance is { } previous) { <a asp-controller="Scenes" asp-action="Edit" asp-route-id="@previous.SceneID">@previous.Label</a> } else { <span class="text-muted">First recorded appearance</span> }</td></tr> }
|
|
</tbody></table></div> }
|
|
</section>
|
|
<section class="story-point-section"><h3>Character knowledge</h3>
|
|
@if (Model.Characters.All(x => x.Knowledge.Count == 0)) { <p class="text-muted">No structured knowledge recorded by this point.</p> }
|
|
@foreach (var person in Model.Characters.Where(x => x.Knowledge.Count > 0)) {
|
|
<h4>@person.Appearance.CharacterName</h4><ul class="story-point-facts">
|
|
@foreach (var fact in person.Knowledge) { <li><strong>@fact.KnowledgeStateName:</strong> @(string.IsNullOrWhiteSpace(fact.Description) ? fact.AssetName ?? fact.ThreadTitle ?? "Recorded fact" : fact.Description)
|
|
<a class="story-point-source" asp-controller="Scenes" asp-action="Edit" asp-route-id="@fact.SceneID">@(Model.Sources.GetValueOrDefault(fact.SceneID)?.Label ?? "Source scene")</a></li> }
|
|
</ul>
|
|
}
|
|
</section>
|
|
<section class="story-point-section"><h3>Relationships at this point</h3>
|
|
@if (Model.Relationships.Count == 0) { <p class="text-muted">No historically established relationships recorded for these characters.</p> }
|
|
<ul class="story-point-facts">@foreach (var relationship in Model.Relationships) {
|
|
var source = relationship.History.LastOrDefault(x => x.SceneID.HasValue);
|
|
<li><strong>@relationship.CharacterAName ↔ @relationship.CharacterBName</strong><div>@relationship.CurrentStateName</div>
|
|
@if (source?.SceneID is int sourceId) { <a class="story-point-source" asp-controller="Scenes" asp-action="Edit" asp-route-id="@sourceId">@(Model.Sources.GetValueOrDefault(sourceId)?.Label ?? "Source scene")</a> }
|
|
else { <small class="text-muted">Established at story start</small> }</li>
|
|
}</ul></section>
|
|
<section class="story-point-section story-point-wide"><h3>Assets / important objects</h3>
|
|
@if (Model.Assets.Count == 0) { <p class="text-muted">No relevant assets recorded by this point.</p> }
|
|
else { <div class="table-responsive"><table class="table table-sm"><thead><tr><th>Asset</th><th>Holder</th><th>Location</th><th>Status</th><th>Last recorded event</th></tr></thead><tbody>
|
|
@foreach (var asset in Model.Assets) { <tr><td><a asp-controller="StoryAssets" asp-action="Edit" asp-route-id="@asset.StoryAssetID">@asset.AssetName</a></td><td>@asset.Holder</td><td>@asset.Location</td><td>@asset.Status</td><td>@asset.LatestEvent
|
|
@if (asset.LastConfirmedSceneID is int sourceId) { <a class="story-point-source" asp-controller="Scenes" asp-action="Edit" asp-route-id="@sourceId">@(Model.Sources.GetValueOrDefault(sourceId)?.Label ?? "Source scene")</a> }</td></tr> }
|
|
</tbody></table></div> }
|
|
</section>
|
|
<section class="story-point-section"><h3>Location state</h3>
|
|
@if (Model.Location is { } location) { <h4><a asp-controller="Locations" asp-action="Edit" asp-route-id="@location.LocationID">@location.LocationPath</a></h4>
|
|
<p><strong>People last known here:</strong> @(location.CharactersPresent.Count == 0 ? "None recorded" : string.Join(", ", location.CharactersPresent))</p>
|
|
<p><strong>Assets last known here:</strong> @(location.AssetsPresent.Count == 0 ? "None recorded" : string.Join(", ", location.AssetsPresent))</p>
|
|
@if (Model.PreviousLocationUse is { } previous) { <p>Previous scene here: <a asp-controller="Scenes" asp-action="Edit" asp-route-id="@previous.SceneID">@previous.Label</a></p> }
|
|
} else { <p class="text-muted">No primary location recorded.</p> }
|
|
</section>
|
|
<section class="story-point-section"><h3>Active threads / questions / clues</h3>
|
|
@if (Model.Threads.Count == 0) { <p class="text-muted">No active threads established by this point.</p> }
|
|
<ul class="story-point-facts">@foreach (var thread in Model.Threads) { <li><a asp-controller="PlotThreads" asp-action="Edit" asp-route-id="@thread.PlotThreadID">@thread.Title</a> <small class="text-muted">@thread.Type · @thread.State</small>
|
|
@if (thread.Source is { } source) { <a class="story-point-source" asp-controller="Scenes" asp-action="Edit" asp-route-id="@source.SceneID">@source.Label</a> }</li> }</ul>
|
|
</section>
|
|
<section class="story-point-section story-point-wide"><h3>Things worth checking at this point</h3>
|
|
@if (Model.Warnings.Count == 0) { <p class="text-muted">No relevant continuity warnings.</p> }
|
|
<ul class="story-point-facts">@foreach (var warning in Model.Warnings) { <li><strong>@warning.Severity:</strong> @warning.Message
|
|
@if (warning.SceneID is int sourceId) { <a class="story-point-source" asp-controller="Scenes" asp-action="Edit" asp-route-id="@sourceId">@(Model.Sources.GetValueOrDefault(sourceId)?.Label ?? "Source scene")</a> }</li> }</ul>
|
|
</section>
|
|
</div>
|
|
</article>
|
|
}
|