Skip to content

Commit

Permalink
opt: images API
Browse files Browse the repository at this point in the history
  • Loading branch information
Valexr committed Apr 14, 2024
1 parent 1f3b4f3 commit c876d8a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 65 deletions.
16 changes: 4 additions & 12 deletions src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" context="module">
import { date, time, start, quote } from "$lib/data";
import { getPhotos } from "$lib/images";
import { images } from "$lib/images";
import DateInput from "$lib/components/DateInput.svelte";
import County from "$lib/components/County.svelte";
Expand All @@ -10,21 +10,13 @@
<script lang="ts">
export let name: Name;
export let repository: Repository;
async function setBack() {
const images = await getPhotos(1, {});
document.body.style.cssText = `
background: url(${images?.[0].src}) center no-repeat;
background-size: cover;
`;
}
</script>

<svelte:head>
<title>{name}</title>
</svelte:head>

{#await setBack() then}
{#await images.back() then}
<header>
{#if $start}
<DateInput bind:value={$start} />
Expand All @@ -42,13 +34,13 @@
{/if}
{#await quote.load() then}
{#if $quote}
<Quote quote={$quote} />
<Quote quote={$quote} href={repository} />
{/if}
{/await}
</main>

<footer>
<button on:click={setBack}>Image</button>
<button on:click={images.back}>Image</button>
<h2>{$time}</h2>
<button on:click={quote.load}>Quote</button>
</footer>
Expand Down
5 changes: 3 additions & 2 deletions src/lib/components/Quote.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
content: "",
author: "",
};
export let href = "";
</script>

<blockquote>
<p>{quote.content}</p>
<cite>~ {quote.author}</cite>
<a {href}>~ {quote.author}</a>
</blockquote>

<style>
blockquote p {
font-style: italic;
}
blockquote cite {
blockquote a {
font-style: normal;
}
</style>
113 changes: 62 additions & 51 deletions src/lib/images.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,4 @@
export async function getPhotos(limit = 5, {
width = window.innerWidth,
height = window.innerHeight,
}) {
try {
return await getImages(limit, { width, height });
} catch (error) {
console.error(`Could not fetch photos: ${error}`);
}
};

async function getImages(
limit: number = 9,
size = { width: window.innerWidth, height: window.innerHeight }
): Promise<Slide[]> {
const url = 'https://valexr.github.io/county/assets/photos.json';
const indexes = Array.from({ length: limit }, () => Math.floor(Math.random() * 24644));
const res = await fetch(url);
const photos = await res.json();

return photos.reduce(
(acc: ImageSchema[], [src, aspectRatio, author]: [string, number, string], id: number) => {
if (indexes.includes(id)) {
const source = { width: size.height * (aspectRatio / 10), height: size.height };
const max = { width: size.width, height: size.height };
const query = `?w=${ratio(applyRatio(source, max).width)}`;

acc.push({
id,
src: `https://images.unsplash.com/photo-${src}${query}`,
alt: `Image by ${author} from Unsplash`,
...applyRatio(source, max),
});
}
return acc;
},
[]
);

function ratio(size: number) {
return size * devicePixelRatio;
}

function applyRatio(src: Size, size: Size): Size {
const ratio = Math.min(size.width / src.width, size.height, src.height);
return {
width: Math.round(src.width * ratio),
height: Math.round(src.height * ratio),
};
};
}
import { cacheable } from "./cacheable";

type Size = {
width: number;
Expand All @@ -70,4 +20,65 @@ type Slide = {
width?: string | number;
height?: string | number;
[key: string]: unknown;
}

export const images = createImages()

function createImages() {
type API = [string, number, string]
const { subscribe, get, set, update } = cacheable<Array<API>>('imagesJSON', [], true)

async function load() {
if (!get().length) {
const url = 'https://valexr.github.io/county/assets/photos.json';
const res = await fetch(url);
set(await res.json());
}
}

function prepare(limit = 1, size = { width: window.innerWidth, height: window.innerHeight }) {
const indexes = Array.from({ length: limit }, () => Math.floor(Math.random() * 24644));
return get().reduce(
(acc: ImageSchema[], [src, aspectRatio, author], id) => {
if (indexes.includes(id)) {
const source = { width: size.height * (aspectRatio / 10), height: size.height };
const max = { width: size.width, height: size.height };
const query = `?w=${ratio(applyRatio(source, max).width)}`;

acc.push({
id,
src: `https://images.unsplash.com/photo-${src}${query}`,
alt: `Image by ${author} from Unsplash`,
...applyRatio(source, max),
});
}
return acc;
},
[]
);

function ratio(size: number) {
return size * devicePixelRatio;
}

function applyRatio(src: Size, size: Size): Size {
const ratio = Math.min(size.width / src.width, size.height, src.height);
return {
width: Math.round(src.width * ratio),
height: Math.round(src.height * ratio),
};
};
}

return {
subscribe, set, update, load, prepare,
async back() {
await load();
const [{ src }] = prepare();
document.body.style.cssText = `
background: url(${src}) center no-repeat;
background-size: cover;
`;
}
}
}

0 comments on commit c876d8a

Please sign in to comment.