Reorganise functions, Use custom Format Date/Relative Time over dayjs

This commit is contained in:
2020-03-06 14:14:17 +01:00
parent 46488146d0
commit adf2563eb8
11 changed files with 128 additions and 72 deletions

View File

@@ -1,6 +1,6 @@
<script>
import { stores } from '@sapper/app'
import * as fn from '../utils/functions'
import { randomString } from '../utils/functions'
const { page } = stores()
// Props
@@ -9,7 +9,7 @@
export let animated = false
// Generate a random ID for the mask
const randomId = fn.randomString(6, 'A')
const randomId = randomString(6, 'A')
</script>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"

View File

@@ -1,6 +1,6 @@
<script>
import { stores } from '@sapper/app'
import * as fn from '../utils/functions'
import { randomString } from '../utils/functions'
const { page } = stores()
// Props
@@ -9,7 +9,7 @@
export let animated = false
// Generate a random ID for the mask
const randomId = fn.randomString(6, 'A')
const randomId = randomString(6, 'A')
</script>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"

View File

@@ -1,6 +1,4 @@
<script>
import * as fn from '../utils/functions'
export let href = '/'
export let text = ''
export let target = null

View File

@@ -1,11 +1,11 @@
<script>
import * as fn from '../utils/functions'
import { lettersToSpan } from '../utils/functions'
</script>
<div class="title-location title-location--inline">
<div role="heading" aria-level="1" aria-label="Houses" data-aos="letters-translate-bottom">
<div class="anim-mask">
{@html fn.lettersToSpan('Houses')}
{@html lettersToSpan('Houses')}
</div>
</div>
@@ -13,7 +13,7 @@
<div aria-label="World" data-aos="letters-translate-bottom">
<div class="anim-mask">
{@html fn.lettersToSpan('World')}
{@html lettersToSpan('World')}
</div>
</div>
</div>

View File

