Files
housesof/src/routes/viewer/[country]/[location]/[photo].svelte
Félix Péault 9ffc210c02 WIP Animations all over site
- Run a transition In for each page
- Involve a "loader" panel on page change
- TODO: tweak the animations and finish the concept
2020-03-06 14:22:51 +01:00

143 lines
4.8 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>