diff --git a/README.md b/README.md index 0806427..9ff1b50 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Visual POAP +# POAP Feed demo -This is a simple demo for visualizing POAP mints live using a [Goldsky Subgraphs](https://goldsky.com/products/subgraphs) as the data source. This demo is using the following tools: +This is a [simple demo](https://feed.poap.demo.goldsky.com/) for visualizing a live feed of POAP mints using a [Goldsky Subgraphs](https://goldsky.com/products/subgraphs) as the data source. This demo is using the following tools: - [@download/blockies](https://github.com/download13/blockies#readme) to render the blocky avatars (when an ens avatar is not available) - [napi-rs/canvas](https://github.com/Brooooooklyn/canvas#readme) to render the blocky/ens avatars on a serverside canvas @@ -22,3 +22,7 @@ When posting a link to social media (use the _share_ icon in the header for cach ### Farcaster frames When posting to farcaster, the opengraph image will be a [farcaster frame](https://docs.farcaster.xyz/reference/frames/spec). The initial image is a static image as per the spec, with actions to load dynamic content (e.g., `Refresh latest`). Each time an action is pressed a new image is generated which could represent a whole new POAP token that was minted. + +## Notes on the code + +Svelte was chosen as the language to write this demo in as an opportunity to test out some tooling designed for Svelte. However `frames.js` and `satori` are really designed to be used with React. As such, I would recommend that anyone curious about building a similar web app, or using these same tools should strongly consider React instead of Svelte (and consider using `@vercel/og` instead of `satori`). diff --git a/src/lib/client/constants.ts b/src/lib/client/constants.ts index 0c20aa4..97b41f0 100644 --- a/src/lib/client/constants.ts +++ b/src/lib/client/constants.ts @@ -1 +1,4 @@ export const MaxItems = 10 +export const DevBaseUrl = 'http://localhost:5173' +export const ProdBaseUrl = 'https://feed.poap.demo.goldsky.com/' +export const BaseUrl = import.meta.env.DEV ? DevBaseUrl : ProdBaseUrl diff --git a/src/lib/components/AppFrame/app-frame.svelte b/src/lib/components/AppFrame/app-frame.svelte index 6557060..9f66dc9 100644 --- a/src/lib/components/AppFrame/app-frame.svelte +++ b/src/lib/components/AppFrame/app-frame.svelte @@ -29,7 +29,7 @@ return data function composeTitle(metadata: POAPEventMetadata[] | undefined) { - const title = 'Visual POAP' + const title = 'POAP live feed' if (!metadata || metadata.length === 0) return title if (metadata.length === 1) { return `${title} - #${metadata[0].id} ${metadata[0].name}` diff --git a/src/lib/components/Seo/seo.svelte b/src/lib/components/Seo/seo.svelte index fc091e6..88f2a34 100644 --- a/src/lib/components/Seo/seo.svelte +++ b/src/lib/components/Seo/seo.svelte @@ -1,10 +1,10 @@ diff --git a/src/routes/frame/+server.ts b/src/routes/frame/+server.ts index 3986d33..a78f8a9 100644 --- a/src/routes/frame/+server.ts +++ b/src/routes/frame/+server.ts @@ -1,11 +1,11 @@ import { error } from '@sveltejs/kit' import { getFrameHtml, validateFrameMessage, type FrameActionPayload } from 'frames.js' +import { BaseUrl } from '$lib/client/constants' import type { SeoContext } from '$lib/components/Seo' import { fetchLatestPOAPToken } from '$lib/server/poap' import type { RequestHandler } from './$types' export const POST: RequestHandler = async ({ request, url, fetch }) => { - const baseUrl = import.meta.env.DEV ? 'http://localhost:5173' : 'https://vpoap.vercel.app' const context = JSON.parse(url.searchParams.get('context') || '{}') as SeoContext const action = url.searchParams.get('action') || 'latest' const body = (await request.json()) as FrameActionPayload @@ -24,7 +24,7 @@ export const POST: RequestHandler = async ({ request, url, fetch }) => { action: 'post', }, ], - postUrl: `${baseUrl}/frame${url.search}`, + postUrl: `${BaseUrl}/frame${url.search}`, }) return new Response(html, { @@ -36,8 +36,8 @@ export const POST: RequestHandler = async ({ request, url, fetch }) => { async function imageUrl() { const at = new Date().getTime() - if (context.eventIds) return `${baseUrl}/og/event/${context.eventIds.join(',')}?at=${at}` - if (context.account) return `${baseUrl}/og/account/${context.account}?at=${at}` + if (context.eventIds) return `${BaseUrl}/og/event/${context.eventIds.join(',')}?at=${at}` + if (context.account) return `${BaseUrl}/og/account/${context.account}?at=${at}` const { data, error: tokenError } = await fetchLatestPOAPToken(fetch) @@ -59,6 +59,6 @@ export const POST: RequestHandler = async ({ request, url, fetch }) => { const tokenId = data.tokens[0]?.id if (!tokenId) throw error(404, 'POAP token missing id') - return `${baseUrl}/og/token/${tokenId}?at=${at}` + return `${BaseUrl}/og/token/${tokenId}?at=${at}` } } diff --git a/src/routes/og/token/[id]/og-token.svelte b/src/routes/og/token/[id]/og-token.svelte index 2adb7a2..ea5d1c5 100644 --- a/src/routes/og/token/[id]/og-token.svelte +++ b/src/routes/og/token/[id]/og-token.svelte @@ -95,7 +95,7 @@ style:white-space="nowrap" > {#if isStatic} - Visual POAP Feed + POAP live feed {:else} {metadata.name} {/if}