@@ -3,13 +3,10 @@
import { fly } from 'svelte/transition'
import { quartOut } from 'svelte/easing'
import { site, currentLocation } from '../utils/store'
import * as fn from '../utils/functions'
// Dependencies
import * as basicScroll from 'basicscroll'
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
dayjs.extend(advancedFormat)
import { getThumbnail, formatDate } from '../utils/functions'
// Props and variables
export let photo
@@ -66,28 +63,28 @@
<a href={photoHref} sapper-noscroll>
<picture class="photo__picture">
{#if layout === 'list'}
<source media="(min-width: 992px)" data-srcset={fn.getThumbnail(photo.image.private_hash, 1300)}>
<source media="(min-width: 768px)" data-srcset={fn.getThumbnail(photo.image.private_hash, 992)}>
<source media="(min-width: 500px)" data-srcset={fn.getThumbnail(photo.image.private_hash, 650)}>
<source media="(min-width: 300px)" data-srcset={fn.getThumbnail(photo.image.private_hash, 400)}>
<source media="(min-width: 992px)" data-srcset={getThumbnail(photo.image.private_hash, 1300)}>
<source media="(min-width: 768px)" data-srcset={getThumbnail(photo.image.private_hash, 992)}>
<source media="(min-width: 500px)" data-srcset={getThumbnail(photo.image.private_hash, 650)}>
<source media="(min-width: 300px)" data-srcset={getThumbnail(photo.image.private_hash, 400)}>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/+HRfwAJmQPS6gISLwAAAABJRU5ErkJggg=="
data-src="{fn.getThumbnail(photo.image.private_hash, 900)}"
data-src="{getThumbnail(photo.image.private_hash, 900)}"
width={defaultWidth} height={defaultHeight}
alt={imgAlt}
class="lazyload"
data-aos="scale-down-fade-in" data-aos-once="true">
{:else}
<source media="(min-width: 992px)" srcset={fn.getThumbnail(photo.image.private_hash, 1300)}>
<source media="(min-width: 768px)" srcset={fn.getThumbnail(photo.image.private_hash, 992)}>
<source media="(min-width: 500px)" srcset={fn.getThumbnail(photo.image.private_hash, 650)}>
<source media="(min-width: 300px)" srcset={fn.getThumbnail(photo.image.private_hash, 400)}>
<img src="{fn.getThumbnail(photo.image.private_hash, 900)}" alt={imgAlt} width={defaultWidth} height={defaultHeight}>
<source media="(min-width: 992px)" srcset={getThumbnail(photo.image.private_hash, 1300)}>
<source media="(min-width: 768px)" srcset={getThumbnail(photo.image.private_hash, 992)}>
<source media="(min-width: 500px)" srcset={getThumbnail(photo.image.private_hash, 650)}>
<source media="(min-width: 300px)" srcset={getThumbnail(photo.image.private_hash, 400)}>
<img src="{getThumbnail(photo.image.private_hash, 900)}" alt={imgAlt} width={defaultWidth} height={defaultHeight}>
{/if}
</picture>
</a>
<time class="photo__date" datetime={dayjs(photo.date).format('YYYY-MM-DDThh:mm:ss')}>
{dayjs(photo.date).format('MMM Do, YYYY')}
<time class="photo__date" datetime={formatDate(photo.date, 'DATETIME')}>
{formatDate(photo.date, 'FULL')}
</time>
<span class="photo__number">{(index < 10 ? '0': '') + index}</span>
</div>

View File

@@ -2,15 +2,10 @@
import { onMount, createEventDispatcher } from 'svelte'
import { stores } from '@sapper/app'
import { currentLocation } from '../utils/store'
import * as fn from '../utils/functions'
import { getThumbnail, formatDate } from '../utils/functions'
const dispatch = createEventDispatcher()
const { page } = stores()
// Dependencies
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
dayjs.extend(advancedFormat)
// Components
import IconArrow from '../atoms/IconArrow'
@@ -147,11 +142,11 @@
class:gallery__photo--active={photo === currentPhoto}
class:gallery__photo--next={photo === nextPhoto}
>
<source media="(min-width: 968px)" srcset={fn.getThumbnail(photo.image.private_hash, 1400)}>
<source media="(min-width: 800px)" srcset={fn.getThumbnail(photo.image.private_hash, 900)}>
<source media="(min-width: 500px)" srcset={fn.getThumbnail(photo.image.private_hash, 600)}>
<source media="(min-width: 300px)" srcset={fn.getThumbnail(photo.image.private_hash, 400)}>
<img src="{fn.getThumbnail(photo.image.private_hash, 900)}" alt="{photo.name}, {photo.location.name}, {photo.location.country.name}">
<source media="(min-width: 968px)" srcset={getThumbnail(photo.image.private_hash, 1400)}>
<source media="(min-width: 800px)" srcset={getThumbnail(photo.image.private_hash, 900)}>
<source media="(min-width: 500px)" srcset={getThumbnail(photo.image.private_hash, 600)}>
<source media="(min-width: 300px)" srcset={getThumbnail(photo.image.private_hash, 400)}>
<img src="{getThumbnail(photo.image.private_hash, 900)}" alt="{photo.name}, {photo.location.name}, {photo.location.country.name}">
</picture>
{/each}
</div>
@@ -201,7 +196,7 @@
{/each}
</div>
{#if viewer}
<p class="carousel__date">{dayjs(currentPhoto.created_on).format('MMM Do, YYYY')}</p>
<p class="carousel__date">{formatDate(currentPhoto.date, 'FULL')}</p>
{/if}
</div>

View File

@@ -3,10 +3,10 @@
import { flip } from 'svelte/animate'
import { crossfadeReceive, crossfadeSend } from '../utils/animations'
import { locations, countries, continents } from '../utils/store'
import * as fn from '../utils/functions'
// Dependencies
import AOS from 'aos'
import { throttle } from '../utils/functions'
// Components
import Button from '../atoms/Button'
@@ -25,7 +25,7 @@
// Filter by continent
// Detects if click difference if too short with a throttled function
const toggleContinents = fn.throttle((event, continent) => {
const toggleContinents = throttle((event, continent) => {
continentsFiltered = (!continent) ? [...continentsToDisplay] : [continent]
}, transitionDuration)

View File

@@ -19,7 +19,7 @@
<script>
import { onMount } from 'svelte'
import { site, currentLocation, currentPhotos } from '../utils/store'
import * as fn from '../utils/functions'
import { lettersToSpan } from '../utils/functions'
// Dependencies
import * as basicScroll from 'basicscroll'
@@ -102,7 +102,7 @@
<div class="anim-mask">
<div class="anim title-parallax" id="title-houses" data-aos="letters-translate-top" data-aos-once="true">
<h1 class="title-massive" aria-label="Houses">
{@html fn.lettersToSpan('Houses')}
{@html lettersToSpan('Houses')}
</h1>
</div>
</div>
@@ -123,7 +123,7 @@
<section class="explore explore--homepage">
<div class="of" aria-label="of" data-aos="letters-translate-bottom" data-aos-once="true">
<div class="anim-mask">
{@html fn.lettersToSpan('of')}
{@html lettersToSpan('of')}
</div>
</div>
@@ -135,7 +135,7 @@
<div class="anim-mask anim-title">
<h1 class="title-massive title-parallax" id="title-world" aria-label="World" data-aos="letters-translate-bottom" data-aos-once="true">
{@html fn.lettersToSpan('World')}
{@html lettersToSpan('World')}
</h1>
</div>

View File

@@ -22,17 +22,11 @@
<script>
import { onMount } from 'svelte'
import * as fn from '../../../utils/functions'
import { formatDate, relativeTime, getThumbnail } from '../../../utils/functions'
const { page } = stores()
// Dependencies
import AOS from 'aos'
import 'lazysizes'
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
import relativeTime from 'dayjs/plugin/relativeTime'
dayjs.extend(advancedFormat)
dayjs.extend(relativeTime)
// Components
import IconGlobe from '../../../atoms/IconGlobe'
@@ -56,10 +50,9 @@
// Define dates
$: latestPhoto = photos[0]
$: dateUpdatedFull = latestPhoto ? dayjs(latestPhoto.modified_on).format('MMM Do, YYYY') : ''
$: dateUpdatedDatetime = latestPhoto ?dayjs(latestPhoto.modified_on).format('YYYY-MM-DDThh:mm:ss') : ''
$: dateUpdatedRelative = latestPhoto ?dayjs().to(dayjs(latestPhoto.modified_on)) : ''
$: lastUpdated = latestPhoto ? (dayjs(latestPhoto.modified_on).isBefore(dayjs().subtract(1, 'M'))) ? dateUpdatedFull : dateUpdatedRelatives : ''
$: dateUpdatedFull = latestPhoto ? formatDate(latestPhoto.modified_on, 'FULL') : ''
$: dateUpdatedDatetime = latestPhoto ? formatDate(latestPhoto.modified_on, 'DATETIME') : ''
$: dateUpdatedRelative = latestPhoto ? relativeTime(latestPhoto.modified_on, 2592000000) : ''
/*
@@ -98,7 +91,7 @@
url="https://housesof.world/location/{location.country.slug}/{location.slug}"
title="{$site.seo_name} Beautiful houses of {location.name}, {location.country.name}"
description="{$site.seo_name} {location.name} {location.description}"
image={latestPhoto ? fn.getThumbnail(latestPhoto.image.private_hash, 1200, 630) : null}
image={latestPhoto ? getThumbnail(latestPhoto.image.private_hash, 1200, 630) : null}
/>
</svelte:head>
@@ -129,6 +122,7 @@
<div class="place__description">
<div class="wrapper">
<p>{$site.description}</p>
{#if location.description}
<p>
Houses Of
@@ -142,7 +136,7 @@
{#if photos.length}
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
</p>
<ToggleLayout />
@@ -166,7 +160,7 @@
{#if photos.length}
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
</p>
{/if}
</aside>

View File

@@ -32,15 +32,10 @@
<script>
import { onMount, createEventDispatcher } from 'svelte'
import { goto } from '@sapper/app'
import * as fn from '../../../../utils/functions'
import { getThumbnail } from '../../../../utils/functions'
const { page } = stores()
const dispatch = createEventDispatcher()
// Dependencies
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
dayjs.extend(advancedFormat)
// Components
import IconGlobe from '../../../../atoms/IconGlobe'
import IconCross from '../../../../atoms/IconCross'

View File

@@ -43,16 +43,93 @@ export const lettersToSpan = string => {
/*
** Check if element is in viewport
** Format date from an input date
*/
export const isInViewport = element => {
const bounding = element.getBoundingClientRect()
return (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
)
export const formatDate = (originDate, format) => {
let output
const date = new Date(originDate)
// Date
const day = new Intl.DateTimeFormat('default', { day: 'numeric' }).format(date)
const day2 = new Intl.DateTimeFormat('default', { day: '2-digit' }).format(date)
const mthSh = new Intl.DateTimeFormat('default', { month: 'short' }).format(date)
const mthNb = new Intl.DateTimeFormat('default', { month: '2-digit' }).format(date)
const year = new Intl.DateTimeFormat('default', { year: 'numeric' }).format(date)
const ord = ['th', 'st', 'nd', 'rd'][(day > 3 && day < 21) || day % 10 > 3 ? 0 : day % 10]
// Full format (MMM Do, YYYY)
if (format === 'FULL') {
output = `${mthSh} ${day + ord}, ${year}`
}
// Fulltime format (YYYY-MM-DDThh:mm:ss)
else if (format === 'DATETIME') {
output = date.toISOString()
}
return output
}
/*
** Relative time from an input date
*/
export const relativeTime = (originDate, limit = 0) => {
const date = new Date(originDate)
const diff = Number(new Date()) - date
// Define units in milliseconds
const mn = 60 * 1000
const hr = mn * 60
const day = hr * 24
const mth = day * 30
const yr = day * 365
// Variables
let amount
let unit
let output
// Difference is seconds
if (diff < mn) {
amount = Math.round(diff / 1000)
unit = 'second'
}
// Difference is minutes
else if (diff < hr) {
amount = Math.round(diff / mn)
unit = 'minute'
}
// Difference is hours
else if (diff < day) {
amount = Math.round(diff / hr)
unit = 'hour'
}
// Difference is days
else if (diff < mth) {
amount = Math.round(diff / day)
unit = 'day'
}
// Difference is months
else if (diff < yr) {
amount = Math.round(diff / mth)
unit = 'month'
}
// Difference is years
else if (diff > yr) {
amount = Math.round(diff / yr)
unit = 'year'
}
// Define the output
output = `${amount} ${amount > 1 ? `${unit}s` : unit} ago`
// Detect if the difference is over the limit
if (diff > limit) {
output = formatDate(date, 'FULL')
}
return output
}