✨ Finish Photo viewer styling with responsive
This commit is contained in:
@@ -2,80 +2,126 @@
|
||||
import { page } from '$app/stores'
|
||||
import dayjs from 'dayjs'
|
||||
import advancedFormat from 'dayjs/plugin/advancedFormat.js'
|
||||
import { getAssetUrlKey } from '$utils/helpers'
|
||||
// Components
|
||||
import Metas from '$components/Metas.svelte'
|
||||
import Image from '$components/atoms/Image.svelte'
|
||||
import IconArrow from '$components/atoms/IconArrow.svelte'
|
||||
import ButtonCircle from '$components/atoms/ButtonCircle.svelte'
|
||||
import IconArrow from '$components/atoms/IconArrow.svelte'
|
||||
import ButtonCircle from '$components/atoms/ButtonCircle.svelte'
|
||||
|
||||
export let photos: any[]
|
||||
export let location: any
|
||||
export let currentIndex: number
|
||||
export let totalPhotos: number
|
||||
|
||||
dayjs.extend(advancedFormat)
|
||||
|
||||
// let currentIndex: number = 0
|
||||
|
||||
// Find current photo from the slug
|
||||
$: currentPhoto = photos.find((photo: any) => photo.slug === $page.params.photo)
|
||||
$: currentPhotoIndex = photos.findIndex((photo: any) => photo.slug === $page.params.photo)
|
||||
// Define reactive last and first photos
|
||||
$: isLast = currentIndex === totalPhotos - 1
|
||||
$: isFirst = currentIndex === 0
|
||||
// Define current photo
|
||||
// $: currentPhoto = photos.find((photo: any) => photo.slug === $page.params.photo)
|
||||
$: currentPhoto = photos[photos.findIndex((photo: any) => photo.slug === $page.params.photo)]
|
||||
// Reactive photos showns
|
||||
$: shownPhotos = [
|
||||
...photos.filter((photo: any, index: number) => {
|
||||
// Grab the 4 prev and next photos depending the index
|
||||
console.log(index)
|
||||
// console.log(index >= currentIndex - 4 && index < currentIndex + 4)
|
||||
})
|
||||
]
|
||||
|
||||
|
||||
/**
|
||||
* Go to next photo
|
||||
* Photo navigation
|
||||
*/
|
||||
// Go to next photo
|
||||
const goToNext = () => {
|
||||
currentIndex++
|
||||
if (!isLast) {
|
||||
currentIndex++
|
||||
}
|
||||
|
||||
// TODO: Fetch new photos
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Go to previous photo
|
||||
*/
|
||||
// Fo to previous photo
|
||||
const goToPrevious = () => {
|
||||
currentIndex--
|
||||
if (!isFirst) {
|
||||
currentIndex--
|
||||
}
|
||||
|
||||
// TODO: Fetch new photos
|
||||
}
|
||||
|
||||
// Manage navigation with keyboard
|
||||
const handleKeydown = ({ key, defaultPrevented }: KeyboardEvent) => {
|
||||
if (defaultPrevented) return
|
||||
switch (key) {
|
||||
case 'ArrowLeft': goToNext(); break;
|
||||
case 'ArrowRight': goToPrevious(); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load photos
|
||||
*/
|
||||
const loadPhotos = (index: number) => {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={handleKeydown} />
|
||||
|
||||
<main class="viewer-photo grid">
|
||||
<div class="viewer-photo__carousel">
|
||||
<div class="viewer-photo__images">
|
||||
<Image
|
||||
class="photo"
|
||||
id={currentPhoto.image.id}
|
||||
alt={currentPhoto.title}
|
||||
sizeKey="photo-list"
|
||||
sizes={{
|
||||
small: { width: 500 },
|
||||
medium: { width: 850 },
|
||||
large: { width: 1280 },
|
||||
}}
|
||||
ratio={1.5}
|
||||
/>
|
||||
{#if currentPhoto}
|
||||
<Metas
|
||||
title="{currentPhoto.title} - Houses Of {location.name}"
|
||||
description=""
|
||||
image={getAssetUrlKey(currentPhoto.image.id, 'share')}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<div class="viewer-photo__controls">
|
||||
<ButtonCircle on:click={goToPrevious}>
|
||||
<IconArrow color="pink" flip={true} />
|
||||
</ButtonCircle>
|
||||
<ButtonCircle on:click={goToPrevious}>
|
||||
<IconArrow color="pink" />
|
||||
</ButtonCircle>
|
||||
|
||||
<main class="viewer-photo">
|
||||
<div class="container grid">
|
||||
<div class="viewer-photo__carousel">
|
||||
<div class="viewer-photo__images">
|
||||
{#each photos as photo}
|
||||
<Image
|
||||
class="photo {photo.id === currentPhoto.id ? 'is-active' : ''}"
|
||||
id={photo.image.id}
|
||||
alt={photo.title}
|
||||
sizeKey="photo-list"
|
||||
sizes={{
|
||||
small: { width: 500 },
|
||||
medium: { width: 850 },
|
||||
large: { width: 1280 },
|
||||
}}
|
||||
ratio={1.5}
|
||||
/>
|
||||
{/each}
|
||||
|
||||
<div class="viewer-photo__controls">
|
||||
<ButtonCircle on:click={goToNext} disabled={isLast}>
|
||||
<IconArrow color="pink" flip={true} />
|
||||
</ButtonCircle>
|
||||
<ButtonCircle on:click={goToPrevious} disabled={isFirst}>
|
||||
<IconArrow color="pink" />
|
||||
</ButtonCircle>
|
||||
</div>
|
||||
|
||||
<span class="viewer-photo__index title-index">
|
||||
{currentIndex + 1}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="viewer-photo__index title-index">{currentIndex + 1}</p>
|
||||
</div>
|
||||
<div class="viewer-photo__info">
|
||||
<h1 class="title-medium">{currentPhoto.title}</h1>
|
||||
|
||||
|
||||
<div class="viewer-photo__info">
|
||||
<h1 class="title-medium">{currentPhoto.title}</h1>
|
||||
|
||||
<div class="detail text-date">
|
||||
<img src="/images/icons/map-pin.svg" alt=""><span>{location.name}, {location.country.name}</span> <span class="sep">·</span> <time datetime={dayjs(currentPhoto.date_taken).format('YYYY-MM-DD')}>{dayjs(currentPhoto.date_taken).format('MMMM, Do YYYY')}</time>
|
||||
<div class="detail text-date">
|
||||
<img src="/images/icons/map-pin.svg" width={16} height={18} alt="Map icon"><span>{location.name}, {location.country.name}</span> <span class="sep">·</span> <time datetime={dayjs(currentPhoto.date_taken).format('YYYY-MM-DD')}>{dayjs(currentPhoto.date_taken).format('MMMM, Do YYYY')}</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,8 +137,9 @@ import ButtonCircle from '$components/atoms/ButtonCircle.svelte'
|
||||
photos: photo (
|
||||
filter: { location: { slug: { _eq: "${page.params.location}" }}},
|
||||
sort: "-date_created",
|
||||
limit: 9,
|
||||
limit: 5,
|
||||
) {
|
||||
id
|
||||
title
|
||||
slug
|
||||
date_taken
|
||||
@@ -111,15 +158,19 @@ import ButtonCircle from '$components/atoms/ButtonCircle.svelte'
|
||||
`)
|
||||
|
||||
const { data } = res
|
||||
const location = stuff.locations.find((location: any) => location.slug === page.params.location)
|
||||
const totalPhotos = stuff.countTotalPhotosByLocation.find((total: any) => total.group.location === Number(location.id)).count.id
|
||||
|
||||
// Find photo's index
|
||||
const currentIndex = data.photos.findIndex((photo: any) => photo.slug === page.params.photo)
|
||||
const currentPhotoIndex = data.photos.findIndex((photo: any) => photo.slug === page.params.photo)
|
||||
const currentIndex = (totalPhotos - 1) - currentPhotoIndex
|
||||
|
||||
return {
|
||||
props: {
|
||||
photos: data.photos,
|
||||
location: data.location[0],
|
||||
currentIndex,
|
||||
totalPhotos,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user