Use a component for the pagination
Make the component and the page communicate with events to add more photos
This commit is contained in:
67
src/organisms/Pagination.svelte
Normal file
67
src/organisms/Pagination.svelte
Normal file
@@ -0,0 +1,67 @@
|
||||
<script>
|
||||
import { onMount, createEventDispatcher } from 'svelte'
|
||||
import { currentLocation } from '../store'
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
// Props
|
||||
export let photos
|
||||
export let paginatedPhotos
|
||||
export let photosPerPage
|
||||
|
||||
// Variables
|
||||
let currentIndex = photosPerPage
|
||||
const pagesTotal = Math.ceil(photos.length / photosPerPage)
|
||||
const pagesArray = Array.from({ length: pagesTotal }, (v, k) => k + 1).reverse()
|
||||
let pageTranslate = 100 - (100 / pagesTotal)
|
||||
|
||||
// Add more photos to the loop
|
||||
const displayMorePhotos = () => {
|
||||
if (currentIndex < photos.length) {
|
||||
// Display the X next hidden photos
|
||||
const photosToAppend = photos.filter(photo => photo.hidden === true).splice(0, photosPerPage)
|
||||
photosToAppend.forEach(photo => photo.hidden = false)
|
||||
|
||||
// Merge new photos to show to the existing ones
|
||||
dispatch('updatePagination', {
|
||||
paginatedPhotos: [...paginatedPhotos, ...photosToAppend]
|
||||
})
|
||||
|
||||
// Increment current index
|
||||
currentIndex = currentIndex + photosPerPage
|
||||
|
||||
// Animate the pagination
|
||||
pageTranslate = pageTranslate - (100 / pagesTotal)
|
||||
} else {
|
||||
currentIndex = photos.length
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<section class="pagination">
|
||||
{#if photos.length && currentIndex <= photos.length}
|
||||
<div class="pagination__page" class:disabled={currentIndex === photos.length}
|
||||
on:click={displayMorePhotos}
|
||||
on:mouseenter={() => pageTranslate = pageTranslate - (100 / pagesTotal) * 0.666}
|
||||
on:mouseleave={() => pageTranslate = pageTranslate + (100 / pagesTotal) * 0.666}
|
||||
>
|
||||
<div class="pagination__info">page</div>
|
||||
<div class="pagination__numbers">
|
||||
<div class="scroll" style="transform: translateY(-{pageTranslate}%);">
|
||||
{#each pagesArray as page}
|
||||
<span>{page}</span>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
/{pagesTotal}
|
||||
</div>
|
||||
<p class="pagination__caption style-caps">See more photos</p>
|
||||
|
||||
{:else}
|
||||
{#if $currentLocation}
|
||||
<div class="pagination__message">
|
||||
<h3>That's all folks!</h3>
|
||||
<p class="pagination__caption style-caps">Come back later to check out <br>new photos of {$currentLocation.name}</p>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</section>
|
||||
@@ -11,7 +11,8 @@
|
||||
// Preload data
|
||||
export async function preload (page, session) {
|
||||
// Load photos
|
||||
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,date,slug,image.*,location.*,location.country.*,created_on,modified_on&filter[location.slug][rlike]=%${page.params.location}%&limit=-1&sort=-created_on,name`)
|
||||
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,slug,image.*,location.*,location.country.*,created_on,modified_on&filter[location.slug][rlike]=%${page.params.location}%&limit=-1&sort=-created_on,name`)
|
||||
console.log(req.headers.host)
|
||||
const photos = await req.json()
|
||||
if (req.ok) {
|
||||
return { photos: photos.data }
|
||||
@@ -22,6 +23,7 @@
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte'
|
||||
import * as fn from '../../../functions'
|
||||
const { page } = stores()
|
||||
|
||||
// Dependencies
|
||||
@@ -40,7 +42,9 @@
|
||||
import ToggleLayout from '../../../atoms/ToggleLayout'
|
||||
import Photo from '../../../molecules/Photo'
|
||||
import Switcher from '../../../molecules/Switcher'
|
||||
import Pagination from '../../../organisms/Pagination'
|
||||
import Footer from '../../../organisms/Footer'
|
||||
import SocialMetas from '../../../utils/SocialMetas'
|
||||
|
||||
// Props and variables
|
||||
export let photos
|
||||
@@ -64,33 +68,13 @@
|
||||
*/
|
||||
let photosPerPage = 2 // 12
|
||||
let currentIndex = photosPerPage
|
||||
const pagesTotal = Math.ceil(photos.length / photosPerPage)
|
||||
const pages = Array.from({ length: pagesTotal }, (v, k) => k + 1).reverse()
|
||||
let pageTranslate = 100 - (100 / pagesTotal)
|
||||
|
||||
// Hide photos by default
|
||||
photos.forEach((photo, index) => photo.hidden = (index + 1 > photosPerPage) ? true : false)
|
||||
let paginatedPhotos = photos.filter(photo => photo.hidden === false)
|
||||
|
||||
// Add more photos to the loop
|
||||
const displayMorePhotos = () => {
|
||||
if (currentIndex < photos.length) {
|
||||
// Display the X next hidden photos
|
||||
const photosToAppend = photos.filter(photo => photo.hidden === true).splice(0, photosPerPage)
|
||||
photosToAppend.forEach(photo => photo.hidden = false)
|
||||
|
||||
// Merge new photos to show to the existing ones
|
||||
paginatedPhotos = [...paginatedPhotos, ...photosToAppend]
|
||||
|
||||
// Increment current index
|
||||
currentIndex = currentIndex + photosPerPage
|
||||
|
||||
// Animate the pagination
|
||||
pageTranslate = pageTranslate - (100 / pagesTotal)
|
||||
} else {
|
||||
currentIndex = photos.length
|
||||
}
|
||||
}
|
||||
// Update pagination event from Pagination component
|
||||
const updatePagination = event => paginatedPhotos = event.detail.paginatedPhotos
|
||||
|
||||
|
||||
/*
|
||||
@@ -105,10 +89,18 @@
|
||||
AOS.init()
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Houses Of - Beautiful houses of {location.name}, {location.country.name}</title>
|
||||
<title>Houses Of – Beautiful houses of {location.name}, {location.country.name}</title>
|
||||
<meta name="description" content="Houses Of {location.name} {location.description}">
|
||||
<SocialMetas
|
||||
url="https://housesof.world/location/{location.country.slug}/{location.slug}"
|
||||
title="Houses Of – Beautiful houses of {location.name}, {location.country.name}"
|
||||
description="Houses Of {location.name} {location.description}"
|
||||
image={latestPhoto ? fn.getThumbnail(latestPhoto.image.private_hash, 1200, 630) : null}
|
||||
/>
|
||||
</svelte:head>
|
||||
|
||||
<section class="place">
|
||||
@@ -133,6 +125,7 @@
|
||||
<div class="place__description">
|
||||
<div class="wrapper">
|
||||
<p>{$site.description}</p>
|
||||
{#if location.description}
|
||||
<p>
|
||||
Houses Of
|
||||
<LinkChange href="/choose" text={location.name}>
|
||||
@@ -140,12 +133,16 @@
|
||||
</LinkChange>
|
||||
{location.description}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
{#if photos.length}
|
||||
<p class="updated style-caps">
|
||||
<strong>Updated</strong>
|
||||
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
|
||||
</p>
|
||||
|
||||
<ToggleLayout />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,10 +159,12 @@
|
||||
<aside class="photos__side">
|
||||
<Switcher type="switcher--side" />
|
||||
|
||||
{#if photos.length}
|
||||
<p class="updated style-caps">
|
||||
<strong>Updated</strong>
|
||||
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
|
||||
</p>
|
||||
{/if}
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
@@ -174,39 +173,22 @@
|
||||
{#each paginatedPhotos as photo, index}
|
||||
<Photo
|
||||
photo={photo}
|
||||
index={photos.length - photos.indexOf(photo)}
|
||||
layout={layoutSetting}
|
||||
index={photos.length - (photos.indexOf(photo))}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<section class="pagination">
|
||||
{#if photos.length && currentIndex <= photos.length}
|
||||
<div class="pagination__page" class:disabled={currentIndex === photos.length}
|
||||
on:click={displayMorePhotos}
|
||||
on:mouseenter={() => pageTranslate = pageTranslate - ((100 / pagesTotal) * 0.666)}
|
||||
on:mouseleave={() => pageTranslate = pageTranslate + ((100 / pagesTotal) * 0.666)}
|
||||
>
|
||||
<div class="pagination__info">page</div>
|
||||
<div class="pagination__numbers">
|
||||
<div class="scroll" style="transform: translateY(-{pageTranslate}%);">
|
||||
{#each pages as page}
|
||||
<span>{page}</span>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
/{pagesTotal}
|
||||
</div>
|
||||
<p class="pagination__caption style-caps">See more photos</p>
|
||||
<Pagination
|
||||
{photos} {paginatedPhotos} {photosPerPage}
|
||||
on:updatePagination={updatePagination}
|
||||
/>
|
||||
|
||||
{:else}
|
||||
<div class="pagination__message">
|
||||
<h3>That's all folks!</h3>
|
||||
<p class="pagination__caption style-caps">Come back later to check out <br>new photos of {location.name}</p>
|
||||
<div class="wrap" style="padding-top: 20vw; padding-bottom: 20vw;">
|
||||
<p style="text-align: center; color: #333;">No photo for {location.name}</p>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<Footer />
|
||||
|
||||
Reference in New Issue
Block a user