Photo viewer

This commit is contained in:
2019-12-28 13:16:25 +01:00
parent 648e00d244
commit ff17ee6167

View File

@@ -0,0 +1,148 @@
<script context="module">
// Svelte
import { api, locations, currentLocation } from '../../../../store'
// Define to preload data or load the store
let preloaded
currentLocation.subscribe(store => {
preloaded = (store) ? store : undefined
})
// Sapper preload data
export async function preload (page, session) {
if (preloaded === undefined) {
const photos = await this.fetch(`${api.rest}/items/photos?fields=id,name,slug,image.data,created_on&filter[location.slug][rlike]=%${page.params.location}%`)
const photosData = await photos.json()
return {
photos: photosData.data
}
} else {
return {
photos: preloaded.photos
}
}
}
</script>
<script>
import { stores } from '@sapper/app'
const { page, session, preloading } = stores()
// Dependencies
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
dayjs.extend(advancedFormat)
export let photos
let currentIndex
let indexFormated
let viewerPhotos
// Define current location
if ($currentLocation === undefined) {
currentLocation.set({
location: $locations.find(location => location.slug === $page.params.location),
photos: photos
})
}
// Set current photo, index and siblings
const setCurrentPhotos = () => {
// Define index and prev/next photos
currentIndex = photos.findIndex(photo => photo.slug === $page.params.photo)
indexFormated = (currentIndex < 10) ? '0' + (currentIndex + 1) : currentIndex + 1
viewerPhotos = {
current: photos[currentIndex],
// Last photo if first, otherwise index-1
prev: (currentIndex === 0) ? photos[photos.length - 1] : photos[currentIndex - 1],
// First photo if last, otherwise index+1
next: (currentIndex === photos.length - 1) ? photos[0] : photos[currentIndex + 1]
}
}
// On photo page change
page.subscribe(({ path, params, query }) => {
if (path.includes('/viewer/')) {
setCurrentPhotos()
}
})
// Define things
const locationFull = `${$currentLocation.location.name}, ${$currentLocation.location.country.name}`
const path = `/viewer/${$currentLocation.location.country.slug}/${$currentLocation.location.slug}/`
// Get thumbnail
const getThumb = (photo, size) => {
if (photo) {
const thumbnail = photo.image.data.thumbnails.find(thumb => thumb.url.includes(`key=${size}`))
return thumbnail.url
}
}
// Keyboard navigation
const keyboardNav = event => {
const keyCode = event.keyCode
// Previous
if ([37,80].includes(keyCode)) document.getElementById('photo_prev').click()
// Next
else if ([39,78,32].includes(keyCode)) document.getElementById('photo_next').click()
// Close
else if ([27,67].includes(keyCode)) document.getElementById('photo_close').click()
}
</script>
<!-- <pre>{JSON.stringify(viewerPhotos, null, 2)}</pre> -->
<svelte:window on:keydown={keyboardNav} />
<div class="container">
<div class="nav content">
<a href="/choose" class="button is-info" id="photo_close">Change location</a>
<a href="/location/{$currentLocation.location.country.slug}/{$currentLocation.location.slug}" class="button is-dark" id="photo_close">Close</a>
</div>
<div class="photo">
<div class="image">
<img src="{getThumb(viewerPhotos.current, 'large')}" srcset="{getThumb(viewerPhotos.current, 'large')} 1x, {getThumb(viewerPhotos.current, 'large-2x')} 2x" alt="{viewerPhotos.current.name}">
</div>
<div class="details content">
<strong class="is-size-5">{viewerPhotos.current.name}</strong> <br>
<span>{locationFull}</span> <br>
<span>{indexFormated}</span> <br>
<span>{dayjs(viewerPhotos.current.date).format('MMM Do, YYYY')}</span>
</div>
</div>
<div class="section">
<div class="level">
<div class="level-left">
<a href="{path + viewerPhotos.prev.slug}" id="photo_prev">
<div class="media">
<div class="media-left">
<img src="{getThumb(viewerPhotos.prev, 'thumbnail')}" alt="{viewerPhotos.prev.name}" width="200">
</div>
<div class="media-content content">
<strong class="is-size-5">{viewerPhotos.prev.name}</strong> <br>
<span>{locationFull}</span>
</div>
</div>
</a>
</div>
<div class="level-right">
<a href="{path + viewerPhotos.next.slug}" id="photo_next">
<div class="media">
<div class="media-content content has-text-right">
<strong class="is-size-5">{viewerPhotos.next.name}</strong> <br>
<span>{locationFull}</span>
</div>
<div class="media-right">
<img src="{getThumb(viewerPhotos.next, 'thumbnail')}" alt="{viewerPhotos.next.name}" width="200">
</div>
</div>
</a>
</div>
</div>
</div>
</div>