Reorganise functions, Use custom Format Date/Relative Time over dayjs
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { stores } from '@sapper/app'
|
import { stores } from '@sapper/app'
|
||||||
import * as fn from '../utils/functions'
|
import { randomString } from '../utils/functions'
|
||||||
const { page } = stores()
|
const { page } = stores()
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
export let animated = false
|
export let animated = false
|
||||||
|
|
||||||
// Generate a random ID for the mask
|
// Generate a random ID for the mask
|
||||||
const randomId = fn.randomString(6, 'A')
|
const randomId = randomString(6, 'A')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { stores } from '@sapper/app'
|
import { stores } from '@sapper/app'
|
||||||
import * as fn from '../utils/functions'
|
import { randomString } from '../utils/functions'
|
||||||
const { page } = stores()
|
const { page } = stores()
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
export let animated = false
|
export let animated = false
|
||||||
|
|
||||||
// Generate a random ID for the mask
|
// Generate a random ID for the mask
|
||||||
const randomId = fn.randomString(6, 'A')
|
const randomId = randomString(6, 'A')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import * as fn from '../utils/functions'
|
|
||||||
|
|
||||||
export let href = '/'
|
export let href = '/'
|
||||||
export let text = ''
|
export let text = ''
|
||||||
export let target = null
|
export let target = null
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import * as fn from '../utils/functions'
|
import { lettersToSpan } from '../utils/functions'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="title-location title-location--inline">
|
<div class="title-location title-location--inline">
|
||||||
<div role="heading" aria-level="1" aria-label="Houses" data-aos="letters-translate-bottom">
|
<div role="heading" aria-level="1" aria-label="Houses" data-aos="letters-translate-bottom">
|
||||||
<div class="anim-mask">
|
<div class="anim-mask">
|
||||||
{@html fn.lettersToSpan('Houses')}
|
{@html lettersToSpan('Houses')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<div aria-label="World" data-aos="letters-translate-bottom">
|
<div aria-label="World" data-aos="letters-translate-bottom">
|
||||||
<div class="anim-mask">
|
<div class="anim-mask">
|
||||||
{@html fn.lettersToSpan('World')}
|
{@html lettersToSpan('World')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,13 +3,10 @@
|
|||||||
import { fly } from 'svelte/transition'
|
import { fly } from 'svelte/transition'
|
||||||
import { quartOut } from 'svelte/easing'
|
import { quartOut } from 'svelte/easing'
|
||||||
import { site, currentLocation } from '../utils/store'
|
import { site, currentLocation } from '../utils/store'
|
||||||
import * as fn from '../utils/functions'
|
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
import * as basicScroll from 'basicscroll'
|
import * as basicScroll from 'basicscroll'
|
||||||
import dayjs from 'dayjs'
|
import { getThumbnail, formatDate } from '../utils/functions'
|
||||||
import advancedFormat from 'dayjs/plugin/advancedFormat'
|
|
||||||
dayjs.extend(advancedFormat)
|
|
||||||
|
|
||||||
// Props and variables
|
// Props and variables
|
||||||
export let photo
|
export let photo
|
||||||
@@ -66,28 +63,28 @@
|
|||||||
<a href={photoHref} sapper-noscroll>
|
<a href={photoHref} sapper-noscroll>
|
||||||
<picture class="photo__picture">
|
<picture class="photo__picture">
|
||||||
{#if layout === 'list'}
|
{#if layout === 'list'}
|
||||||
<source media="(min-width: 992px)" data-srcset={fn.getThumbnail(photo.image.private_hash, 1300)}>
|
<source media="(min-width: 992px)" data-srcset={getThumbnail(photo.image.private_hash, 1300)}>
|
||||||
<source media="(min-width: 768px)" data-srcset={fn.getThumbnail(photo.image.private_hash, 992)}>
|
<source media="(min-width: 768px)" data-srcset={getThumbnail(photo.image.private_hash, 992)}>
|
||||||
<source media="(min-width: 500px)" data-srcset={fn.getThumbnail(photo.image.private_hash, 650)}>
|
<source media="(min-width: 500px)" data-srcset={getThumbnail(photo.image.private_hash, 650)}>
|
||||||
<source media="(min-width: 300px)" data-srcset={fn.getThumbnail(photo.image.private_hash, 400)}>
|
<source media="(min-width: 300px)" data-srcset={getThumbnail(photo.image.private_hash, 400)}>
|
||||||
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/+HRfwAJmQPS6gISLwAAAABJRU5ErkJggg=="
|
<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}
|
width={defaultWidth} height={defaultHeight}
|
||||||
alt={imgAlt}
|
alt={imgAlt}
|
||||||
class="lazyload"
|
class="lazyload"
|
||||||
data-aos="scale-down-fade-in" data-aos-once="true">
|
data-aos="scale-down-fade-in" data-aos-once="true">
|
||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
<source media="(min-width: 992px)" srcset={fn.getThumbnail(photo.image.private_hash, 1300)}>
|
<source media="(min-width: 992px)" srcset={getThumbnail(photo.image.private_hash, 1300)}>
|
||||||
<source media="(min-width: 768px)" srcset={fn.getThumbnail(photo.image.private_hash, 992)}>
|
<source media="(min-width: 768px)" srcset={getThumbnail(photo.image.private_hash, 992)}>
|
||||||
<source media="(min-width: 500px)" srcset={fn.getThumbnail(photo.image.private_hash, 650)}>
|
<source media="(min-width: 500px)" srcset={getThumbnail(photo.image.private_hash, 650)}>
|
||||||
<source media="(min-width: 300px)" srcset={fn.getThumbnail(photo.image.private_hash, 400)}>
|
<source media="(min-width: 300px)" srcset={getThumbnail(photo.image.private_hash, 400)}>
|
||||||
<img src="{fn.getThumbnail(photo.image.private_hash, 900)}" alt={imgAlt} width={defaultWidth} height={defaultHeight}>
|
<img src="{getThumbnail(photo.image.private_hash, 900)}" alt={imgAlt} width={defaultWidth} height={defaultHeight}>
|
||||||
{/if}
|
{/if}
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
<time class="photo__date" datetime={dayjs(photo.date).format('YYYY-MM-DDThh:mm:ss')}>
|
<time class="photo__date" datetime={formatDate(photo.date, 'DATETIME')}>
|
||||||
{dayjs(photo.date).format('MMM Do, YYYY')}
|
{formatDate(photo.date, 'FULL')}
|
||||||
</time>
|
</time>
|
||||||
<span class="photo__number">{(index < 10 ? '0': '') + index}</span>
|
<span class="photo__number">{(index < 10 ? '0': '') + index}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,15 +2,10 @@
|
|||||||
import { onMount, createEventDispatcher } from 'svelte'
|
import { onMount, createEventDispatcher } from 'svelte'
|
||||||
import { stores } from '@sapper/app'
|
import { stores } from '@sapper/app'
|
||||||
import { currentLocation } from '../utils/store'
|
import { currentLocation } from '../utils/store'
|
||||||
import * as fn from '../utils/functions'
|
import { getThumbnail, formatDate } from '../utils/functions'
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const { page } = stores()
|
const { page } = stores()
|
||||||
|
|
||||||
// Dependencies
|
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import advancedFormat from 'dayjs/plugin/advancedFormat'
|
|
||||||
dayjs.extend(advancedFormat)
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import IconArrow from '../atoms/IconArrow'
|
import IconArrow from '../atoms/IconArrow'
|
||||||
|
|
||||||
@@ -147,11 +142,11 @@
|
|||||||
class:gallery__photo--active={photo === currentPhoto}
|
class:gallery__photo--active={photo === currentPhoto}
|
||||||
class:gallery__photo--next={photo === nextPhoto}
|
class:gallery__photo--next={photo === nextPhoto}
|
||||||
>
|
>
|
||||||
<source media="(min-width: 968px)" srcset={fn.getThumbnail(photo.image.private_hash, 1400)}>
|
<source media="(min-width: 968px)" srcset={getThumbnail(photo.image.private_hash, 1400)}>
|
||||||
<source media="(min-width: 800px)" srcset={fn.getThumbnail(photo.image.private_hash, 900)}>
|
<source media="(min-width: 800px)" srcset={getThumbnail(photo.image.private_hash, 900)}>
|
||||||
<source media="(min-width: 500px)" srcset={fn.getThumbnail(photo.image.private_hash, 600)}>
|
<source media="(min-width: 500px)" srcset={getThumbnail(photo.image.private_hash, 600)}>
|
||||||
<source media="(min-width: 300px)" srcset={fn.getThumbnail(photo.image.private_hash, 400)}>
|
<source media="(min-width: 300px)" srcset={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}">
|
<img src="{getThumbnail(photo.image.private_hash, 900)}" alt="{photo.name}, {photo.location.name}, {photo.location.country.name}">
|
||||||
</picture>
|
</picture>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@@ -201,7 +196,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{#if viewer}
|
{#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}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
import { flip } from 'svelte/animate'
|
import { flip } from 'svelte/animate'
|
||||||
import { crossfadeReceive, crossfadeSend } from '../utils/animations'
|
import { crossfadeReceive, crossfadeSend } from '../utils/animations'
|
||||||
import { locations, countries, continents } from '../utils/store'
|
import { locations, countries, continents } from '../utils/store'
|
||||||
import * as fn from '../utils/functions'
|
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
import AOS from 'aos'
|
import AOS from 'aos'
|
||||||
|
import { throttle } from '../utils/functions'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import Button from '../atoms/Button'
|
import Button from '../atoms/Button'
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Filter by continent
|
// Filter by continent
|
||||||
// Detects if click difference if too short with a throttled function
|
// 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]
|
continentsFiltered = (!continent) ? [...continentsToDisplay] : [continent]
|
||||||
}, transitionDuration)
|
}, transitionDuration)
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { site, currentLocation, currentPhotos } from '../utils/store'
|
import { site, currentLocation, currentPhotos } from '../utils/store'
|
||||||
import * as fn from '../utils/functions'
|
import { lettersToSpan } from '../utils/functions'
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
import * as basicScroll from 'basicscroll'
|
import * as basicScroll from 'basicscroll'
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
<div class="anim-mask">
|
<div class="anim-mask">
|
||||||
<div class="anim title-parallax" id="title-houses" data-aos="letters-translate-top" data-aos-once="true">
|
<div class="anim title-parallax" id="title-houses" data-aos="letters-translate-top" data-aos-once="true">
|
||||||
<h1 class="title-massive" aria-label="Houses">
|
<h1 class="title-massive" aria-label="Houses">
|
||||||
{@html fn.lettersToSpan('Houses')}
|
{@html lettersToSpan('Houses')}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
<section class="explore explore--homepage">
|
<section class="explore explore--homepage">
|
||||||
<div class="of" aria-label="of" data-aos="letters-translate-bottom" data-aos-once="true">
|
<div class="of" aria-label="of" data-aos="letters-translate-bottom" data-aos-once="true">
|
||||||
<div class="anim-mask">
|
<div class="anim-mask">
|
||||||
{@html fn.lettersToSpan('of')}
|
{@html lettersToSpan('of')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
|
|
||||||
<div class="anim-mask anim-title">
|
<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">
|
<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>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -22,17 +22,11 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import * as fn from '../../../utils/functions'
|
import { formatDate, relativeTime, getThumbnail } from '../../../utils/functions'
|
||||||
const { page } = stores()
|
const { page } = stores()
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
import AOS from 'aos'
|
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
|
// Components
|
||||||
import IconGlobe from '../../../atoms/IconGlobe'
|
import IconGlobe from '../../../atoms/IconGlobe'
|
||||||
@@ -56,10 +50,9 @@
|
|||||||
|
|
||||||
// Define dates
|
// Define dates
|
||||||
$: latestPhoto = photos[0]
|
$: latestPhoto = photos[0]
|
||||||
$: dateUpdatedFull = latestPhoto ? dayjs(latestPhoto.modified_on).format('MMM Do, YYYY') : ''
|
$: dateUpdatedFull = latestPhoto ? formatDate(latestPhoto.modified_on, 'FULL') : ''
|
||||||
$: dateUpdatedDatetime = latestPhoto ?dayjs(latestPhoto.modified_on).format('YYYY-MM-DDThh:mm:ss') : ''
|
$: dateUpdatedDatetime = latestPhoto ? formatDate(latestPhoto.modified_on, 'DATETIME') : ''
|
||||||
$: dateUpdatedRelative = latestPhoto ?dayjs().to(dayjs(latestPhoto.modified_on)) : ''
|
$: dateUpdatedRelative = latestPhoto ? relativeTime(latestPhoto.modified_on, 2592000000) : ''
|
||||||
$: lastUpdated = latestPhoto ? (dayjs(latestPhoto.modified_on).isBefore(dayjs().subtract(1, 'M'))) ? dateUpdatedFull : dateUpdatedRelatives : ''
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -98,7 +91,7 @@
|
|||||||
url="https://housesof.world/location/{location.country.slug}/{location.slug}"
|
url="https://housesof.world/location/{location.country.slug}/{location.slug}"
|
||||||
title="{$site.seo_name} – Beautiful houses of {location.name}, {location.country.name}"
|
title="{$site.seo_name} – Beautiful houses of {location.name}, {location.country.name}"
|
||||||
description="{$site.seo_name} {location.name} {location.description}"
|
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>
|
</svelte:head>
|
||||||
|
|
||||||
@@ -129,6 +122,7 @@
|
|||||||
<div class="place__description">
|
<div class="place__description">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<p>{$site.description}</p>
|
<p>{$site.description}</p>
|
||||||
|
|
||||||
{#if location.description}
|
{#if location.description}
|
||||||
<p>
|
<p>
|
||||||
Houses Of
|
Houses Of
|
||||||
@@ -142,7 +136,7 @@
|
|||||||
{#if photos.length}
|
{#if photos.length}
|
||||||
<p class="updated style-caps">
|
<p class="updated style-caps">
|
||||||
<strong>Updated</strong>
|
<strong>Updated</strong>
|
||||||
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
|
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ToggleLayout />
|
<ToggleLayout />
|
||||||
@@ -166,7 +160,7 @@
|
|||||||
{#if photos.length}
|
{#if photos.length}
|
||||||
<p class="updated style-caps">
|
<p class="updated style-caps">
|
||||||
<strong>Updated</strong>
|
<strong>Updated</strong>
|
||||||
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
|
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@@ -32,15 +32,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount, createEventDispatcher } from 'svelte'
|
import { onMount, createEventDispatcher } from 'svelte'
|
||||||
import { goto } from '@sapper/app'
|
import { goto } from '@sapper/app'
|
||||||
import * as fn from '../../../../utils/functions'
|
import { getThumbnail } from '../../../../utils/functions'
|
||||||
const { page } = stores()
|
const { page } = stores()
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
// Dependencies
|
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import advancedFormat from 'dayjs/plugin/advancedFormat'
|
|
||||||
dayjs.extend(advancedFormat)
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import IconGlobe from '../../../../atoms/IconGlobe'
|
import IconGlobe from '../../../../atoms/IconGlobe'
|
||||||
import IconCross from '../../../../atoms/IconCross'
|
import IconCross from '../../../../atoms/IconCross'
|
||||||
|
|||||||
@@ -43,16 +43,93 @@ export const lettersToSpan = string => {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Check if element is in viewport
|
** Format date from an input date
|
||||||
*/
|
*/
|
||||||
export const isInViewport = element => {
|
export const formatDate = (originDate, format) => {
|
||||||
const bounding = element.getBoundingClientRect()
|
let output
|
||||||
return (
|
const date = new Date(originDate)
|
||||||
bounding.top >= 0 &&
|
|
||||||
bounding.left >= 0 &&
|
// Date
|
||||||
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
const day = new Intl.DateTimeFormat('default', { day: 'numeric' }).format(date)
|
||||||
bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user