Gallery page now lists common tags, added basic pagination controls
This commit is contained in:
parent
03df15818e
commit
1a154f2db4
@ -87,6 +87,9 @@ class ImageController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: return "gallery"
|
} ?: 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)
|
model.addAttribute("imagePage", images)
|
||||||
return "gallery"
|
return "gallery"
|
||||||
}
|
}
|
||||||
|
@ -32,4 +32,14 @@ interface ImageRepository : JpaRepository<Image, Long> {
|
|||||||
interface TagRepository : CrudRepository<Tag, Long> {
|
interface TagRepository : CrudRepository<Tag, Long> {
|
||||||
fun findByTagIs(tag: String): Tag?
|
fun findByTagIs(tag: String): Tag?
|
||||||
fun findAllByTagIn(tags: List<String>): List<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>
|
||||||
}
|
}
|
@ -38,5 +38,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</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>
|
</body>
|
||||||
</html>
|
</html>
|
@ -7,32 +7,71 @@
|
|||||||
<body>
|
<body>
|
||||||
<div th:replace="fragments :: navbar"></div>
|
<div th:replace="fragments :: navbar"></div>
|
||||||
<div class="container">
|
<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">
|
<div class="col-10">
|
||||||
<!--suppress HtmlFormInputWithoutLabel -->
|
<div class="container-fluid">
|
||||||
<input class="form-control" id="imageSearch"
|
<div class="row">
|
||||||
name="tags"
|
<div class="col-xl-2 col-lg-4 col-md-6 col-sm-12" th:each="image : ${imagePage.content}">
|
||||||
pattern="[a-zA-Z0-9\s_]*"
|
<!--suppress ThymeleafVariablesResolveInspection -->
|
||||||
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}">
|
|
||||||
<a th:href="'/view/' + ${image.id}">
|
<a th:href="'/view/' + ${image.id}">
|
||||||
|
<!--suppress ThymeleafVariablesResolveInspection -->
|
||||||
<img alt="" class="img-thumbnail" th:src="'/i/thumbnail.' + ${image.filename}"/>
|
<img alt="" class="img-thumbnail" th:src="'/i/thumbnail.' + ${image.filename}"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row" th:if="${imagePage == null}">
|
<div class="row" th:if="${imagePage == null}">
|
||||||
<div class="col text-center mt-3">
|
<div class="col text-center mt-3">
|
||||||
<p class="lead">No images found with all the specified tags.</p>
|
<p class="lead">No images found with all the specified tags.</p>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</body>
|
||||||
</html>
|
</html>
|
@ -14,18 +14,20 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<p class="text-center">
|
<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>
|
<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>
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row justify-content-center">
|
<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 -->
|
<!--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>
|
<button class="btn btn-primary mt-1 w-25" type="submit">Search</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,34 +7,27 @@
|
|||||||
<body>
|
<body>
|
||||||
<div th:replace="fragments :: navbar"></div>
|
<div th:replace="fragments :: navbar"></div>
|
||||||
<div class="container">
|
<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="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 class="row mt-2">
|
||||||
<div class="col-2">
|
<div class="col-2">
|
||||||
<ul>
|
<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>
|
</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>
|
<button type="submit">Delete</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<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>
|
||||||
<div class="col-2"></div>
|
<div class="col-2"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user