PlotDirector/PlotLine/Views/Shared/SceneInspectorV2/_SceneAttachmentsEditor.cshtml

211 lines
12 KiB
Plaintext

@model SceneEditViewModel
@{
static string? FileHref(string? filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
{
return null;
}
return filePath.StartsWith("http", StringComparison.OrdinalIgnoreCase)
? filePath
: filePath.StartsWith("/")
? filePath
: !System.IO.Path.IsPathRooted(filePath)
? "/" + filePath.TrimStart('/', '\\')
: null;
}
static bool IsImageAttachment(string? href, string? filePath)
{
if (string.IsNullOrWhiteSpace(href) || string.IsNullOrWhiteSpace(filePath))
{
return false;
}
var extension = System.IO.Path.GetExtension(filePath);
return new[] { ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp" }
.Contains(extension, StringComparer.OrdinalIgnoreCase);
}
}
<div class="scene-inspector-editor-form">
<div class="scene-inspector-editor-fields">
<section class="scene-writer-editor-section">
<div class="scene-writer-editor-heading">
<span>Current attachments</span>
<strong>@Model.Attachments.Count</strong>
</div>
@if (Model.StorageUsage is not null)
{
<p class="muted">Storage used: @Model.StorageUsage.DisplayLabel</p>
}
@if (!Model.Attachments.Any())
{
<p class="muted">No scene references yet.</p>
}
else
{
<div class="scene-writer-editor-list">
@foreach (var attachment in Model.Attachments)
{
var href = FileHref(attachment.FilePath);
var hasFile = !string.IsNullOrWhiteSpace(attachment.FilePath);
var hasImage = IsImageAttachment(href, attachment.FilePath);
<article class="scene-writer-editor-card scene-attachment-editor-card">
<div class="scene-writer-editor-card-header">
<div>
<h4>@attachment.Title</h4>
<p>@attachment.TypeName / @(hasFile ? "Uploaded file" : "External link")</p>
</div>
</div>
<div class="scene-attachment-preview-row">
@if (hasImage)
{
<a class="scene-attachment-thumb" href="@href" target="_blank" rel="noopener" aria-label="Open @attachment.Title image">
<img src="@href" alt="@attachment.Title preview" loading="lazy" />
</a>
}
else
{
<div class="scene-attachment-thumb scene-attachment-thumb-fallback" aria-hidden="true">
<span>@(hasFile ? "File" : "Link")</span>
</div>
}
<div class="scene-attachment-preview-copy">
@if (!string.IsNullOrWhiteSpace(attachment.Notes))
{
<p>@attachment.Notes</p>
}
@if (hasFile)
{
<p class="muted">@System.IO.Path.GetFileName(attachment.FilePath)</p>
}
<div class="button-row compact-buttons">
@if (!string.IsNullOrWhiteSpace(href))
{
<a class="btn btn-outline-secondary btn-sm" href="@href" target="_blank" rel="noopener">Open</a>
<a class="btn btn-outline-secondary btn-sm" href="@href" download>Download</a>
}
@if (!string.IsNullOrWhiteSpace(attachment.ExternalUrl))
{
<a class="btn btn-outline-secondary btn-sm" href="@attachment.ExternalUrl" target="_blank" rel="noopener">Open link</a>
}
</div>
</div>
</div>
<form asp-controller="Scenes" asp-action="SaveAttachment" method="post" enctype="multipart/form-data" class="scene-attachment-editor-form" data-scene-editor-form>
@Html.AntiForgeryToken()
<input type="hidden" name="SceneAttachmentID" value="@attachment.SceneAttachmentID" />
<input type="hidden" name="SceneID" value="@Model.SceneID" />
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
<input type="hidden" name="FilePath" value="@attachment.FilePath" />
<div class="scene-inspector-editor-error" data-scene-editor-error hidden></div>
<div class="form-group">
<label for="Attachment_@(attachment.SceneAttachmentID)__SceneAttachmentTypeID">Attachment type</label>
<select class="form-control form-control-sm" id="Attachment_@(attachment.SceneAttachmentID)__SceneAttachmentTypeID" name="SceneAttachmentTypeID">
@foreach (var option in Model.SceneAttachmentTypeOptions)
{
<option value="@option.Value" selected="@(option.Value == attachment.SceneAttachmentTypeID.ToString())">@option.Text</option>
}
</select>
</div>
<div class="form-group">
<label for="Attachment_@(attachment.SceneAttachmentID)__Title">Title</label>
<input class="form-control form-control-sm" id="Attachment_@(attachment.SceneAttachmentID)__Title" name="Title" value="@attachment.Title" />
</div>
<div class="scene-inspector-editor-grid">
<div class="form-group">
<label for="Attachment_@(attachment.SceneAttachmentID)__UploadedFile">Replace file</label>
<input class="form-control form-control-sm" id="Attachment_@(attachment.SceneAttachmentID)__UploadedFile" name="UploadedFile" type="file" />
</div>
<div class="form-group">
<label for="Attachment_@(attachment.SceneAttachmentID)__ExternalUrl">External URL</label>
<input class="form-control form-control-sm" id="Attachment_@(attachment.SceneAttachmentID)__ExternalUrl" name="ExternalUrl" value="@attachment.ExternalUrl" />
</div>
</div>
<div class="form-group">
<label for="Attachment_@(attachment.SceneAttachmentID)__Notes">Notes</label>
<textarea class="form-control form-control-sm" id="Attachment_@(attachment.SceneAttachmentID)__Notes" name="Notes" rows="2">@attachment.Notes</textarea>
</div>
<div class="scene-attachment-action-row">
<button class="btn btn-sm btn-primary" type="submit" data-scene-editor-save>Save attachment</button>
</div>
</form>
<form asp-controller="Scenes" asp-action="DeleteAttachment" method="post" class="scene-attachment-delete-form" data-scene-editor-form>
@Html.AntiForgeryToken()
<input type="hidden" name="id" value="@attachment.SceneAttachmentID" />
<input type="hidden" name="sceneId" value="@Model.SceneID" />
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
<input type="hidden" name="filePath" value="@attachment.FilePath" />
<div class="scene-inspector-editor-error" data-scene-editor-error hidden></div>
<button class="btn btn-sm btn-outline-danger" type="submit" data-scene-editor-save>Remove attachment</button>
</form>
</article>
}
</div>
}
</section>
<section class="scene-writer-editor-section">
<div class="scene-writer-editor-heading">
<span>Add attachment</span>
</div>
<form asp-controller="Scenes" asp-action="SaveAttachment" method="post" enctype="multipart/form-data" class="scene-writer-editor-card scene-attachment-editor-form" data-scene-editor-form>
@Html.AntiForgeryToken()
<input type="hidden" name="SceneID" value="@Model.SceneID" />
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
<div class="scene-inspector-editor-error" data-scene-editor-error hidden></div>
<div class="form-group">
<label for="NewAttachment_SceneAttachmentTypeID">Attachment type</label>
<select class="form-control form-control-sm" id="NewAttachment_SceneAttachmentTypeID" name="SceneAttachmentTypeID" asp-items="Model.SceneAttachmentTypeOptions"></select>
</div>
<div class="form-group">
<label for="NewAttachment_Title">Title</label>
<input class="form-control form-control-sm" id="NewAttachment_Title" name="Title" placeholder="Reference title" />
</div>
<div class="scene-inspector-editor-grid">
<div class="form-group">
<label for="NewAttachment_UploadedFile">Choose file</label>
<input class="form-control form-control-sm" id="NewAttachment_UploadedFile" name="UploadedFile" type="file" />
</div>
<div class="form-group">
<label for="NewAttachment_ExternalUrl">Or external URL</label>
<input class="form-control form-control-sm" id="NewAttachment_ExternalUrl" name="ExternalUrl" placeholder="https://..." />
</div>
</div>
<div class="form-group">
<label for="NewAttachment_Notes">Notes</label>
<textarea class="form-control form-control-sm" id="NewAttachment_Notes" name="Notes" rows="2" placeholder="Why this reference matters"></textarea>
</div>
<div class="scene-attachment-action-row">
<button class="btn btn-sm btn-primary" type="submit" data-scene-editor-save>Add attachment</button>
</div>
</form>
</section>
</div>
<div class="scene-inspector-editor-footer">
<button type="button" class="btn btn-sm btn-outline-secondary" data-scene-editor-close>Close</button>
</div>
</div>