Newer
Older
Sakayaki / Pages / Index.cshtml
@fabre fabre 9 hours ago 5 KB 超级缩略图
@page
@model IndexModel
@{
    ViewData["Title"] = "Gallery";
}

<div class="d-flex flex-wrap gap-2 align-items-end mt-3">
    <form method="post" asp-page-handler="Update" class="mb-0">
        <button type="submit" class="btn btn-success">Update</button>
    </form>

    <form method="get" class="row g-2 align-items-end flex-grow-1 mb-0">
        <div class="col-12 col-sm-6 col-md-4">
            <input id="keywordInput"
                   name="keyword"
                   class="form-control"
                   value="@Model.Keyword"
                   placeholder="Search by keyword"
                   aria-label="Keyword" />
        </div>
        <div class="col-auto">
            <button type="submit" class="btn btn-primary">Search</button>
            <a class="btn btn-outline-secondary" href="@Url.Page("Index")">Clear</a>
        </div>
    </form>
</div>

@if (!string.IsNullOrWhiteSpace(Model.StatusMessage))
{
    <div class="alert alert-info mt-3">@Model.StatusMessage</div>
}

<div class="row row-cols-1 row-cols-sm-2 row-cols-lg-4 g-3 mt-3">
    @if (Model.Folders.Count == 0)
    {
        <div class="col">
            <div class="alert alert-secondary mb-0">No records yet.</div>
        </div>
    }
    else
    {
        foreach (var card in Model.Folders)
        {
            var item = card.Folder;
            <div class="col">
                <a class="card h-100 text-start shadow-sm text-decoration-none"
                   data-folder-link="true"
                   data-folder-id="@item.Id"
                   href="@Url.Page("Folder", null, new { id = item.Id, keyword = Model.Keyword, p = Model.PageNumber > 1 ? Model.PageNumber : (int?)null })">
                    @if (!string.IsNullOrWhiteSpace(card.CoverUrl))
                    {
                        <img src="@card.CoverUrl" alt="@card.CoverFileName" class="card-img-top" />
                    }
                    <div class="card-body d-flex flex-column">
                        <h5 class="card-title mb-1">@item.Title</h5>
                        <div class="text-muted small">@item.Date.ToString("yyyy-MM-dd") · @item.Author</div>
                        @if (!string.IsNullOrWhiteSpace(item.Keywords))
                        {
                            <div class="mt-2 text-body-secondary small">@item.Keywords</div>
                        }
                        <div class="mt-auto pt-2">
                            <span class="badge text-bg-light">@((item.FileCount ?? 0).ToString()) files</span>
                        </div>
                    </div>
                </a>
            </div>
        }
    }
</div>

@if (Model.TotalPages > 1)
{
    <nav class="mt-3" aria-label="Pagination">
        <ul class="pagination mb-0">
            <li class="page-item @(Model.PageNumber <= 1 ? "disabled" : "")">
                <a class="page-link"
                   href="@Url.Page("Index", null, new { p = Model.PageNumber - 1, keyword = Model.Keyword })"
                   aria-label="Previous">
                    <span aria-hidden="true">«</span>
                </a>
            </li>
            @for (var i = 1; i <= Model.TotalPages; i++)
            {
                <li class="page-item @(i == Model.PageNumber ? "active" : "")">
                    <a class="page-link" href="@Url.Page("Index", null, new { p = i, keyword = Model.Keyword })">@i</a>
                </li>
            }
            <li class="page-item @(Model.PageNumber >= Model.TotalPages ? "disabled" : "")">
                <a class="page-link"
                   href="@Url.Page("Index", null, new { p = Model.PageNumber + 1, keyword = Model.Keyword })"
                   aria-label="Next">
                    <span aria-hidden="true">»</span>
                </a>
            </li>
        </ul>
    </nav>
}

<div id="thumbWait" class="position-fixed top-0 start-0 w-100 h-100 d-none" style="z-index: 1080;">
    <div class="d-flex align-items-center justify-content-center w-100 h-100 bg-dark bg-opacity-50">
        <div class="text-center text-white">
            <div class="spinner-border text-light" role="status" aria-hidden="true"></div>
            <div class="mt-2">Please wait, generating thumbnails...</div>
        </div>
    </div>
</div>

@section Scripts {
    <script>
        const waitOverlay = document.getElementById("thumbWait");
        document.querySelectorAll("[data-folder-link='true']").forEach(link => {
            link.addEventListener("click", async event => {
                if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
                    return;
                }

                const folderId = link.dataset.folderId;
                if (!folderId) {
                    return;
                }

                event.preventDefault();
                waitOverlay?.classList.remove("d-none");

                try {
                    await fetch(`?handler=EnsureThumbnails&id=${encodeURIComponent(folderId)}`);
                } catch (error) {
                    console.warn("Thumbnail generation failed", error);
                }

                window.location.href = link.href;
            });
        });
    </script>
}