Skip to content

Commit df354ed

Browse files
committed
Ratings scroll
1 parent edca20a commit df354ed

5 files changed

Lines changed: 41 additions & 28 deletions

File tree

src/main/kotlin/com/embabel/movie/domain/MovieService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ class MovieService(
3737
fun findMovieBuffByEmail(email: String): MovieBuff? {
3838
return movieBuffRepository.findById(email).orElse(null)
3939
}
40-
40+
4141
@Transactional(readOnly = true)
4242
fun getUserRatings(movieBuff: MovieBuff, offset: Int, limit: Int): List<MovieRating> {
4343
return movieBuff.movieRatings
44-
.sortedByDescending { it.timestamp }
44+
.sortedBy { it.movie.title }
4545
.drop(offset)
4646
.take(limit)
4747
}

src/main/kotlin/com/embabel/movie/web/MovieHtmxController.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,13 @@ class MovieHtmxController(
128128
logger.info("Loading more ratings for user {} at offset {}", movieBuff.email, offset)
129129
val ratings = movieService.getUserRatings(movieBuff, offset, limit)
130130

131+
val newOffset = offset + ratings.size
132+
val totalRatings = movieBuff.movieRatings.size
133+
131134
model.addAttribute("ratings", ratings)
132-
model.addAttribute("offset", offset + ratings.size)
135+
model.addAttribute("offset", newOffset)
133136
model.addAttribute("limit", limit)
134-
model.addAttribute("hasMore", offset + ratings.size < movieBuff.movieRatings.size)
137+
model.addAttribute("hasMore", newOffset < totalRatings)
135138

136139
return "fragments/rating-items"
137140
}
@@ -147,7 +150,7 @@ class MovieHtmxController(
147150
/**
148151
* Process a new rating submission
149152
*/
150-
@PostMapping("/ratings/add")
153+
@PostMapping("/ratings/add", produces = [MediaType.TEXT_HTML_VALUE])
151154
fun addRating(
152155
@RequestParam title: String,
153156
@RequestParam rating: Int,
@@ -169,9 +172,13 @@ class MovieHtmxController(
169172
val updatedMovieBuff = movieService.findMovieBuffByEmail(movieBuff.email)
170173
?: error("Could not find movie buff after adding rating")
171174

172-
val latestRating = updatedMovieBuff.movieRatings.minByOrNull { it.movie.title }
175+
val latestRating = updatedMovieBuff.movieRatings.maxByOrNull { it.timestamp }
173176

174177
model.addAttribute("ratings", listOfNotNull(latestRating))
178+
model.addAttribute("offset", 1) // Since we're only showing one rating
179+
model.addAttribute("limit", 10)
180+
model.addAttribute("hasMore", false) // Don't show load more for the single new rating
181+
175182
return "fragments/rating-items"
176183
}
177184

src/main/resources/templates/common/layout.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<title th:replace="${title}">Embabel</title>
77
<link href="/css/embabel-common-dark.css" rel="stylesheet">
88
<link href="/css/project.css" rel="stylesheet">
9-
<script src="https://unpkg.com/htmx.org@2.0.5" th:if="${_htmx}"></script>
9+
<script src="https://unpkg.com/htmx.org@2.0.5"></script>
1010
<script src="https://unpkg.com/htmx.org@2.2.2/dist/ext/sse.js" th:if="${_sse}"></script>
1111
<th:block th:replace="~{${extraHeadContent != null ? extraHeadContent : 'common/fragments/empty'}}"
1212
th:if="${extraHeadContent != null}"></th:block>
Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
<!DOCTYPE html>
2-
<html xmlns:th="http://www.thymeleaf.org">
3-
<body>
41
<div th:fragment="rating-items(ratings, limit)">
52
<div class="ratings-list">
63
<div th:each="rating : ${ratings}" class="rating-item">
@@ -20,15 +17,13 @@ <h3 th:text="${rating.movie.title}"></h3>
2017
</div>
2118
</div>
2219
</div>
23-
24-
<!-- Infinite scroll trigger -->
20+
2521
<div th:if="${hasMore}"
26-
hx-get="@{/movie/ratings/more(offset=${offset}, limit=10)}"
27-
hx-trigger="revealed"
28-
hx-swap="outerHTML"
22+
th:hx-get="@{/movie/ratings/more(offset=${offset},limit=${limit})}"
23+
hx-trigger="intersect once"
24+
hx-target="#ratings-container"
25+
hx-swap="beforeend"
2926
hx-indicator=".loading-indicator">
30-
<div class="loading-indicator">Loading more...</div>
27+
<!-- <div class="loading-indicator">Loading more...</div>-->
3128
</div>
32-
</div>
33-
</body>
34-
</html>
29+
</div>

src/main/resources/templates/movie-ratings.html

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
<html xmlns:th="http://www.thymeleaf.org"
2-
th:replace="~{common/layout :: layout(~{::title}, ~{::section})}">
2+
th:replace="~{common/layout :: layout(~{::title}, ~{::section})}"
3+
th:with="_htmx=true">
34
<head>
4-
<title>
5-
<!-- th:text="${movieRecommendations.caption}"-->
6-
>Embabel Movie Finder</title>
7-
<th:block th:fragment="extraHeadContent">
8-
<script src="https://unpkg.com/htmx.org@2.0.5"></script>
9-
</th:block>
5+
6+
<title>Flicker</title>
7+
108
</head>
119
<body>
1210
<section>
1311
<div class="container">
1412
<h1>My Movie Ratings</h1>
1513
<p>
16-
<a href="/" class="btn btn-primary">Find Movies</a>
17-
<button class="btn btn-success" hx-get="/movie/ratings/add" hx-target="#rating-form-container">
14+
<!-- Replace whole page -->
15+
<button class="movie-button" hx-get="/" hx-target="body" hx-swap="outerHTML">
16+
Find movies
17+
</button>
18+
<button class="movie-button" hx-get="/movie/ratings/add" hx-target="#rating-form-container">
1819
Add New Rating
1920
</button>
2021
</p>
@@ -26,6 +27,16 @@ <h1>My Movie Ratings</h1>
2627
<div id="ratings-container">
2728
<div th:replace="~{fragments/rating-items :: rating-items(${ratings}, ${limit})}"></div>
2829
</div>
30+
31+
<!-- Infinite scroll trigger -->
32+
<div th:if="${hasMore}"
33+
th:hx-get="@{/movie/ratings/more(offset=${offset},limit=${limit})}"
34+
hx-trigger="intersect once"
35+
hx-target="#ratings-container"
36+
hx-swap="beforeend"
37+
hx-indicator=".loading-indicator">
38+
<div class="loading-indicator">Loading more...</div>
39+
</div>
2940
</div>
3041

3142
</section>

0 commit comments

Comments
 (0)