137 lines
4.9 KiB
Svelte
137 lines
4.9 KiB
Svelte
<script context="module">
|
||
// 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 fields = [
|
||
'id', 'name', 'slug', 'date', 'image.private_hash',
|
||
'location.id', 'location.name', 'location.slug',
|
||
'location.country.name', 'location.country.slug'
|
||
]
|
||
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=${fields.join()}&status=published&filter[location.slug][rlike]=%${page.params.place}%`, {
|
||
'Authorization': 'bearer ' + process.env.CONFIG.API_TOKEN
|
||
})
|
||
const photos = await req.json()
|
||
if (req.ok) {
|
||
return { photos: photos.data }
|
||
}
|
||
}
|
||
// Use the store otherwise
|
||
else return {
|
||
photos: preloaded
|
||
}
|
||
this.error(404, 'Not found')
|
||
}
|
||
</script>
|
||
|
||
<script>
|
||
import { onMount } from 'svelte'
|
||
import { stores } from '@sapper/app'
|
||
import {
|
||
apiEndpoints,
|
||
site,
|
||
locations,
|
||
currentLocation,
|
||
currentPhotos,
|
||
pageReady,
|
||
pageAnimation
|
||
} from 'utils/store'
|
||
import { getThumbnail } from 'utils/functions'
|
||
// Components
|
||
import IconGlobe from 'atoms/IconGlobe'
|
||
import IconCross from 'atoms/IconCross'
|
||
import Carousel from 'organisms/Carousel'
|
||
import Fullscreen from 'organisms/Fullscreen'
|
||
import Transition from 'utils/Transition'
|
||
import SocialMetas from 'utils/SocialMetas'
|
||
// Animations
|
||
import { animateIn } from 'animations/viewer'
|
||
|
||
// Props
|
||
export let photos
|
||
|
||
const { page } = stores()
|
||
pageAnimation.set(animateIn)
|
||
|
||
// Update store current location
|
||
currentLocation.set($locations.find(loc => loc.slug === $page.params.place))
|
||
currentPhotos.set(photos)
|
||
|
||
let windowWidth
|
||
let gotoLink
|
||
let pageTitle
|
||
let currentPhoto = photos.find(photo => photo.slug === $page.params.photo)
|
||
|
||
|
||
// Photo has changed (from Carousel)
|
||
const photoChanged = event => {
|
||
const currentPhoto = event.detail
|
||
const windowPathname = window.location.pathname
|
||
if (currentPhoto) {
|
||
const newUrl = windowPathname.substring(0, windowPathname.lastIndexOf('/') + 1) + currentPhoto.slug
|
||
// Go to page via a sapper-noscroll link to avoid scroll jump (hacky)
|
||
if (gotoLink && newUrl) {
|
||
gotoLink.href = newUrl
|
||
gotoLink.click()
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
** Run code when mounted
|
||
*/
|
||
onMount(() => {
|
||
// Page is loaded
|
||
pageReady.set(true)
|
||
})
|
||
</script>
|
||
|
||
<svelte:head>
|
||
{#if $currentLocation}
|
||
<title>{$site.seo_name} – {$site.seo_title_default} of {$currentLocation.name}, {$currentLocation.country.name}</title>
|
||
<meta name="description" content="{$site.seo_name} {$currentLocation.name} {$currentLocation.description}">
|
||
<SocialMetas
|
||
url="{process.env.CONFIG.PROD_URL}/viewer/{currentPhoto.location.country.slug}/{currentPhoto.location.slug}/{currentPhoto.slug}"
|
||
title="{$site.seo_name} - {$site.seo_title_default} of {$currentLocation.name}, {$currentLocation.country.name}"
|
||
description="{$site.seo_name} {$currentLocation.name} {$currentLocation.description}"
|
||
image={getThumbnail(currentPhoto.image.private_hash, 1200, 630)}
|
||
/>
|
||
{/if}
|
||
</svelte:head>
|
||
|
||
<svelte:window bind:innerWidth={windowWidth} />
|
||
|
||
<main class="housesof" class:is-transitioning={!$pageReady}>
|
||
<section class="viewer">
|
||
<div class="viewer__top">
|
||
<p class="tip">Tap for fullscreen</p>
|
||
|
||
<div class="viewer__buttons">
|
||
<a href="/choose" class="button-control button-control--dashed" aria-label="Change the location" rel="prefetch">
|
||
<IconGlobe color="#fff" width={windowWidth >= 768 ? 22 : 18} />
|
||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||
<circle cx="50%" cy="50%" r="{windowWidth >= 768 ? 32 : 24}px"></circle>
|
||
</svg>
|
||
</a>
|
||
{#if $currentLocation}
|
||
<a href="/location/{$currentLocation.country.slug}/{$currentLocation.slug}" class="button-control button-control--lightpink dir-bottom" aria-label="Back to photos" rel="prefetch">
|
||
<IconCross color="#fff" width="18" class="icon" />
|
||
<IconCross color="#fff" width="18" class="icon" hidden="true" />
|
||
</a>
|
||
{/if}
|
||
</div>
|
||
<a href="/" bind:this={gotoLink} aria-hidden="true" hidden class="hidden" sapper-noscroll> </a>
|
||
</div>
|
||
|
||
<Carousel {photos} viewer={true}
|
||
on:photoChange={photoChanged}
|
||
/>
|
||
|
||
<Fullscreen />
|
||
</section>
|
||
</main> |