Files
housesof/src/routes/_layout.svelte
Félix Péault cd609cd710 Add a badge on locations for new photos
- The last updated date is taken from the latest photo of each location (without any other API call, just some data manipulation)
- Manipulation of data in the preload request instead of the code
2020-05-06 17:12:07 +02:00

178 lines
5.8 KiB
Svelte

<script context="module">
export async function preload (page, session) {
await this.fetch(apiEndpoints.gql, {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': 'bearer ' + process.env.CONFIG.API_TOKEN
},
body: JSON.stringify({ query: `{
site {
data {
description
explore_globe
explore_list
photos_per_page
instagram
seo_name
seo_title_default
seo_description_default
seo_share_image { full_url }
credits_text
credits_list
newsletter_text
newsletter_subtitle
newsletter_url
}
}
continents {
data {
id
name
rotation_position
}
}
countries {
data {
id
name
slug
flag { full_url title }
continent { id name }
}
}
locations (filter: { status_eq: "published" }) {
data {
id
name
slug
region
country { id name slug }
description
close
coordinates
illu_desktop { full_url }
illu_desktop_2x { full_url }
illu_mobile { full_url }
}
}
photos (filter: { status_eq: "published" }) {
data {
created_on
location { id }
}
}
}`})
})
.then(res => res.json())
.then(res => {
const { data } = res
// Manipulate countries data
data.countries.data.forEach(country => {
const matchingContinent = data.continents.data.find(continent => continent.id === country.continent.id)
// Replace continent with request data
country.continent = matchingContinent
// Add countries to each continents
matchingContinent.countries = []
matchingContinent.countries.push(country)
})
// Replace each location's country with request data
data.locations.data.forEach(location => {
location.country = data.countries.data.find(country => country.id === location.country.id)
})
// Filter and keep only the latest photo for each location
// https://stackoverflow.com/questions/61636965/
const latestPhotos = Object.values(data.photos.data.reduce((photos, photo) => {
if (photos.hasOwnProperty(photo.location.id)) {
if (new Date(photos[photo.location.id].created_on) < new Date(photo.created_on)) {
photos[photo.location.id] = photo
}
} else {
photos[photo.location.id] = photo
}
return photos
}, {}))
// Add last updated date to each location
data.locations.data.forEach(location => {
const latestPhoto = latestPhotos.find(photo => photo.location.id === location.id)
location.last_updated = latestPhoto.created_on
})
// Set data into store
site.set(data.site.data[0])
continents.set(data.continents.data)
countries.set(data.countries.data)
locations.set(data.locations.data)
})
}
</script>
<script>
import { onMount } from 'svelte'
import { stores } from '@sapper/app'
import {
apiEndpoints,
site,
continents,
countries,
locations,
pageReady
} from 'utils/store'
// Dependencies
import lazySizes from 'lazysizes'
// Components
import AnalyticsTracker from 'utils/AnalyticsTracker'
import Transition from 'utils/Transition'
// Variables
const { page } = stores()
// Settings
lazySizes.cfg.lazyClass = 'lazyload'
/*
** Head stuff
*/
// Preconnect
const preconnect = [
'https://api.housesof.world',
'https://www.googletagmanager.com',
'https://stats.g.doubleclick.net',
'https://www.google-analytics.com',
]
// Preload assets
const preload = {
fonts: [
'/fonts/G-Light.woff2',
'/fonts/G-Regular.woff2',
'/fonts/G-Semibold.woff2',
'/fonts/M-Extralight.woff2',
'/fonts/M-Light.woff2',
]
}
</script>
<style lang="scss" global>
@import "../style/style.scss";
</style>
<svelte:head>
<link rel="canonical" href={`https://${$page.host}${$page.path}`} />
{#each preconnect as host}
<link rel="preconnect" href={host} crossorigin>
<link rel="dns-prefetch" href={host}>
{/each}
{#each preload.fonts as font}
<link rel="preload" href={font} as="font" type="font/woff2" crossorigin>
{/each}
</svelte:head>
<slot></slot>
<Transition />
<AnalyticsTracker {stores} id={process.env.CONFIG.GA_TRACKER_ID} />