diff --git a/src/lib/components/Image.svelte b/src/lib/components/Image.svelte index 97102d8..12b3d0f 100644 --- a/src/lib/components/Image.svelte +++ b/src/lib/components/Image.svelte @@ -6,16 +6,22 @@ interface ImageSrc { img: string; + w?: number; + h?: number; webp?: Srcset[]; jpeg?: Srcset[]; png?: Srcset[]; failback: string; alt: string; + placeholder?: string; } export let src: ImageSrc; - export let style: string; + if (src.placeholder) { + style = `${style} background: url(${src.placeholder}) no-repeat center/cover;`; + } + const handleImgError = (e: Event) => { if (e.type !== 'error') { return; @@ -23,12 +29,11 @@ // failback src = { + ...src, img: src.failback, webp: [], jpeg: [], - png: [], - alt: src.alt, - failback: src.failback + png: [] }; }; @@ -43,5 +48,31 @@ {#if src.png} `${s.src} ${s.w}w`).join(', ')} type="image/png" /> {/if} - {src.alt} + {src.alt} + + diff --git a/src/lib/image-utils.ts b/src/lib/image-utils.ts new file mode 100644 index 0000000..954ddd2 --- /dev/null +++ b/src/lib/image-utils.ts @@ -0,0 +1 @@ +// TBD diff --git a/src/lib/index.ts b/src/lib/index.ts index 856f2b6..f08bcd4 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1 +1 @@ -// place files you want to import through the `$lib` alias in this folder. +export * from './image-utils'; diff --git a/src/lib/server/blog-store.service.ts b/src/lib/server/blog-store.service.ts index 524543c..f438b78 100644 --- a/src/lib/server/blog-store.service.ts +++ b/src/lib/server/blog-store.service.ts @@ -35,6 +35,38 @@ export class BlogStoreService { }) })); + // fetch imagePlaceholderUrl + for (const blog of blogs) { + if (blog.image) { + // PoC + // TODO: config + const optimazerPrefix = 'https://nostr-image-optimizer.ocknamo.com/image/'; + + const res = await fetch( + `${optimazerPrefix}width=200,quality=40,format=webp/${blog.image}`, + { headers: { 'User-Agent': 'Mozilla/5.0' } } + ); // dummy user-agent + + console.info(`Requested to: ${res.url}`); + + if (!res.ok) { + console.warn(`${res.status}: ${res.statusText}`); + + continue; + } + + const blob = await res.blob(); + + const buffer = Buffer.from(await blob.arrayBuffer()); + const base64 = buffer.toString('base64'); + + // Base64文字列を使ってData URLsを作成する + const base64DataURL = base64 ? `data:image/webp;base64,${base64}` : undefined; + + Object.assign(blog, { imagePlaceholderUrl: base64DataURL }); + } + } + this.blogs = blogs; console.info('BlogStoreService: end fetch.'); diff --git a/src/lib/types.ts b/src/lib/types.ts index 030d41a..fb5e211 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -4,6 +4,7 @@ export interface Blog extends NostrEventExt { title: string; summary: string; image: string; + imagePlaceholderUrl?: string; hashTags: string[]; identifier: string; naddress: string; diff --git a/src/routes/blog/[slug]/+page.server.ts b/src/routes/blog/[slug]/+page.server.ts index 19bbaf3..fc72904 100644 --- a/src/routes/blog/[slug]/+page.server.ts +++ b/src/routes/blog/[slug]/+page.server.ts @@ -2,7 +2,7 @@ import { error } from '@sveltejs/kit'; import { blogStore } from '$lib/server/blog-store.service'; -export function load({ params }: { params: { slug: string } }) { +export async function load({ params }: { params: { slug: string } }) { const blogs = blogStore.blogs; const blog = blogs.find((b) => b.id === params.slug); diff --git a/src/routes/blog/[slug]/+page.svelte b/src/routes/blog/[slug]/+page.svelte index 2ab91ca..68627c4 100644 --- a/src/routes/blog/[slug]/+page.svelte +++ b/src/routes/blog/[slug]/+page.svelte @@ -6,9 +6,11 @@ export let data; // PoC + // TODO: set from config const optimazerPrefix = 'https://nostr-image-optimizer.ocknamo.com/image/'; let src = { + w: 800, img: `${optimazerPrefix}width=1600,quality=70,format=webp/${data.blog.image}`, webp: [ { src: `${optimazerPrefix}width=1600,quality=50,format=webp/${data.blog.image}`, w: 1600 }, @@ -19,7 +21,8 @@ { src: `${optimazerPrefix}width=800,quality=50,format=jpeg/${data.blog.image}`, w: 800 } ], failback: data.blog.image, - alt: 'blog top' + alt: 'blog top', + placeholder: data.blog.imagePlaceholderUrl };