- Run a transition In for each page - Involve a "loader" panel on page change - TODO: tweak the animations and finish the concept
143 lines
4.8 KiB
Svelte
143 lines
4.8 KiB
Svelte
<script context="module">
|
||
import { stores } from '@sapper/app'
|
||
import { apiEndpoints } from '../../../../utils/store'
|
||
|
||
// Define either to preload data or use the store
|
||
let preloaded
|
||
currentPhotos.subscribe(store => preloaded = store ? store : undefined)
|
||
|
||
|
||
// Preload data
|
||
export async function preload (page, session) {
|
||
// Load the photos if not loaded
|
||
if (!preloaded) {
|
||
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,slug,date,image.*,location.*,location.country.*,created_on,modified_on&filter[location.slug][rlike]=%${page.params.location}%`)
|
||
const photos = await req.json()
|
||
return {
|
||
photos: photos.data
|
||
}
|
||
}
|
||
// Use the store otherwise
|
||
else return {
|
||
photos: preloaded
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<script>
|
||
import { onMount, createEventDispatcher } from 'svelte'
|
||
import {
|
||
site,
|
||
locations,
|
||
currentLocation,
|
||
currentPhotos,
|
||
pageReady,
|
||
pageTransition
|
||
} from '../../../../utils/store'
|
||
import { getThumbnail } from '../../../../utils/functions'
|
||
const { page } = stores()
|
||
const dispatch = createEventDispatcher()
|
||
|
||
// Components
|
||
import IconGlobe from '../../../../atoms/IconGlobe'
|
||
import IconCross from '../../../../atoms/IconCross'
|
||
import Carousel from '../../../../organisms/Carousel'
|
||
import SocialMetas from '../../../../utils/SocialMetas'
|
||
|
||
// Animations
|
||
// import { animateIn } from '../../../animations/photoPage'
|
||
// pageTransition.onAnimationEnd = animateIn
|
||
|
||
|
||
// Props
|
||
export let photos
|
||
|
||
// Variables
|
||
let windowWidth
|
||
let currentPhoto = photos.find(photo => photo.slug === $page.params.photo)
|
||
|
||
// Update store current location
|
||
if (!$currentLocation) currentLocation.set($locations.find(loc => loc.slug === $page.params.location))
|
||
if (!$currentPhotos) currentPhotos.set(photos)
|
||
|
||
// The photo has changed from the carousel
|
||
const photoChanged = event => {
|
||
currentPhoto = event.detail.currentPhoto
|
||
|
||
// Change the URL to the current photo
|
||
if (!event.detail.init) {
|
||
const windowPathname = window.location.pathname
|
||
const newUrl = windowPathname.substring(0, windowPathname.lastIndexOf('/') + 1) + currentPhoto.slug
|
||
history.pushState('', document.title, newUrl)
|
||
}
|
||
}
|
||
|
||
// Access a direct photo or navigate in history
|
||
const photoSlug = $page.params.photo
|
||
// On init, send an event to the Carousel component with the photoSlug to set currentIndex and then change the photo
|
||
|
||
// Pop event from browser (prev/next)
|
||
// const changedUrl = event => {
|
||
// dispatch('changedUrl', {
|
||
// location: event.target.location
|
||
// })
|
||
// }
|
||
|
||
|
||
/*
|
||
** Run code when mounted
|
||
*/
|
||
onMount(() => {
|
||
// Page is loaded
|
||
pageReady.set(true)
|
||
|
||
/*
|
||
!!! TODO:
|
||
- Change the title with the current photo name and update Metas (with window location url)
|
||
*/
|
||
|
||
dispatch('changeUrl', {
|
||
page: $page
|
||
})
|
||
})
|
||
</script>
|
||
|
||
<svelte:head>
|
||
<title>{$site.seo_name} – Photos of {$currentLocation.name}, {$currentLocation.country.name}</title>
|
||
<meta name="description" content="{$site.seo_name} {$currentLocation.name} {$currentLocation.description}">
|
||
<SocialMetas
|
||
title="{$site.seo_name} - Beautiful homes of {$currentLocation.name}, {$currentLocation.country.name}"
|
||
description="{$site.seo_name} {$currentLocation.name} {$currentLocation.description}"
|
||
image={getThumbnail(currentPhoto.image.private_hash, 1200, 630)}
|
||
url="//{$page.host.split(':3000')[0]}/viewer/{currentPhoto.location.country.slug}/{currentPhoto.location.slug}/{currentPhoto.slug}"
|
||
/>
|
||
</svelte:head>
|
||
|
||
<svelte:window bind:innerWidth={windowWidth} />
|
||
|
||
<section class="viewer">
|
||
<div class="viewer__top">
|
||
<p class="tip">Tap for fullscreen</p>
|
||
|
||
<div class="buttons">
|
||
<a href="/choose" class="button-control button-control--dashed">
|
||
<IconGlobe color="#fff" width={windowWidth >= 768 ? 22 : 18} />
|
||
<svg>
|
||
<circle cx="50%" cy="50%" r="{windowWidth >= 768 ? 32 : 24}px"></circle>
|
||
</svg>
|
||
</a>
|
||
<a href="/location/{$currentLocation.country.slug}/{$currentLocation.slug}" class="button-control button-control--pink dir-bottom" aria-label="Close">
|
||
<IconCross color="#fff" width="18" class="icon" />
|
||
<IconCross color="#fff" width="18" class="icon" hidden="true" />
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
<Carousel
|
||
photos={photos}
|
||
viewer={true}
|
||
init={$page}
|
||
on:photoChange={photoChanged}
|
||
/>
|
||
</section>
|