PlotDirector/PlotLine/Controllers/WritingController.cs

100 lines
3.4 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using PlotLine.Models;
using PlotLine.Services;
using PlotLine.ViewModels;
namespace PlotLine.Controllers;
[Authorize]
[Route("Writing")]
public sealed class WritingController(
IStoryContextService storyContext,
IRelationshipMapService relationshipMap,
IFloorPlanService floorPlans) : Controller
{
[HttpGet("Context")]
public async Task<IActionResult> Context(int? projectId, int? bookId, int? chapterId, int? sceneId)
{
var model = new WritingContextPageViewModel
{
ProjectID = projectId,
BookID = bookId,
ChapterID = chapterId,
SceneID = sceneId,
Display = sceneId.HasValue
? await BuildDisplayAsync(projectId, bookId, chapterId, sceneId, "Manual context")
: new WritingContextDisplayViewModel { FollowStatus = "Connected, waiting for scene" }
};
return View(model);
}
[HttpGet("Context/Scene")]
public async Task<IActionResult> ContextScene(int? projectId, int? bookId, int? chapterId, int? sceneId)
{
if (!sceneId.HasValue)
{
return PartialView("~/Views/Writing/_WritingContextContent.cshtml", new WritingContextDisplayViewModel
{
FollowStatus = "Connected, waiting for scene"
});
}
var model = await BuildDisplayAsync(projectId, bookId, chapterId, sceneId, "Following Word");
return model?.HasScene == true
? PartialView("~/Views/Writing/_WritingContextContent.cshtml", model)
: NotFound();
}
private async Task<WritingContextDisplayViewModel?> BuildDisplayAsync(int? projectId, int? bookId, int? chapterId, int? sceneId, string followStatus)
{
if (!sceneId.HasValue)
{
return new WritingContextDisplayViewModel { FollowStatus = followStatus };
}
var context = await storyContext.GetForSceneAsync(sceneId.Value, projectId, bookId);
if (context?.Scene is null)
{
return null;
}
var position = context.Position;
var relationships = await relationshipMap.GetAsync(position, null, true);
var floorPlan = context.Scene.FloorPlanID.HasValue
? await floorPlans.GetEditorAsync(context.Scene.FloorPlanID.Value)
: null;
return new WritingContextDisplayViewModel
{
Context = context,
RelationshipMap = relationships,
FloorPlan = floorPlan,
FollowStatus = followStatus,
SceneOptions = BuildSceneOptions(context.Scene)
};
}
private static IReadOnlyList<SelectListItem> BuildSceneOptions(SceneEditViewModel scene)
{
var options = scene.SceneOptions
.Select(x => new SelectListItem(x.Text, x.Value, x.Value == scene.SceneID.ToString()))
.ToList();
if (!options.Any(x => x.Value == scene.SceneID.ToString()))
{
options.Insert(0, new SelectListItem(
$"{scene.Book?.BookDisplayTitle ?? "Book"} / Ch {scene.Chapter?.ChapterNumber:g} / Scene {scene.SceneNumber:g}: {scene.SceneTitle}",
scene.SceneID.ToString(),
true));
}
return options
.OrderByDescending(x => x.Selected)
.ThenBy(x => x.Text)
.ToList();
}
}