Merge branch 'dev'
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
*.d.ts
|
||||||
|
|
||||||
|
# Ignore files for PNPM, NPM and YARN
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
|||||||
@@ -1,20 +1 @@
|
|||||||
module.exports = {
|
module.exports = require('config/eslintrc.config.cjs')
|
||||||
root: true,
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
|
||||||
plugins: ['svelte3', '@typescript-eslint'],
|
|
||||||
ignorePatterns: ['*.cjs'],
|
|
||||||
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
|
|
||||||
settings: {
|
|
||||||
'svelte3/typescript': () => require('typescript')
|
|
||||||
},
|
|
||||||
parserOptions: {
|
|
||||||
sourceType: 'module',
|
|
||||||
ecmaVersion: 2019
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
es2017: true,
|
|
||||||
node: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,26 +20,27 @@
|
|||||||
"embla-carousel": "^7.0.9",
|
"embla-carousel": "^7.0.9",
|
||||||
"focus-visible": "^5.2.0",
|
"focus-visible": "^5.2.0",
|
||||||
"motion": "^10.15.5",
|
"motion": "^10.15.5",
|
||||||
"ogl": "^0.0.104",
|
"ogl": "^0.0.110",
|
||||||
"sanitize.css": "^13.0.0",
|
"sanitize.css": "^13.0.0",
|
||||||
"swell-js": "3.19.5",
|
"swell-js": "3.19.8",
|
||||||
"tweakpane": "^3.1.4"
|
"tweakpane": "^3.1.4",
|
||||||
|
"utils": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^1.0.2",
|
"@sveltejs/adapter-auto": "^2.0.0",
|
||||||
"@sveltejs/adapter-cloudflare": "^2.0.1",
|
"@sveltejs/adapter-cloudflare": "^2.0.1",
|
||||||
"@sveltejs/adapter-node": "^1.1.4",
|
"@sveltejs/adapter-vercel": "^2.0.2",
|
||||||
"@sveltejs/adapter-vercel": "^1.0.6",
|
"@sveltejs/kit": "^1.5.3",
|
||||||
"@sveltejs/kit": "^1.3.7",
|
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
"@typescript-eslint/parser": "^5.51.0",
|
||||||
"@typescript-eslint/parser": "^5.50.0",
|
|
||||||
"base-64": "^1.0.0",
|
"base-64": "^1.0.0",
|
||||||
"browserslist": "^4.21.5",
|
"browserslist": "^4.21.5",
|
||||||
|
"config": "workspace:*",
|
||||||
"cssnano": "^5.1.14",
|
"cssnano": "^5.1.14",
|
||||||
"eslint": "^8.33.0",
|
"eslint": "^8.33.0",
|
||||||
"eslint-plugin-svelte3": "^4.0.0",
|
"eslint-plugin-svelte": "^2.16.0",
|
||||||
"postcss": "^8.4.21",
|
"postcss": "^8.4.21",
|
||||||
"postcss-focus-visible": "^8.0.1",
|
"postcss-focus-visible": "^8.0.2",
|
||||||
"postcss-normalize": "^10.0.1",
|
"postcss-normalize": "^10.0.1",
|
||||||
"postcss-preset-env": "^8.0.1",
|
"postcss-preset-env": "^8.0.1",
|
||||||
"postcss-sort-media-queries": "^4.3.0",
|
"postcss-sort-media-queries": "^4.3.0",
|
||||||
@@ -49,7 +50,7 @@
|
|||||||
"svelte-preprocess": "^5.0.1",
|
"svelte-preprocess": "^5.0.1",
|
||||||
"tslib": "^2.5.0",
|
"tslib": "^2.5.0",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
"vite": "^4.0.4"
|
"vite": "^4.1.1"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
const cssnano = require('cssnano')
|
import cssnano from 'cssnano'
|
||||||
const presetEnv = require('postcss-preset-env')
|
import presetEnv from 'postcss-preset-env'
|
||||||
const focusVisible = require('postcss-focus-visible')
|
import focusVisible from 'postcss-focus-visible'
|
||||||
// const sortMediaQueries = require('postcss-sort-media-queries')
|
// import sortMediaQueries from 'postcss-sort-media-queries'
|
||||||
const normalize = require('postcss-normalize')
|
import normalize from 'postcss-normalize'
|
||||||
|
|
||||||
const dev = process.env.NODE_ENV !== 'development'
|
|
||||||
|
|
||||||
module.exports = {
|
export default {
|
||||||
plugins: [
|
plugins: [
|
||||||
// Preset Env
|
// Preset Env
|
||||||
presetEnv({
|
presetEnv({
|
||||||
@@ -25,7 +24,7 @@ module.exports = {
|
|||||||
normalize({}),
|
normalize({}),
|
||||||
|
|
||||||
// CSS Nano
|
// CSS Nano
|
||||||
!dev && cssnano({
|
!process.env.DEV && cssnano({
|
||||||
preset: ['default', {
|
preset: ['default', {
|
||||||
autoprefixer: true,
|
autoprefixer: true,
|
||||||
discardComments: { removeAll: true },
|
discardComments: { removeAll: true },
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
import { page } from '$app/stores'
|
import { page } from '$app/stores'
|
||||||
import { afterUpdate } from 'svelte'
|
import { afterUpdate } from 'svelte'
|
||||||
import { fade } from 'svelte/transition'
|
import { fade } from 'svelte/transition'
|
||||||
import { scrollToTop } from '$utils/functions'
|
import { scrollToTop } from 'utils/scroll'
|
||||||
import { pageLoading } from '$utils/stores'
|
import { pageLoading } from '$utils/stores'
|
||||||
import { DELAY, DURATION } from '$utils/constants'
|
import { DELAY, DURATION } from '$utils/constants'
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { splitText } from '$utils/functions'
|
import { splitText } from 'utils/text'
|
||||||
|
|
||||||
export let text: string
|
export let text: string
|
||||||
export let mode: string = undefined
|
export let mode: string = undefined
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
<span class="text-split__line" aria-hidden={index === 1}>
|
<span class="text-split__line" aria-hidden={index === 1}>
|
||||||
{#each split as word, i}
|
{#each split as word, i}
|
||||||
<span class="word" style:--i-w={i}>{word}</span>{#if word.includes('\n')}<br>{/if}
|
<span class="word" style:--i-w={i}>{word}</span>{#if word.includes('\n')}<br>{/if}
|
||||||
<!-- svelte-ignore empty-block -->
|
|
||||||
{#if i < split.length - 1}{/if}
|
{#if i < split.length - 1}{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
href={url} class={classes}
|
href={url} class={classes}
|
||||||
{target} {rel}
|
{target} {rel}
|
||||||
data-sveltekit-noscroll={isExternal || isProtocol ? 'off' : ''}
|
data-sveltekit-noscroll={isExternal || isProtocol ? 'off' : ''}
|
||||||
{disabled}
|
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
on:click
|
on:click
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
export let ratio: number = undefined
|
export let ratio: number = undefined
|
||||||
export let alt: string
|
export let alt: string
|
||||||
export let lazy = true
|
export let lazy = true
|
||||||
export let decoding: "auto" | "sync" | "async" = "auto"
|
export let decoding: 'auto' | 'sync' | 'async' = 'auto'
|
||||||
|
|
||||||
interface Sizes {
|
interface Sizes {
|
||||||
small?: { width?: number, height?: number }
|
small?: { width?: number, height?: number }
|
||||||
@@ -50,16 +50,16 @@
|
|||||||
$: imgSrc = id ? getAssetUrlKey(id, `${sizeKey}-small-jpg`) : src ? src : undefined
|
$: imgSrc = id ? getAssetUrlKey(id, `${sizeKey}-small-jpg`) : src ? src : undefined
|
||||||
$: srcSet = {
|
$: srcSet = {
|
||||||
// WebP
|
// WebP
|
||||||
webp:
|
webp: sizes
|
||||||
sizes ? [
|
? [
|
||||||
`${getAssetUrlKey(id, `${sizeKey}-small-webp`)} 345w`,
|
`${getAssetUrlKey(id, `${sizeKey}-small-webp`)} 345w`,
|
||||||
sizes.medium ? `${getAssetUrlKey(id, `${sizeKey}-medium-webp`)} 768w` : null,
|
sizes.medium ? `${getAssetUrlKey(id, `${sizeKey}-medium-webp`)} 768w` : null,
|
||||||
sizes.large ? `${getAssetUrlKey(id, `${sizeKey}-large-webp`)} 1280w` : null,
|
sizes.large ? `${getAssetUrlKey(id, `${sizeKey}-large-webp`)} 1280w` : null,
|
||||||
]
|
]
|
||||||
: [getAssetUrlKey(id, `${sizeKey}-webp`)],
|
: [getAssetUrlKey(id, `${sizeKey}-webp`)],
|
||||||
// JPG
|
// JPG
|
||||||
jpg:
|
jpg: sizes
|
||||||
sizes ? [
|
? [
|
||||||
`${getAssetUrlKey(id, `${sizeKey}-small-jpg`)} 345w`,
|
`${getAssetUrlKey(id, `${sizeKey}-small-jpg`)} 345w`,
|
||||||
sizes.medium ? `${getAssetUrlKey(id, `${sizeKey}-medium-jpg`)} 768w` : null,
|
sizes.medium ? `${getAssetUrlKey(id, `${sizeKey}-medium-jpg`)} 768w` : null,
|
||||||
sizes.large ? `${getAssetUrlKey(id, `${sizeKey}-large-jpg`)} 1280w` : null,
|
sizes.large ? `${getAssetUrlKey(id, `${sizeKey}-large-jpg`)} 1280w` : null,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { map } from '$utils/functions'
|
import { map } from 'utils/math'
|
||||||
import reveal from '$animations/reveal'
|
import reveal from '$animations/reveal'
|
||||||
|
|
||||||
export let tag: string
|
export let tag: string
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { addToCart } from '$utils/functions/shop'
|
import { addToCart } from '$utils/functions/shop'
|
||||||
import { capitalizeFirstLetter } from '$utils/functions'
|
import { capitalizeFirstLetter } from 'utils/string'
|
||||||
// Components
|
// Components
|
||||||
import SplitText from '$components/SplitText.svelte'
|
import SplitText from '$components/SplitText.svelte'
|
||||||
import Button from '$components/atoms/Button.svelte'
|
import Button from '$components/atoms/Button.svelte'
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { getContext } from 'svelte'
|
import { getContext } from 'svelte'
|
||||||
import { spring } from 'svelte/motion'
|
import { spring } from 'svelte/motion'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { lerp } from '$utils/functions'
|
import { lerp } from 'utils/math'
|
||||||
import { PUBLIC_PREVIEW_COUNT } from '$env/static/public'
|
import { PUBLIC_PREVIEW_COUNT } from '$env/static/public'
|
||||||
import { seenLocations } from '$utils/stores'
|
import { seenLocations } from '$utils/stores'
|
||||||
// Components
|
// Components
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
// Detect if location has new content
|
// Detect if location has new content
|
||||||
const seenLocationDate = dayjs(parsedSeenLocations[location.id])
|
const seenLocationDate = dayjs(parsedSeenLocations[location.id])
|
||||||
const isLocationSeen = parsedSeenLocations?.hasOwnProperty(location.id)
|
const isLocationSeen = location.id in parsedSeenLocations
|
||||||
|
|
||||||
// Define if location is has new photos
|
// Define if location is has new photos
|
||||||
if (seenLocationDate && isLocationSeen) {
|
if (seenLocationDate && isLocationSeen) {
|
||||||
|
|||||||
@@ -19,8 +19,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="notification-cart shadow-small"
|
<div class="notification-cart shadow-small"
|
||||||
on:click={closeNotification}
|
|
||||||
transition:fly={{ y: 20, duration: 700, easing: quartOut }}
|
transition:fly={{ y: 20, duration: 700, easing: quartOut }}
|
||||||
|
on:click={closeNotification}
|
||||||
|
on:keydown
|
||||||
>
|
>
|
||||||
<div class="notification-cart__left">
|
<div class="notification-cart__left">
|
||||||
<img src={image} width={58} height={88} alt={title}>
|
<img src={image} width={58} height={88} alt={title}>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
alt={image.title}
|
alt={image.title}
|
||||||
/>
|
/>
|
||||||
{:else if video && video.mp4 && video.webm}
|
{:else if video && video.mp4 && video.webm}
|
||||||
<video muted loop playsinline autoplay allow="autoplay">
|
<video muted loop playsinline autoplay>
|
||||||
<source type="video/mp4" src={getAssetUrlKey(video.mp4, 'step')} />
|
<source type="video/mp4" src={getAssetUrlKey(video.mp4, 'step')} />
|
||||||
<source type="video/webm" src={getAssetUrlKey(video.webm, 'step')} />
|
<source type="video/webm" src={getAssetUrlKey(video.webm, 'step')} />
|
||||||
<track kind="captions" />
|
<track kind="captions" />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
|
||||||
interface Option {
|
interface Option {
|
||||||
value: string
|
value: string
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
import { smoothScroll } from '$utils/stores'
|
import { smoothScroll } from '$utils/stores'
|
||||||
import { cartOpen, cartData, cartAmount, cartIsUpdating } from '$utils/stores/shop'
|
import { cartOpen, cartData, cartAmount, cartIsUpdating } from '$utils/stores/shop'
|
||||||
import { initSwell, getCart, updateCartItem, removeCartItem } from '$utils/functions/shop'
|
import { initSwell, getCart, updateCartItem, removeCartItem } from '$utils/functions/shop'
|
||||||
|
import { sendEvent } from '$utils/analytics'
|
||||||
// Components
|
// Components
|
||||||
import Button from '$components/atoms/Button.svelte'
|
import Button from '$components/atoms/Button.svelte'
|
||||||
import Icon from '$components/atoms/Icon.svelte'
|
import Icon from '$components/atoms/Icon.svelte'
|
||||||
import CartItem from '$components/molecules/CartItem.svelte'
|
import CartItem from '$components/molecules/CartItem.svelte'
|
||||||
import ShopLocationSwitcher from '$components/molecules/ShopLocationSwitcher.svelte'
|
import ShopLocationSwitcher from '$components/molecules/ShopLocationSwitcher.svelte'
|
||||||
import { sendEvent } from '$utils/analytics';
|
|
||||||
|
|
||||||
|
|
||||||
// Block scroll if cart is open
|
// Block scroll if cart is open
|
||||||
@@ -151,5 +151,6 @@
|
|||||||
<div class="cart-overlay"
|
<div class="cart-overlay"
|
||||||
transition:fade={{ duration: 600, easing: quartOut }}
|
transition:fade={{ duration: 600, easing: quartOut }}
|
||||||
on:click={handleCloseCart}
|
on:click={handleCloseCart}
|
||||||
|
on:keydown
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
import { fade, fly as flySvelte } from 'svelte/transition'
|
import { fade, fly as flySvelte } from 'svelte/transition'
|
||||||
import { quartOut } from 'svelte/easing'
|
import { quartOut } from 'svelte/easing'
|
||||||
import { Globe, type Marker } from '$modules/globe'
|
import { Globe, type Marker } from '$modules/globe'
|
||||||
import { getRandomItem, debounce } from '$utils/functions'
|
import { getRandomItem } from 'utils/array'
|
||||||
|
import { debounce } from 'utils/actions'
|
||||||
import { revealSplit } from '$animations/transitions'
|
import { revealSplit } from '$animations/transitions'
|
||||||
// Components
|
// Components
|
||||||
import SplitText from '$components/SplitText.svelte'
|
import SplitText from '$components/SplitText.svelte'
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import { quartOut } from 'svelte/easing'
|
import { quartOut } from 'svelte/easing'
|
||||||
import reveal from '$animations/reveal'
|
import reveal from '$animations/reveal'
|
||||||
import { send, receive } from '$animations/crossfade'
|
import { send, receive } from '$animations/crossfade'
|
||||||
import { throttle } from '$utils/functions'
|
import { throttle } from 'utils/actions'
|
||||||
import { sendEvent } from '$utils/analytics'
|
import { sendEvent } from '$utils/analytics'
|
||||||
// Components
|
// Components
|
||||||
import Button from '$components/atoms/Button.svelte'
|
import Button from '$components/atoms/Button.svelte'
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import EmblaCarousel, { type EmblaCarouselType } from 'embla-carousel'
|
import EmblaCarousel, { type EmblaCarouselType } from 'embla-carousel'
|
||||||
// Components
|
// Components
|
||||||
import Poster from '$components/molecules/Poster.svelte'
|
import Poster from '$components/molecules/Poster.svelte'
|
||||||
import { debounce } from '$utils/functions'
|
import { debounce } from 'utils/actions'
|
||||||
|
|
||||||
export let posters: any = []
|
export let posters: any = []
|
||||||
|
|
||||||
|
|||||||
@@ -16,21 +16,10 @@ export class Globe {
|
|||||||
this.markers = options.markers || []
|
this.markers = options.markers || []
|
||||||
this.zoom = 1.3075
|
this.zoom = 1.3075
|
||||||
|
|
||||||
// Calculate the current sun position from a given location
|
// Calculate local time for sun position
|
||||||
// const locations = [
|
const date = new Date()
|
||||||
// {
|
const localHour = date.getHours() + date.getTimezoneOffset() / 60
|
||||||
// lat: -37.840935,
|
this.options.sunAngle = (localHour - 12) / 12
|
||||||
// lng: 144.946457,
|
|
||||||
// tz: 'Australia/Melbourne',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// lat: 48.856614,
|
|
||||||
// lng: 2.3522219,
|
|
||||||
// tz: 'Europe/Paris',
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// const location = locations[1]
|
|
||||||
// const localDate = new Date(new Date().toLocaleString('en-US', { timeZone: location.tz }))
|
|
||||||
|
|
||||||
// Parameters
|
// Parameters
|
||||||
this.params = {
|
this.params = {
|
||||||
@@ -39,7 +28,6 @@ export class Globe {
|
|||||||
enableMarkers: options.enableMarkers,
|
enableMarkers: options.enableMarkers,
|
||||||
enableMarkersLinks: options.enableMarkersLinks,
|
enableMarkersLinks: options.enableMarkersLinks,
|
||||||
sunAngle: options.sunAngle || 0,
|
sunAngle: options.sunAngle || 0,
|
||||||
sunAngleDelta: 1.8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
@@ -121,11 +109,10 @@ export class Globe {
|
|||||||
imgDark.src = this.options.mapFileDark
|
imgDark.src = this.options.mapFileDark
|
||||||
|
|
||||||
// Create light
|
// Create light
|
||||||
const lightD = degToRad(7 * 360 / 24)
|
|
||||||
const sunPosition = new Vec3(
|
const sunPosition = new Vec3(
|
||||||
Math.cos(lightD),
|
Math.cos(this.params.sunAngle),
|
||||||
Math.sin(lightD) * Math.sin(0),
|
Math.sin(this.params.sunAngle) * Math.sin(0),
|
||||||
Math.sin(lightD) * Math.cos(0)
|
Math.sin(this.params.sunAngle) * Math.cos(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create program
|
// Create program
|
||||||
@@ -362,7 +349,7 @@ export type Marker = {
|
|||||||
/**
|
/**
|
||||||
* Detect WebGL support
|
* Detect WebGL support
|
||||||
*/
|
*/
|
||||||
function WebGLSupport () {
|
const WebGLSupport = (): boolean => {
|
||||||
try {
|
try {
|
||||||
const canvas = document.createElement('canvas')
|
const canvas = document.createElement('canvas')
|
||||||
return !!window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))
|
return !!window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))
|
||||||
|
|||||||
@@ -47,9 +47,10 @@ export const createPane = (ctx: any) => {
|
|||||||
title: 'Misc',
|
title: 'Misc',
|
||||||
})
|
})
|
||||||
// Sun position
|
// Sun position
|
||||||
misc.addInput(ctx.params, 'sunAngleDelta', {
|
misc.addInput(ctx.params, 'sunAngle', {
|
||||||
label: 'Sun angle delta',
|
label: 'Sun angle',
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 2 * Math.PI,
|
max: 1,
|
||||||
|
step: 0.01,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
500: {
|
500: {
|
||||||
title: 'Server error',
|
title: 'Server error',
|
||||||
message: "That is embarassing, the problem is on our side.",
|
message: 'That is embarassing, the problem is on our side.',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import type { LayoutServerLoad } from './$types'
|
|||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { fetchSwell } from '$utils/functions/shopServer'
|
import { fetchSwell } from '$utils/functions/shopServer'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async () => {
|
export const load = (async () => {
|
||||||
try {
|
try {
|
||||||
// Get content from API
|
// Get content from API
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import { error } from '@sveltejs/kit'
|
import { error } from '@sveltejs/kit'
|
||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { getRandomItem } from '$utils/functions'
|
import { getRandomItem } from 'utils/array'
|
||||||
import { fetchSwell } from '$utils/functions/shopServer'
|
import { fetchSwell } from '$utils/functions/shopServer'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
// Get content from API
|
// Get content from API
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import type { PageServerLoad } from './$types'
|
|||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { fetchSwell } from '$utils/functions/shopServer'
|
import { fetchSwell } from '$utils/functions/shopServer'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ params, setHeaders }) => {
|
export const load = (async ({ params, setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
// Get content from API
|
// Get content from API
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { getContext } from 'svelte'
|
import { getContext } from 'svelte'
|
||||||
import { getAssetUrlKey } from '$utils/api'
|
import { getAssetUrlKey } from '$utils/api'
|
||||||
import { shopCurrentProductSlug } from '$utils/stores/shop'
|
import { shopCurrentProductSlug } from '$utils/stores/shop'
|
||||||
import { capitalizeFirstLetter } from '$utils/functions'
|
import { capitalizeFirstLetter } from 'utils/string'
|
||||||
// Components
|
// Components
|
||||||
import PageTransition from '$components/PageTransition.svelte'
|
import PageTransition from '$components/PageTransition.svelte'
|
||||||
import Metas from '$components/Metas.svelte'
|
import Metas from '$components/Metas.svelte'
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import type { PageServerLoad } from './$types'
|
|||||||
import { PUBLIC_LIST_AMOUNT } from '$env/static/public'
|
import { PUBLIC_LIST_AMOUNT } from '$env/static/public'
|
||||||
import { fetchAPI, photoFields } from '$utils/api'
|
import { fetchAPI, photoFields } from '$utils/api'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ params, setHeaders }) => {
|
export const load = (async ({ params, setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
const { location: slug } = params
|
const { location: slug } = params
|
||||||
@@ -73,7 +77,7 @@ export const load = (async ({ params, setHeaders }) => {
|
|||||||
const { data: { location: location, photos, total_published, product } } = res
|
const { data: { location: location, photos, total_published, product } } = res
|
||||||
|
|
||||||
if (!location.length || location.length && params.country !== location[0].country.slug) {
|
if (!location.length || location.length && params.country !== location[0].country.slug) {
|
||||||
throw error(404, "This location is not available… yet!")
|
throw error(404, 'This location is not available… yet!')
|
||||||
}
|
}
|
||||||
|
|
||||||
setHeaders({ 'Cache-Control': 'public, max-age=1, stale-while-revalidate=604799' })
|
setHeaders({ 'Cache-Control': 'public, max-age=1, stale-while-revalidate=604799' })
|
||||||
|
|||||||
@@ -219,7 +219,6 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<PageTransition>
|
<PageTransition>
|
||||||
<main class="location-page">
|
<main class="location-page">
|
||||||
<section class="location-page__intro grid" bind:this={introEl}>
|
<section class="location-page__intro grid" bind:this={introEl}>
|
||||||
@@ -302,7 +301,7 @@
|
|||||||
location={location.name}
|
location={location.name}
|
||||||
ratio={width / height}
|
ratio={width / height}
|
||||||
date={date_taken}
|
date={date_taken}
|
||||||
index={(totalPhotos - index < 10) ? '0' : ''}{totalPhotos - index}
|
index="{(totalPhotos - index < 10) ? '0' : ''}{totalPhotos - index}"
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</section>
|
</section>
|
||||||
@@ -312,7 +311,7 @@
|
|||||||
ended={ended}
|
ended={ended}
|
||||||
current={currentPhotosAmount}
|
current={currentPhotosAmount}
|
||||||
total={totalPhotos}
|
total={totalPhotos}
|
||||||
on:click={!ended && loadMorePhotos}
|
on:click={() => !ended && loadMorePhotos()}
|
||||||
>
|
>
|
||||||
{#if !ended}
|
{#if !ended}
|
||||||
<p class="more">See more photos</p>
|
<p class="more">See more photos</p>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ import { error } from '@sveltejs/kit'
|
|||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ params, setHeaders }) => {
|
export const load = (async ({ params, setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
// Get the first photo ID
|
// Get the first photo ID
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
import { getAssetUrlKey } from '$utils/api'
|
import { getAssetUrlKey } from '$utils/api'
|
||||||
import { previousPage } from '$utils/stores'
|
import { previousPage } from '$utils/stores'
|
||||||
import { DELAY } from '$utils/constants'
|
import { DELAY } from '$utils/constants'
|
||||||
import { throttle } from '$utils/functions'
|
import { throttle } from 'utils/actions'
|
||||||
import { swipe } from '$utils/interactions/swipe'
|
import { swipe } from '$utils/interactions/swipe'
|
||||||
// Components
|
// Components
|
||||||
import Metas from '$components/Metas.svelte'
|
import Metas from '$components/Metas.svelte'
|
||||||
@@ -93,10 +93,10 @@
|
|||||||
const handleKeydown = ({ key, defaultPrevented }: KeyboardEvent) => {
|
const handleKeydown = ({ key, defaultPrevented }: KeyboardEvent) => {
|
||||||
if (defaultPrevented) return
|
if (defaultPrevented) return
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'ArrowLeft': goToPrevious(); break;
|
case 'ArrowLeft': goToPrevious(); break
|
||||||
case 'ArrowRight': goToNext(); break;
|
case 'ArrowRight': goToNext(); break
|
||||||
case 'Escape': closeViewer(); break;
|
case 'Escape': closeViewer(); break
|
||||||
default: return;
|
default: return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,15 +105,15 @@
|
|||||||
// Swipe up and down on mobile/small screens
|
// Swipe up and down on mobile/small screens
|
||||||
if (innerWidth < 992) {
|
if (innerWidth < 992) {
|
||||||
switch (detail) {
|
switch (detail) {
|
||||||
case '-y': goToNext(); break;
|
case '-y': goToNext(); break
|
||||||
case 'y': goToPrevious(); break;
|
case 'y': goToPrevious(); break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Swipe left and right on larger screens
|
// Swipe left and right on larger screens
|
||||||
else {
|
else {
|
||||||
switch (detail) {
|
switch (detail) {
|
||||||
case '-x': goToNext(); break;
|
case '-x': goToNext(); break
|
||||||
case 'x': goToPrevious(); break;
|
case 'x': goToPrevious(); break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,7 +320,11 @@
|
|||||||
</ButtonCircle>
|
</ButtonCircle>
|
||||||
|
|
||||||
<div class="photo-page__carousel">
|
<div class="photo-page__carousel">
|
||||||
<div class="photo-page__images" use:swipe on:swipe={handleSwipe} on:tap={toggleFullscreen}>
|
<div class="photo-page__images"
|
||||||
|
use:swipe
|
||||||
|
on:swipe={handleSwipe}
|
||||||
|
on:tap={toggleFullscreen}
|
||||||
|
>
|
||||||
{#each visiblePhotos as { id, image, title }, index (id)}
|
{#each visiblePhotos as { id, image, title }, index (id)}
|
||||||
<div class="photo-page__picture is-{currentIndex === 0 ? index + 1 : index}">
|
<div class="photo-page__picture is-{currentIndex === 0 ? index + 1 : index}">
|
||||||
<Image
|
<Image
|
||||||
@@ -377,7 +381,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if isFullscreen}
|
{#if isFullscreen}
|
||||||
<div class="photo-page__fullscreen" bind:this={fullscreenEl} on:click={toggleFullscreen}
|
<div class="photo-page__fullscreen" bind:this={fullscreenEl}
|
||||||
|
on:click={toggleFullscreen} on:keydown
|
||||||
in:fade={{ easing: quartOut, duration: 1000 }}
|
in:fade={{ easing: quartOut, duration: 1000 }}
|
||||||
out:fade={{ easing: quartOut, duration: 1000, delay: 300 }}
|
out:fade={{ easing: quartOut, duration: 1000, delay: 300 }}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { error } from '@sveltejs/kit'
|
import { error } from '@sveltejs/kit'
|
||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { getRandomItems } from '$utils/functions'
|
import { getRandomItems } from 'utils/array'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -3,15 +3,17 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { navigating, page } from '$app/stores'
|
import { navigating } from '$app/stores'
|
||||||
import { onMount, afterUpdate } from 'svelte'
|
import { onMount, afterUpdate } from 'svelte'
|
||||||
import { quartOut as quartOutSvelte } from 'svelte/easing'
|
import { quartOut as quartOutSvelte } from 'svelte/easing'
|
||||||
import { fade, fly } from 'svelte/transition'
|
import { fade, fly } from 'svelte/transition'
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
import { animate, inView, stagger, timeline } from 'motion'
|
import { animate, inView, stagger, timeline } from 'motion'
|
||||||
import { mailtoClipboard, map } from '$utils/functions'
|
import { mailtoClipboard } from '$utils/functions'
|
||||||
import { getAssetUrlKey } from '$utils/api'
|
import { getAssetUrlKey } from '$utils/api'
|
||||||
import { DELAY } from '$utils/constants'
|
import { DELAY } from '$utils/constants'
|
||||||
|
import { map } from 'utils/math'
|
||||||
|
import { sendEvent } from '$utils/analytics'
|
||||||
import { quartOut } from '$animations/easings'
|
import { quartOut } from '$animations/easings'
|
||||||
// Components
|
// Components
|
||||||
import Metas from '$components/Metas.svelte'
|
import Metas from '$components/Metas.svelte'
|
||||||
@@ -21,7 +23,6 @@
|
|||||||
import AboutGridPhoto from '$components/atoms/AboutGridPhoto.svelte'
|
import AboutGridPhoto from '$components/atoms/AboutGridPhoto.svelte'
|
||||||
import ProcessStep from '$components/molecules/ProcessStep.svelte'
|
import ProcessStep from '$components/molecules/ProcessStep.svelte'
|
||||||
import Banner from '$components/organisms/Banner.svelte'
|
import Banner from '$components/organisms/Banner.svelte'
|
||||||
import { sendEvent } from '$utils/analytics';
|
|
||||||
|
|
||||||
export let data: PageData
|
export let data: PageData
|
||||||
const { about, photos } = data
|
const { about, photos } = data
|
||||||
@@ -223,7 +224,7 @@
|
|||||||
{about.intro_firstphoto_caption}<br>
|
{about.intro_firstphoto_caption}<br>
|
||||||
in
|
in
|
||||||
<a href="/{about.intro_firstlocation.country.slug}/{about.intro_firstlocation.slug}" data-sveltekit-noscroll>
|
<a href="/{about.intro_firstlocation.country.slug}/{about.intro_firstlocation.slug}" data-sveltekit-noscroll>
|
||||||
<img src="{getAssetUrlKey(about.intro_firstlocation.country.flag.id, 'square-small-jpg')}" width="32" height="32" alt="{about.intro_firstlocation.country.flag.title}">
|
<img src={getAssetUrlKey(about.intro_firstlocation.country.flag.id, 'square-small-jpg')} width="32" height="32" alt={about.intro_firstlocation.country.flag.title}>
|
||||||
<span>Naarm Australia (Melbourne)</span>
|
<span>Naarm Australia (Melbourne)</span>
|
||||||
</a>
|
</a>
|
||||||
</figcaption>
|
</figcaption>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ import { error } from '@sveltejs/kit'
|
|||||||
import type { RequestHandler } from './$types'
|
import type { RequestHandler } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const POST = (async ({ request, setHeaders }) => {
|
export const POST = (async ({ request, setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
const body = await request.text()
|
const body = await request.text()
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ import { error } from '@sveltejs/kit'
|
|||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
const res = await fetchAPI(`query {
|
const res = await fetchAPI(`query {
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import type { RequestHandler } from './$types'
|
|||||||
import { fetchSwell } from '$utils/functions/shopServer'
|
import { fetchSwell } from '$utils/functions/shopServer'
|
||||||
import { fetchAPI, getAssetUrlKey } from '$utils/api'
|
import { fetchAPI, getAssetUrlKey } from '$utils/api'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
const gCategories = [
|
const gCategories = [
|
||||||
{
|
{
|
||||||
id: '61851d83cd16416c78a8e5ef',
|
id: '61851d83cd16416c78a8e5ef',
|
||||||
|
|||||||
3
apps/website/src/routes/(site)/locations/+page.server.ts
Normal file
3
apps/website/src/routes/(site)/locations/+page.server.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
import Heading from '$components/molecules/Heading.svelte'
|
import Heading from '$components/molecules/Heading.svelte'
|
||||||
|
|
||||||
const { locations }: any = getContext('global')
|
const { locations }: any = getContext('global')
|
||||||
const text = "Explore the globe to discover unique locations across the world"
|
const text = 'Explore the globe to discover unique locations across the world'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Metas
|
<Metas
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import type { PageServerLoad } from './$types'
|
|||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { PUBLIC_FILTERS_DEFAULT_COUNTRY, PUBLIC_FILTERS_DEFAULT_SORT, PUBLIC_GRID_AMOUNT } from '$env/static/public'
|
import { PUBLIC_FILTERS_DEFAULT_COUNTRY, PUBLIC_FILTERS_DEFAULT_SORT, PUBLIC_GRID_AMOUNT } from '$env/static/public'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ url, setHeaders }) => {
|
export const load = (async ({ url, setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
// Query parameters
|
// Query parameters
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||||
import { stagger, timeline } from 'motion'
|
import { stagger, timeline } from 'motion'
|
||||||
import { DELAY } from '$utils/constants'
|
import { DELAY } from '$utils/constants'
|
||||||
import { map, lerp, throttle } from '$utils/functions'
|
import { map, lerp } from 'utils/math'
|
||||||
|
import { throttle } from 'utils/actions'
|
||||||
import { getAssetUrlKey } from '$utils/api'
|
import { getAssetUrlKey } from '$utils/api'
|
||||||
import { quartOut } from '$animations/easings'
|
import { quartOut } from '$animations/easings'
|
||||||
import { PUBLIC_FILTERS_DEFAULT_COUNTRY, PUBLIC_FILTERS_DEFAULT_SORT, PUBLIC_GRID_INCREMENT } from '$env/static/public'
|
import { PUBLIC_FILTERS_DEFAULT_COUNTRY, PUBLIC_FILTERS_DEFAULT_SORT, PUBLIC_GRID_INCREMENT } from '$env/static/public'
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ import { error } from '@sveltejs/kit'
|
|||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
const res = await fetchAPI(`query {
|
const res = await fetchAPI(`query {
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ import { error } from '@sveltejs/kit'
|
|||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
const res = await fetchAPI(`query {
|
const res = await fetchAPI(`query {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import type { LayoutServerLoad } from './$types'
|
|||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { PUBLIC_PREVIEW_COUNT } from '$env/static/public'
|
import { PUBLIC_PREVIEW_COUNT } from '$env/static/public'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async () => {
|
export const load = (async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import { error } from '@sveltejs/kit'
|
import { error } from '@sveltejs/kit'
|
||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { getRandomItems } from '$utils/functions'
|
import { getRandomItems } from 'utils/array'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { NEWSLETTER_API_TOKEN, NEWSLETTER_LIST_ID } from '$env/static/private'
|
import { NEWSLETTER_API_TOKEN, NEWSLETTER_LIST_ID } from '$env/static/private'
|
||||||
import type { RequestHandler } from './$types'
|
import type { RequestHandler } from './$types'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const POST = (async ({ request, fetch }) => {
|
export const POST = (async ({ request, fetch }) => {
|
||||||
const data: { email: string } = await request.json()
|
const data: { email: string } = await request.json()
|
||||||
const { email } = data
|
const { email } = data
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import { error } from '@sveltejs/kit'
|
|||||||
import type { RequestHandler } from './$types'
|
import type { RequestHandler } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
runtime: 'edge'
|
||||||
|
}
|
||||||
|
|
||||||
export const GET = (async ({ url, setHeaders }) => {
|
export const GET = (async ({ url, setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -15,12 +15,11 @@ const cached = build.concat(files);
|
|||||||
.then(cache => cache.addAll(cached))
|
.then(cache => cache.addAll(cached))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// if you use typescript:
|
// if you use typescript:
|
||||||
(self as unknown as ServiceWorkerGlobalScope).skipWaiting();
|
(self as unknown as ServiceWorkerGlobalScope).skipWaiting()
|
||||||
// self.skipWaiting();
|
// self.skipWaiting();
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// self.addEventListener(
|
// self.addEventListener(
|
||||||
// if you use typescript:
|
// if you use typescript:
|
||||||
@@ -38,7 +37,7 @@ const cached = build.concat(files);
|
|||||||
(self as unknown as ServiceWorkerGlobalScope).clients.claim()
|
(self as unknown as ServiceWorkerGlobalScope).clients.claim()
|
||||||
// self.clients.claim()
|
// self.clients.claim()
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -110,5 +109,4 @@ async function fetchAndCache(request: Request) {
|
|||||||
return cachedAsset || fetchAndCache(event.request)
|
return cachedAsset || fetchAndCache(event.request)
|
||||||
})()
|
})()
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,150 +1,6 @@
|
|||||||
import { sendEvent } from '$utils/analytics'
|
import { sendEvent } from '$utils/analytics'
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debounce a function with a given amount of time
|
|
||||||
* @description For scrolling or other resource demanding behaviors
|
|
||||||
*/
|
|
||||||
export const debounce = (callback: (...args: any[]) => any, wait: number, immediate = false) => {
|
|
||||||
let timeout: ReturnType<typeof setTimeout> | number = 0
|
|
||||||
return (...args: any[]) => {
|
|
||||||
const callNow: boolean = immediate && !timeout
|
|
||||||
const next = () => callback(...args)
|
|
||||||
clearTimeout(timeout)
|
|
||||||
timeout = setTimeout(next, wait)
|
|
||||||
if (callNow) next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throttle a function by a given amount of time
|
|
||||||
* @description Throttling enforces a maximum number of times a function can be called over time, as in 'execute this function at most once every 100 milliseconds
|
|
||||||
*/
|
|
||||||
export const throttle = (fn: (...args: any[]) => any, delay: number) => {
|
|
||||||
let lastCall = 0
|
|
||||||
return (...args: unknown[]) => {
|
|
||||||
const now = performance.now()
|
|
||||||
if (now - lastCall < delay) return
|
|
||||||
lastCall = now
|
|
||||||
requestAnimationFrame(() => fn(...args))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Split text
|
|
||||||
* @description Split a string into words or characters
|
|
||||||
* @returns string[]
|
|
||||||
*/
|
|
||||||
export const splitText = (text: string, mode = 'words'): string[] => {
|
|
||||||
// Split by words
|
|
||||||
if (mode === 'words') {
|
|
||||||
const words = text
|
|
||||||
.replace(/\\n/g, '\n')
|
|
||||||
.replace(/\s+/g, m => m.includes('\n') ? '\n ' : ' ')
|
|
||||||
.trim()
|
|
||||||
.split(' ')
|
|
||||||
|
|
||||||
return words
|
|
||||||
}
|
|
||||||
// Split by chars
|
|
||||||
else if (mode === 'chars') {
|
|
||||||
const chars = Array.from(text).map(char => char === ' ' ? '\xa0' : char)
|
|
||||||
return chars
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Capitalize first letter
|
|
||||||
*/
|
|
||||||
export const capitalizeFirstLetter = (string: string) => {
|
|
||||||
return string[0].toUpperCase() + string.slice(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a delay
|
|
||||||
*/
|
|
||||||
export const sleep = (milliseconds: number) => {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, milliseconds))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Linear Interpolation
|
|
||||||
*/
|
|
||||||
export const lerp = (start: number, end: number, amount: number): number => {
|
|
||||||
return (1 - amount) * start + amount * end
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-maps a number from one range to another
|
|
||||||
* @param value the incoming value to be converted
|
|
||||||
* @param start1 lower bound of the value's current range
|
|
||||||
* @param stop1 upper bound of the value's current range
|
|
||||||
* @param start2 lower bound of the value's target range
|
|
||||||
* @param stop2 upper bound of the value's target range
|
|
||||||
* @param [withinBounds] constrain the value to the newly mapped range
|
|
||||||
* @return remapped number
|
|
||||||
*/
|
|
||||||
export const map = (n: number, start1: number, stop1: number, start2: number, stop2: number, withinBounds: boolean): number => {
|
|
||||||
const value = (n - start1) / (stop1 - start1) * (stop2 - start2) + start2
|
|
||||||
if (!withinBounds) return value
|
|
||||||
if (start2 < stop2) {
|
|
||||||
return clamp(value, start2, stop2)
|
|
||||||
} else {
|
|
||||||
return clamp(value, stop2, start2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clamp a number
|
|
||||||
*/
|
|
||||||
export const clamp = (num: number, a: number, b: number) => {
|
|
||||||
return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return random elements from an array
|
|
||||||
*/
|
|
||||||
export const getRandomItems = <T> (array: T[], amount: number): T[] => {
|
|
||||||
const shuffled = array.slice()
|
|
||||||
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
||||||
const j = Math.floor(Math.random() * (i + 1));
|
|
||||||
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
|
|
||||||
}
|
|
||||||
return shuffled.slice(0, amount)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a random element from an array
|
|
||||||
*/
|
|
||||||
export const getRandomItem = <T extends Array<unknown>> (array: T): T[0] => {
|
|
||||||
return getRandomItems(array, 1)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll back to top after page transition
|
|
||||||
*/
|
|
||||||
export const scrollToTop = (delay?: number) => {
|
|
||||||
const scroll = () => window.scrollTo(0,0)
|
|
||||||
|
|
||||||
if (delay && delay > 0) {
|
|
||||||
setTimeout(scroll, delay)
|
|
||||||
} else {
|
|
||||||
return scroll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy mailto links to clipboard and show message
|
* Copy mailto links to clipboard and show message
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const config = {
|
|||||||
|
|
||||||
kit: {
|
kit: {
|
||||||
adapter: adapter({
|
adapter: adapter({
|
||||||
// edge: true,
|
edge: true,
|
||||||
}),
|
}),
|
||||||
alias: {
|
alias: {
|
||||||
$components: 'src/components',
|
$components: 'src/components',
|
||||||
|
|||||||
@@ -11,5 +11,6 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
// "strict": true
|
// "strict": true
|
||||||
}
|
},
|
||||||
|
"exclude": [],
|
||||||
}
|
}
|
||||||
|
|||||||
11
package.json
11
package.json
@@ -1,9 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "housesof",
|
"name": "housesof",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/*"
|
"apps/*",
|
||||||
|
"packages/*"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "turbo run dev --parallel",
|
"dev": "turbo run dev --parallel",
|
||||||
@@ -11,12 +12,12 @@
|
|||||||
"lint": "turbo run lint"
|
"lint": "turbo run lint"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^2.8.3",
|
"prettier": "^2.8.4",
|
||||||
"turbo": "^1.7.1"
|
"turbo": "^1.7.4"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0"
|
"node": ">=16.0.0"
|
||||||
},
|
},
|
||||||
"packageManager": "^pnpm@7.0.0"
|
"packageManager": "^pnpm@7.27.0"
|
||||||
}
|
}
|
||||||
78
packages/config/eslintrc.config.cjs
Normal file
78
packages/config/eslintrc.config.cjs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/** @type {import('eslint').Linter.Config} */
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2017: true,
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
project: './*/tsconfig.json',
|
||||||
|
extraFileExtensions: ['.svelte']
|
||||||
|
},
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
plugins: [
|
||||||
|
'@typescript-eslint'
|
||||||
|
],
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:svelte/recommended',
|
||||||
|
],
|
||||||
|
ignorePatterns: [
|
||||||
|
'*.d.ts',
|
||||||
|
'**/build/**', '**/node_modules/**', '**/.svelte-kit/**', '**/dist/**'
|
||||||
|
],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
'files': ['*.svelte'],
|
||||||
|
'parser': 'svelte-eslint-parser',
|
||||||
|
'parserOptions': {
|
||||||
|
'parser': '@typescript-eslint/parser'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
/* Javascript / Typescript
|
||||||
|
========================================= */
|
||||||
|
// Use spaces over tabs
|
||||||
|
'no-tabs': 'error',
|
||||||
|
indent: ['error', 4, { SwitchCase: 1 }],
|
||||||
|
// Use single quote in javascript
|
||||||
|
quotes: ['error', 'single', {
|
||||||
|
avoidEscape: true,
|
||||||
|
allowTemplateLiterals: true
|
||||||
|
}],
|
||||||
|
// Avoid semicolons
|
||||||
|
semi: ['error', 'never'],
|
||||||
|
// Avoid ==
|
||||||
|
eqeqeq: 'error',
|
||||||
|
// Avoid trailing spaces
|
||||||
|
'no-trailing-spaces': ['error', { skipBlankLines: true }],
|
||||||
|
// Add a space between curlies
|
||||||
|
'object-curly-spacing': ['error', 'always'],
|
||||||
|
// Require a line at end of file
|
||||||
|
'eol-last': ['error', 'always'],
|
||||||
|
// Allow ts exceptions
|
||||||
|
'@typescript-eslint/ban-ts-comment': ['error', {
|
||||||
|
'ts-ignore': false,
|
||||||
|
'ts-nocheck': false,
|
||||||
|
'ts-expect-error': 'allow-with-description',
|
||||||
|
}],
|
||||||
|
|
||||||
|
/* Svelte
|
||||||
|
========================================= */
|
||||||
|
// Use double quotes
|
||||||
|
'svelte/html-quotes': ['error', {
|
||||||
|
prefer: 'double',
|
||||||
|
dynamic: {
|
||||||
|
quoted: false,
|
||||||
|
avoidInvalidUnquotedInHTML: false,
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
},
|
||||||
|
}
|
||||||
5
packages/config/package.json
Normal file
5
packages/config/package.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "config",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true
|
||||||
|
}
|
||||||
29
packages/utils/actions.ts
Normal file
29
packages/utils/actions.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Debounce a function with a given amount of time
|
||||||
|
* @description For scrolling or other resource demanding behaviors
|
||||||
|
*/
|
||||||
|
export const debounce = (callback: (...args: any[]) => any, wait: number, immediate = false) => {
|
||||||
|
let timeout: ReturnType<typeof setTimeout> | number = 0
|
||||||
|
return (...args: any[]) => {
|
||||||
|
const callNow: boolean = immediate && !timeout
|
||||||
|
const next = () => callback(...args)
|
||||||
|
clearTimeout(timeout)
|
||||||
|
timeout = setTimeout(next, wait)
|
||||||
|
if (callNow) next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throttle a function by a given amount of time
|
||||||
|
* @description Throttling enforces a maximum number of times a function can be called over time, as in 'execute this function at most once every 100 milliseconds
|
||||||
|
*/
|
||||||
|
export const throttle = (fn: (...args: any[]) => any, delay: number) => {
|
||||||
|
let lastCall = 0
|
||||||
|
return (...args: unknown[]) => {
|
||||||
|
const now = performance.now()
|
||||||
|
if (now - lastCall < delay) return
|
||||||
|
lastCall = now
|
||||||
|
requestAnimationFrame(() => fn(...args))
|
||||||
|
}
|
||||||
|
}
|
||||||
19
packages/utils/array.ts
Normal file
19
packages/utils/array.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Return random elements from an array
|
||||||
|
*/
|
||||||
|
export const getRandomItems = <T> (array: T[], amount: number): T[] => {
|
||||||
|
const shuffled = array.slice()
|
||||||
|
for (let i = shuffled.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
|
||||||
|
}
|
||||||
|
return shuffled.slice(0, amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a random element from an array
|
||||||
|
*/
|
||||||
|
export const getRandomItem = <T extends Array<unknown>> (array: T): T[0] => {
|
||||||
|
return getRandomItems(array, 1)[0]
|
||||||
|
}
|
||||||
17
packages/utils/index.ts
Normal file
17
packages/utils/index.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Create a delay
|
||||||
|
*/
|
||||||
|
export const sleep = (milliseconds: number) => {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, milliseconds))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an object is empty
|
||||||
|
*/
|
||||||
|
export const isEmpty = (obj: Object) => {
|
||||||
|
if (obj === null || obj === undefined) {
|
||||||
|
throw new Error('Error: Given object is not an object')
|
||||||
|
}
|
||||||
|
return Object.keys(obj).length === 0 && obj.constructor === Object
|
||||||
|
}
|
||||||
35
packages/utils/math.ts
Normal file
35
packages/utils/math.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Linear Interpolation
|
||||||
|
*/
|
||||||
|
export const lerp = (start: number, end: number, amount: number): number => {
|
||||||
|
return (1 - amount) * start + amount * end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamp a number
|
||||||
|
*/
|
||||||
|
export const clamp = (num: number, a: number, b: number) => {
|
||||||
|
return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-maps a number from one range to another
|
||||||
|
* @param value the incoming value to be converted
|
||||||
|
* @param start1 lower bound of the value's current range
|
||||||
|
* @param stop1 upper bound of the value's current range
|
||||||
|
* @param start2 lower bound of the value's target range
|
||||||
|
* @param stop2 upper bound of the value's target range
|
||||||
|
* @param [withinBounds] constrain the value to the newly mapped range
|
||||||
|
* @return remapped number
|
||||||
|
*/
|
||||||
|
export const map = (n: number, start1: number, stop1: number, start2: number, stop2: number, withinBounds: boolean): number => {
|
||||||
|
const value = (n - start1) / (stop1 - start1) * (stop2 - start2) + start2
|
||||||
|
if (!withinBounds) return value
|
||||||
|
if (start2 < stop2) {
|
||||||
|
return clamp(value, start2, stop2)
|
||||||
|
} else {
|
||||||
|
return clamp(value, stop2, start2)
|
||||||
|
}
|
||||||
|
}
|
||||||
6
packages/utils/package.json
Normal file
6
packages/utils/package.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "utils",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"module": "index.ts"
|
||||||
|
}
|
||||||
12
packages/utils/scroll.ts
Normal file
12
packages/utils/scroll.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Scroll back to top after page transition
|
||||||
|
*/
|
||||||
|
export const scrollToTop = (delay?: number) => {
|
||||||
|
const scroll = () => window.scrollTo(0,0)
|
||||||
|
|
||||||
|
if (delay && delay > 0) {
|
||||||
|
return setTimeout(scroll, delay)
|
||||||
|
} else {
|
||||||
|
return scroll()
|
||||||
|
}
|
||||||
|
}
|
||||||
6
packages/utils/string.ts
Normal file
6
packages/utils/string.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Capitalize first letter
|
||||||
|
*/
|
||||||
|
export const capitalizeFirstLetter = (string: string) => {
|
||||||
|
return string[0].toUpperCase() + string.slice(1)
|
||||||
|
}
|
||||||
24
packages/utils/text.ts
Normal file
24
packages/utils/text.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Split text
|
||||||
|
* @description Split a string into words or characters
|
||||||
|
* @returns string[]
|
||||||
|
*/
|
||||||
|
export const splitText = (text: string, mode = 'words'): string[] => {
|
||||||
|
// Split by words
|
||||||
|
if (mode === 'words') {
|
||||||
|
const words = text
|
||||||
|
.replace(/\\n/g, '\n')
|
||||||
|
.replace(/\s+/g, m => m.includes('\n') ? '\n ' : ' ')
|
||||||
|
.trim()
|
||||||
|
.split(' ')
|
||||||
|
|
||||||
|
return words
|
||||||
|
}
|
||||||
|
// Split by chars
|
||||||
|
else if (mode === 'chars') {
|
||||||
|
const chars = Array.from(text).map(char => char === ' ' ? '\xa0' : char)
|
||||||
|
return chars
|
||||||
|
}
|
||||||
|
|
||||||
|
return []
|
||||||
|
}
|
||||||
737
pnpm-lock.yaml
generated
737
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,3 @@
|
|||||||
packages:
|
packages:
|
||||||
- "apps/*"
|
- "apps/*"
|
||||||
|
- "packages/*"
|
||||||
|
|||||||
Reference in New Issue
Block a user