feat: infinite scroll

This commit is contained in:
efim 2023-09-24 14:32:47 +00:00
parent 43daef0455
commit aca8599d6e
2 changed files with 35 additions and 11 deletions

View File

@ -25,9 +25,11 @@
> >
<h1 class="font-bold">Where in the world?</h1> <h1 class="font-bold">Where in the world?</h1>
<div class="flex flex-row gap-x-2"> <div class="flex flex-row gap-x-2">
<img src="../public/icons/half-moon-shape-svgrepo-com.svg" <img
src="../public/icons/half-moon-shape-svgrepo-com.svg"
class="w-4" class="w-4"
alt="" /> alt=""
/>
<p>Dark Mode</p> <p>Dark Mode</p>
</div> </div>
</header> </header>
@ -42,10 +44,12 @@
> >
<div class="flex flex-row bg-white shadow-md h-14 rounded-lg"> <div class="flex flex-row bg-white shadow-md h-14 rounded-lg">
<!-- <p class="w-16 grid place-content-center">IC</p> --> <!-- <p class="w-16 grid place-content-center">IC</p> -->
<img src="../public/icons/search-svgrepo-com.svg" <img
src="../public/icons/search-svgrepo-com.svg"
th:src="@{~/public/icons/search-svgrepo-com.svg}" th:src="@{~/public/icons/search-svgrepo-com.svg}"
class="w-6 mx-5" class="w-6 mx-5"
alt="" /> alt=""
/>
<input <input
class="appearance-none flex-grow focus:outline-none mr-2" class="appearance-none flex-grow focus:outline-none mr-2"
type="text" type="text"
@ -99,7 +103,6 @@
<main <main
class="flex flex-col items-center gap-10 pb-8" class="flex flex-col items-center gap-10 pb-8"
id="countries-main-list" id="countries-main-list"
th:remove="all-but-first"
th:fragment="countries-main (countriesList)" th:fragment="countries-main (countriesList)"
> >
<article <article
@ -141,10 +144,19 @@
</section> </section>
</a> </a>
</article> </article>
<div
th:if="${nextPage != -1}"
id="next-page-anchor"
hx-trigger="revealed"
th:hx-get="@{~/(region=${selectedRegion},page=${nextPage})}"
hx-swap="outerHTML"
hx-select="#countries-main-list"
></div>
<article <article
id="usa" id="usa"
class="bg-white h-[350px] w-[275px] border flex flex-col rounded-lg shadow-lg" class="bg-white h-[350px] w-[275px] border flex flex-col rounded-lg shadow-lg"
th:remove="all"
> >
<img <img
src="https://flagcdn.com/us.svg" src="https://flagcdn.com/us.svg"
@ -173,6 +185,7 @@
<article <article
id="Brazil" id="Brazil"
class="bg-white h-[350px] w-[275px] border flex flex-col rounded-lg shadow-lg" class="bg-white h-[350px] w-[275px] border flex flex-col rounded-lg shadow-lg"
th:remove="all"
> >
<img <img
src="https://flagcdn.com/br.svg" src="https://flagcdn.com/br.svg"

View File

@ -30,18 +30,28 @@ case class Routes(countries: List[Country])(implicit
} }
val engine: TemplateEngine = buildTemplateEngine() val engine: TemplateEngine = buildTemplateEngine()
private val pageSize = 10
@cask.get("/") @cask.get("/")
def indexPage(region: Option[String] = None) = { def indexPage(region: Option[String] = None, page: Int = 0) = {
val context = new Context() val context = new Context()
val regions = countries.map(_.region).distinct.sorted.asJava val regions = countries.map(_.region).distinct.sorted.asJava
val selectedCountries = region match { val selectedCountries = region match {
case None => countries case None => countries
case Some("") => countries
case Some(selectedRegion) => countries.filter(_.region == selectedRegion) case Some(selectedRegion) => countries.filter(_.region == selectedRegion)
} }
val startIndex = page * pageSize
val countriesPage =
selectedCountries.slice(startIndex, startIndex + pageSize)
// if current page is not full - there will be no next page
val nextPage = if (countriesPage.length == pageSize) page + 1 else -1
context.setVariable("nextPage", nextPage)
context.setVariable("regionsSet", regions) context.setVariable("regionsSet", regions)
context.setVariable("countriesList", selectedCountries.asJava) context.setVariable("countriesList", countriesPage.asJava)
context.setVariable("allCountriesList", countries.asJava) context.setVariable("allCountriesList", countries.asJava)
context.setVariable("selectedRegion", region.getOrElse("")) context.setVariable("selectedRegion", region.getOrElse(""))
@ -60,7 +70,8 @@ case class Routes(countries: List[Country])(implicit
context.setVariable("country", selectedCountry) context.setVariable("country", selectedCountry)
val borderCountries = countries val borderCountries = countries
.filter(c => selectedCountry.borders.contains(c.alpha3Code)) .filter(c => selectedCountry.borders.contains(c.alpha3Code))
.map(_.name).asJava .map(_.name)
.asJava
context.setVariable("borderCountries", borderCountries) context.setVariable("borderCountries", borderCountries)