Add Fullscreen in viewer, Track links with Google Analytics, Use .env file
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
- Fullscreen is a component that watches a store value set by the Carousel component on a picture click - Use a .env file for API and website related settings and informations - Google Analytics is now in place, tracking each routes link and viewer photo change
This commit is contained in:
@@ -71,9 +71,11 @@
|
||||
countries,
|
||||
locations
|
||||
} from '../utils/store'
|
||||
import { stores } from '@sapper/app'
|
||||
|
||||
// Components
|
||||
import Transition from '../utils/Transition'
|
||||
import AnalyticsTracker from '../utils/AnalyticsTracker'
|
||||
|
||||
// Props
|
||||
export const segment = null
|
||||
@@ -96,7 +98,6 @@
|
||||
$locations.forEach(loc => loc.country = $countries.find(cont => cont.id === loc.country.id))
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss" global>
|
||||
@import "../style/style.scss";
|
||||
</style>
|
||||
@@ -104,3 +105,5 @@
|
||||
<slot></slot>
|
||||
|
||||
<Transition />
|
||||
<AnalyticsTracker {stores} id={process.env.CONFIG.GA_TRACKER_ID} />
|
||||
|
||||
|
||||
@@ -6,21 +6,26 @@
|
||||
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}%`)
|
||||
// Fields
|
||||
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()}&filter[location.slug][rlike]=%${page.params.place}%`)
|
||||
const photos = await req.json()
|
||||
return {
|
||||
photos: photos.data
|
||||
if (req.ok) {
|
||||
return { photos: photos.data }
|
||||
}
|
||||
}
|
||||
// Use the store otherwise
|
||||
else return {
|
||||
photos: preloaded
|
||||
}
|
||||
this.error(404, 'Not found')
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -34,33 +39,33 @@
|
||||
pageReady,
|
||||
pageTransition
|
||||
} from '../../../../utils/store'
|
||||
import { getThumbnail } from '../../../../utils/functions'
|
||||
const { page } = stores()
|
||||
const dispatch = createEventDispatcher()
|
||||
import { getThumbnail, analyticsUpdate } 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 SocialMetas from '../../../../utils/SocialMetas'
|
||||
|
||||
// Animations
|
||||
import { animateIn } from '../../../../animations/viewer'
|
||||
pageTransition.onAnimationEnd = animateIn
|
||||
|
||||
|
||||
// Props
|
||||
export let photos
|
||||
|
||||
// Variables
|
||||
const { page } = stores()
|
||||
const dispatch = createEventDispatcher()
|
||||
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 (!$currentLocation) currentLocation.set($locations.find(loc => loc.slug === $page.params.place))
|
||||
if (!$currentPhotos) currentPhotos.set(photos)
|
||||
|
||||
// The photo has changed from the carousel
|
||||
// Photo has changed from the Carousel component
|
||||
const photoChanged = event => {
|
||||
currentPhoto = event.detail.currentPhoto
|
||||
|
||||
@@ -69,6 +74,7 @@
|
||||
const windowPathname = window.location.pathname
|
||||
const newUrl = windowPathname.substring(0, windowPathname.lastIndexOf('/') + 1) + currentPhoto.slug
|
||||
history.pushState('', document.title, newUrl)
|
||||
analyticsUpdate(newUrl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,11 +83,7 @@
|
||||
// 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', {
|
||||
currentPhoto: currentPhoto
|
||||
})
|
||||
}
|
||||
const changedUrl = event => dispatch('changedUrl', { currentPhoto: currentPhoto })
|
||||
|
||||
|
||||
/*
|
||||
@@ -91,25 +93,21 @@
|
||||
// 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
|
||||
})
|
||||
dispatch('changeUrl', { page: $page })
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<!-- TODO:
|
||||
- Change the title with the current photo name and update Metas (with window location url)
|
||||
-->
|
||||
<title>{$site.seo_name} – Photos of {$currentLocation.name}, {$currentLocation.country.name}</title>
|
||||
<meta name="description" content="{$site.seo_name} {$currentLocation.name} {$currentLocation.description}">
|
||||
<SocialMetas
|
||||
url="https://{$page.host}/viewer/{currentPhoto.location.country.slug}/{currentPhoto.location.slug}/{currentPhoto.slug}"
|
||||
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>
|
||||
|
||||
@@ -119,14 +117,14 @@
|
||||
<div class="viewer__top">
|
||||
<p class="tip">Tap for fullscreen</p>
|
||||
|
||||
<div class="buttons">
|
||||
<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>
|
||||
<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">
|
||||
<a href="/location/{$currentLocation.country.slug}/{$currentLocation.slug}" class="button-control button-control--pink 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>
|
||||
@@ -134,9 +132,11 @@
|
||||
</div>
|
||||
|
||||
<Carousel
|
||||
viewer="true"
|
||||
photos={photos}
|
||||
viewer={true}
|
||||
init={$page}
|
||||
on:photoChange={photoChanged}
|
||||
/>
|
||||
|
||||
<Fullscreen />
|
||||
</section>
|
||||
Reference in New Issue
Block a user