feat: initial cat page
This commit is contained in:
parent
5b43a36d31
commit
8d02623c8c
7 changed files with 135 additions and 9 deletions
27
src/lib/components/Image.svelte
Normal file
27
src/lib/components/Image.svelte
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { ImageMetadata } from '$lib/utils/types';
|
||||||
|
export let metadata: ImageMetadata[];
|
||||||
|
export let sizes: string;
|
||||||
|
|
||||||
|
const fallback = metadata[metadata.length - 1];
|
||||||
|
const _metadata = metadata.slice(0, metadata.length - 1);
|
||||||
|
|
||||||
|
const srcset = _metadata
|
||||||
|
.map(({ href, width }) => `https://cats.daichendt.one/${href} ${width}w`)
|
||||||
|
.join(',');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if !fallback && !metadata}
|
||||||
|
No metadata supplied
|
||||||
|
{:else}
|
||||||
|
<img {srcset} class="image" alt="A cute kitty" {sizes} loading="lazy" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
22
src/lib/components/blurupplaceholder.svelte
Normal file
22
src/lib/components/blurupplaceholder.svelte
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Thumbnail } from '$lib/utils/types';
|
||||||
|
|
||||||
|
export let thumbnail: Thumbnail;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 {thumbnail.width} {thumbnail.height}">
|
||||||
|
<filter id="blur" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feGaussianBlur stdDeviation="20 20" edgeMode="duplicate" />
|
||||||
|
<feComponentTransfer>
|
||||||
|
<feFuncA type="discrete" tableValues="1 1" />
|
||||||
|
</feComponentTransfer>
|
||||||
|
</filter>
|
||||||
|
<image
|
||||||
|
filter="url(#blur)"
|
||||||
|
xlink:href="data:image/jpeg;base64,{thumbnail.value}"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
height="100%"
|
||||||
|
width="100%"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
@ -15,3 +15,15 @@ export interface Skill {
|
||||||
years: number;
|
years: number;
|
||||||
started: number;
|
started: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ImageMetadata {
|
||||||
|
href: string;
|
||||||
|
mime: string;
|
||||||
|
width: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Thumbnail {
|
||||||
|
value: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}
|
||||||
|
|
|
||||||
17
src/lib/utils/utils.ts
Normal file
17
src/lib/utils/utils.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
export const createLoadObserver = (handler: () => void) => {
|
||||||
|
let waiting = 0;
|
||||||
|
|
||||||
|
const onload = (el) => {
|
||||||
|
waiting++;
|
||||||
|
console.log(waiting);
|
||||||
|
el.addEventListener('load', () => {
|
||||||
|
waiting--;
|
||||||
|
console.log('waiting ' + waiting);
|
||||||
|
if (waiting === 0) {
|
||||||
|
handler();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return onload;
|
||||||
|
};
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
<p>Copyright <Icon path={mdiCopyright} size="1rem" /> {year} Alexander Daichendt</p>
|
<p>Copyright <Icon path={mdiCopyright} size="1rem" /> {year} Alexander Daichendt</p>
|
||||||
|
|
||||||
<div class="footerLinks">
|
<div class="footerLinks">
|
||||||
|
<Link href="/cat">Meeeeeow</Link>
|
||||||
<Link href="/privacy">Privacy Policy</Link>
|
<Link href="/privacy">Privacy Policy</Link>
|
||||||
<Link href="/impressum">Impressum</Link>
|
<Link href="/impressum">Impressum</Link>
|
||||||
<Link href="https://github.com/AlexDaichendt/site">Source</Link>
|
<Link href="https://github.com/AlexDaichendt/site">Source</Link>
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,19 @@
|
||||||
function beamKitty() {
|
function beamKitty() {
|
||||||
importing = true;
|
importing = true;
|
||||||
|
|
||||||
fetch(`https://cats.daichendt.one/import?key=${kittyLink}`, {
|
fetch(`https://cats.daichendt.one/import?url=${kittyLink}&optimize=true`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { 'X-Custom-Auth-Key': import.meta.env.VITE_CATAPI_PASSWD },
|
headers: { 'X-Custom-Auth-Key': import.meta.env.VITE_CATAPI_PASSWD },
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
|
importing = false;
|
||||||
|
|
||||||
if (result.status === 200) {
|
if (result.status === 200) {
|
||||||
kittyLink = '';
|
kittyLink = '';
|
||||||
importing = false;
|
|
||||||
showSuccess = true;
|
showSuccess = true;
|
||||||
setTimeout(() => (showSuccess = false), 5000);
|
setTimeout(() => (showSuccess = false), 5000);
|
||||||
|
} else {
|
||||||
|
// display error
|
||||||
|
console.log(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
export async function load({ fetch }: LoadEvent): LoadOutput {
|
export async function load({ fetch }: LoadEvent): LoadOutput {
|
||||||
const response = await fetch('https://cats.daichendt.one/list');
|
const response = await fetch('https://cats.daichendt.one/list');
|
||||||
const asJson = await response.json();
|
const asJson = await response.json();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: response.status,
|
status: response.status,
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -15,15 +14,59 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let cats: Record<string, string>[];
|
import Image from '$lib/components/Image.svelte';
|
||||||
|
import type { ImageMetadata } from '$lib/utils/types';
|
||||||
|
import Link from '$lib/components/Link.svelte';
|
||||||
|
|
||||||
|
export let cats: { images: ImageMetadata[] }[];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each cats as cat}
|
<section class="masonry">
|
||||||
<img src={`https://cats.daichendt.one/${cat.key}`} alt="cat" />
|
{#each cats as cat}
|
||||||
{/each}
|
<figure>
|
||||||
|
<Link
|
||||||
|
href={`https://cats.daichendt.one/${cat.images[cat.images.length - 1].href}`}
|
||||||
|
disableIcon
|
||||||
|
disablePrefetch
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
metadata={cat.images}
|
||||||
|
sizes="(max-width: 720px) 1px, (max-width: 1280px) 360px, 720px"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</figure>
|
||||||
|
{/each}
|
||||||
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
img {
|
.masonry {
|
||||||
width: 50%;
|
column-count: 3;
|
||||||
|
column-gap: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Masonry on medium-sized screens */
|
||||||
|
@media only screen and (max-width: 800px) and (min-width: 500px) {
|
||||||
|
.masonry {
|
||||||
|
column-count: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Masonry on small screens */
|
||||||
|
@media only screen and (max-width: 500px) and (min-width: 0px) {
|
||||||
|
.masonry {
|
||||||
|
column-count: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.4);
|
||||||
|
margin: 0;
|
||||||
|
background-color: #eee;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 0 1em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
figure:hover {
|
||||||
|
filter: brightness(90%);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue