Gallery page now lists common tags, added basic pagination controls

This commit is contained in:
neviyn 2021-05-10 15:42:46 +01:00
parent 03df15818e
commit 1a154f2db4
6 changed files with 115 additions and 52 deletions

View File

@ -87,6 +87,9 @@ class ImageController
}
}
} ?: return "gallery"
model.addAttribute("pageNumber", pageNumber)
val commonTags: List<Tag> = tagRepository.find20TagsOnImages(images.content.map { it.id })
model.addAttribute("commonTags", commonTags)
model.addAttribute("imagePage", images)
return "gallery"
}

View File

@ -32,4 +32,14 @@ interface ImageRepository : JpaRepository<Image, Long> {
interface TagRepository : CrudRepository<Tag, Long> {
fun findByTagIs(tag: String): Tag?
fun findAllByTagIn(tags: List<String>): List<Tag>
//SELECT * FROM booru.tag t WHERE t.id IN (SELECT DISTINCT tag_id FROM booru.tag_image ti WHERE ti.image_id IN ?1) ORDER BY t.amount DESC, t.tag LIMIT 20
//SELECT DISTINCT t.id, t.tag, t.amount FROM booru.tag t JOIN booru.tag_image ti ON ti.tag_id = t.id WHERE ti.image_id IN ?1 ORDER BY t.amount DESC, t.tag LIMIT 20
//WITH x AS (SELECT DISTINCT tag_id FROM booru.tag_image ti WHERE ti.image_id in ?1) SELECT t.* FROM booru.tag t RIGHT JOIN x ON t.id = x.tag_id ORDER BY t.AMOUNT DESC, t.tag LIMIT 20
@Suppress("SqlResolve")
@Query(
value = "SELECT * FROM booru.tag t WHERE t.id IN (SELECT DISTINCT tag_id FROM booru.tag_image ti WHERE ti.image_id IN ?1) ORDER BY t.amount DESC, t.tag LIMIT 20",
nativeQuery = true
)
fun find20TagsOnImages(imageIDs: List<Long>): List<Tag>
}

View File

@ -38,5 +38,21 @@
</div>
</nav>
</div>
<div th:fragment="searchBarRow">
<form action="/gallery" class="text-center row row-cols-auto align-items-center mt-2">
<div class="col-10">
<!--suppress HtmlFormInputWithoutLabel -->
<input class="form-control" id="imageSearch"
name="tags"
pattern="[a-zA-Z0-9\s_]*"
placeholder="Ex: blue_eyes smile"
th:value="${#request.getParameter('tags')}"
type="search">
</div>
<div class="col-2 d-grid">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</form>
</div>
</body>
</html>

View File

@ -7,32 +7,71 @@
<body>
<div th:replace="fragments :: navbar"></div>
<div class="container">
<form action="/gallery" class="text-center row row-cols-auto align-items-center mt-2">
<div th:replace="fragments :: searchBarRow"></div>
<div class="row mt-3" th:if="${imagePage != null}">
<div class="col-2">
<ul>
<li th:each="tag : ${commonTags}">
<a class="text-decoration-none"
th:href="${#mvc.url('IC#getGalleryPage').arg(0, 1).arg(1, tag.tag).build()}"
th:text="${tag.tag} + ' ' + ${tag.amount}">tag</a>
</li>
</ul>
</div>
<div class="col-10">
<!--suppress HtmlFormInputWithoutLabel -->
<input class="form-control" id="imageSearch"
name="tags"
pattern="[a-zA-Z0-9\s_]*"
placeholder="Ex: blue_eyes smile"
th:value="${#request.getParameter('tags')}"
type="search">
</div>
<div class="col-2 d-grid">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</form>
</div>
<div class="row" th:if="${imagePage != null}">
<div class="col-2" th:each="image : ${imagePage.content}">
<div class="container-fluid">
<div class="row">
<div class="col-xl-2 col-lg-4 col-md-6 col-sm-12" th:each="image : ${imagePage.content}">
<!--suppress ThymeleafVariablesResolveInspection -->
<a th:href="'/view/' + ${image.id}">
<!--suppress ThymeleafVariablesResolveInspection -->
<img alt="" class="img-thumbnail" th:src="'/i/thumbnail.' + ${image.filename}"/>
</a>
</div>
</div>
<div class="row" th:if="${imagePage == null}">
</div>
</div>
</div>
</div>
<div class="row" th:if="${imagePage == null}">
<div class="col text-center mt-3">
<p class="lead">No images found with all the specified tags.</p>
</div>
</div>
<div class="row justify-content-center mt-3" th:if="${imagePage != null}">
<div class="col d-flex justify-content-center">
<ul class="pagination">
<li class="page-item" th:classappend="${imagePage.isFirst() ? 'disabled' : ''}">
<a class="page-link"
th:href="@{/gallery/(page=${pageNumber - 1},tags=${param.tags})}">Previous</a>
</li>
<li class="page-item" th:if="${pageNumber > 2}">
<a class="page-link"
th:href="@{/gallery/(page=${pageNumber - 2},tags=${param.tags})}"
th:text="${pageNumber - 2}">P-2</a></li>
<li class="page-item" th:if="${pageNumber > 1}">
<a class="page-link"
th:href="@{/gallery/(page=${pageNumber - 1},tags=${param.tags})}"
th:text="${pageNumber - 1}">P-1</a></li>
<li class="page-item active">
<a class="page-link"
th:href="@{/gallery/(page=${pageNumber},tags=${param.tags})}"
th:text="${pageNumber}">P</a>
</li>
<li class="page-item" th:if="${pageNumber < imagePage.getTotalPages() - 1}">
<a class="page-link"
th:href="@{/gallery/(page=${pageNumber},tags=${param.tags})}"
th:text="${pageNumber}">P+1</a></li>
<li class="page-item" th:if="${pageNumber < imagePage.getTotalPages()}">
<a class="page-link"
th:href="@{/gallery/(page=${pageNumber},tags=${param.tags})}"
th:text="${pageNumber}">P+2</a></li>
<li class="page-item" th:classappend="${imagePage.isLast() ? 'disabled' : ''}">
<a class="page-link"
th:href="@{/gallery/(page=${pageNumber + 1},tags=${param.tags})}">Next</a>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>

View File

@ -14,18 +14,20 @@
<div class="row">
<div class="col">
<p class="text-center">
<a th:href="${#mvc.url('IC#getGalleryPage').build()}" class="text-decoration-none">Browse All</a>
<a class="text-decoration-none" th:href="${#mvc.url('IC#getGalleryPage').arg(0, 1).build()}">Browse All</a>
<span class="text-secondary"> |</span>
<a th:href="${#mvc.url('UC#showUploadPage').build()}" class="text-decoration-none">Upload New</a>
<a class="text-decoration-none" th:href="${#mvc.url('UC#showUploadPage').build()}">Upload New</a>
<span class="text-secondary"> |</span>
<a th:href="${#mvc.url('MC#memberDetails').build()}" class="text-decoration-none">My Account</a>
<a class="text-decoration-none" th:href="${#mvc.url('MC#memberDetails').build()}">My Account</a>
</p>
</div>
</div>
<div class="row justify-content-center">
<form class="col-xs-12 col-sm-9 col-md-6 text-center" action="/gallery">
<form action="/gallery" class="col-xs-12 col-sm-9 col-md-6 text-center">
<!--suppress HtmlFormInputWithoutLabel -->
<input class="form-control" id="imageSearch" pattern="[a-zA-Z0-9\s_]*" placeholder="Ex: blue_eyes smile" type="search" name="tags">
<input name="page" type="hidden" value="1">
<!--suppress HtmlFormInputWithoutLabel -->
<input class="form-control" id="imageSearch" name="tags" pattern="[a-zA-Z0-9\s_]*" placeholder="Ex: blue_eyes smile" type="search">
<button class="btn btn-primary mt-1 w-25" type="submit">Search</button>
</form>
</div>

View File

@ -7,34 +7,27 @@
<body>
<div th:replace="fragments :: navbar"></div>
<div class="container">
<form action="/gallery" class="text-center row row-cols-auto align-items-center mt-2">
<div class="col-10">
<!--suppress HtmlFormInputWithoutLabel -->
<input class="form-control" id="imageSearch"
name="tags"
pattern="[a-zA-Z0-9\s_]*"
placeholder="Ex: blue_eyes smile"
th:value="${#request.getParameter('tags')}"
type="search">
</div>
<div class="col-2 d-grid">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</form>
</div>
<div class="row mt-2">
<div th:replace="fragments :: searchBarRow"></div>
<div class="row mt-2">
<div class="col-2">
<ul>
<li th:each="tag : ${tags}"><a class="text-decoration-none" th:href="${#mvc.url('IC#getGalleryPage').arg(1, tag.tag).build()}" th:text="${tag.tag} + ' ' + ${tag.amount}">tag</a></li>
<li th:each="tag : ${tags}">
<a class="text-decoration-none"
th:href="${#mvc.url('IC#getGalleryPage').arg(1, tag.tag).build()}"
th:text="${tag.tag} + ' ' + ${tag.amount}">tag</a></li>
</ul>
<form th:if="${isUploader}" th:action="'/upload/d/' + ${image.id}" th:method="delete">
<form th:action="'/upload/d/' + ${image.id}"
th:if="${isUploader}"
th:method="delete">
<button type="submit">Delete</button>
</form>
</div>
<div class="col-8">
<img th:src="'/i/' + ${image.filename}" th:alt="${image.filename}" class="w-100">
<!--suppress HtmlRequiredAltAttribute -->
<img class="w-100" th:alt="${image.filename}" th:src="'/i/' + ${image.filename}">
</div>
<div class="col-2"></div>
</div>
</div>
</body>
</html>