100 lines
3.4 KiB
C#
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();
|
|
}
|
|
}
|