Skip to content

Commit 8fcd870

Browse files
committed
Allow passing of size to album-art for smaller images
1 parent 52e9680 commit 8fcd870

File tree

3 files changed

+71
-22
lines changed

3 files changed

+71
-22
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"lucide-react": "^0.485.0",
3030
"next": "15.2.4",
3131
"next-redux-wrapper": "8.1.0",
32+
"next-zod-route": "^0.2.5",
3233
"nextjs-toploader": "^3.7.15",
3334
"node-device-detector": "^2.1.0",
3435
"react": "19.0.0",
@@ -38,7 +39,8 @@
3839
"redux": "^4.2.1",
3940
"tailwind-merge": "^2.3.0",
4041
"thenby": "^1.3.4",
41-
"ua-parser-js": "^1.0.37"
42+
"ua-parser-js": "^1.0.37",
43+
"zod": "^3.24.2"
4244
},
4345
"devDependencies": {
4446
"@switz/eslint-config": "^11.0.0",

pnpm-lock.yaml

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/album-art/route.tsx

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { fetchArtists, fetchShowByUUID } from '@/app/queries';
55
import { ImageResponse } from 'next/og';
66
import { NextRequest } from 'next/server';
77
import { notFound } from 'next/navigation';
8+
import { createZodRoute } from 'next-zod-route';
9+
import { z } from 'zod';
810

911
export const runtime = 'edge';
1012

@@ -75,9 +77,9 @@ const getArtistGradient = (uuid: string) => {
7577
return gradientString;
7678
};
7779

78-
const generatePixelatedSVG = (opacity = 0.4) => {
79-
// Create a pixelated pattern with large squares
80-
const squareSize = 45; // Size of each pixel square
80+
// Create a pixelated pattern with large squares
81+
const generatePixelatedSVG = (opacity = 0.4, size: number) => {
82+
const squareSize = (size / 1024) * 45; // Size of each pixel square
8183
const gridSize = 10; // Number of squares in each row/column
8284
const borderWidth = 1; // Reduced width of the border between pixels
8385
const borderColor = 'rgba(0, 0, 0, 0.1)'; // More transparent black for subtler borders
@@ -108,16 +110,19 @@ const generatePixelatedSVG = (opacity = 0.4) => {
108110
return `url("data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}")`;
109111
};
110112

111-
export async function GET(request: NextRequest) {
112-
try {
113-
const { searchParams } = new URL(request.url);
113+
const querySchema = z.object({
114+
showUuid: z.string().uuid(),
115+
size: z.coerce.number().gte(256).lte(1024).default(1024),
116+
});
114117

115-
const showUuid = searchParams.get('showUuid');
116-
if (!showUuid) return notFound();
118+
export const GET = createZodRoute()
119+
.query(querySchema)
120+
.handler(async (request, context) => {
121+
if (!context.query.showUuid) return notFound();
117122

118123
const [artists, show, fontReg, fontBold, fontMegaBold] = await Promise.all([
119124
fetchArtists(),
120-
fetchShowByUUID(showUuid),
125+
fetchShowByUUID(context.query.showUuid),
121126
fetch(
122127
new URL('https://cdn.jsdelivr.net/fontsource/fonts/roboto@latest/latin-400-normal.ttf'),
123128
{ next: { revalidate: 60 * 60 * 24 * 30 } } // Cache for 30 days
@@ -141,7 +146,8 @@ export async function GET(request: NextRequest) {
141146
// Generate dynamic background color and pattern based on artist UUID
142147
const bgGradient = getArtistGradient(show.artist_uuid || '');
143148
// Generate pixelated background pattern
144-
const pixelatedSVG = generatePixelatedSVG(0.8);
149+
const size = context.query.size;
150+
const pixelatedSVG = generatePixelatedSVG(0.8, size);
145151

146152
return new ImageResponse(
147153
(
@@ -153,23 +159,49 @@ export async function GET(request: NextRequest) {
153159
}}
154160
>
155161
<div tw="flex w-full max-w-[800px] flex-col items-center justify-center rounded-2xl bg-black/25 p-12 relative">
156-
<div tw="mb-2 text-center text-7xl font-extrabold tracking-tight">{artistName}</div>
157-
<div tw="mb-2 text-center text-6xl font-bold">{show.display_date}</div>
162+
<div
163+
tw="mb-2 text-center font-extrabold tracking-tight"
164+
style={{
165+
fontSize: (size / 1024) * 72,
166+
}}
167+
>
168+
{artistName}
169+
</div>
170+
<div
171+
tw="mb-2 text-center font-bold"
172+
style={{
173+
fontSize: (size / 1024) * 60,
174+
}}
175+
>
176+
{show.display_date}
177+
</div>
158178
<div tw="flex items-center justify-center" style={{ gap: 8 }}>
159179
{show.venue?.name && (
160-
<div tw="rounded-xl bg-white/20 px-6 py-3 text-4xl flex text-center">
180+
<div
181+
tw="rounded-xl bg-white/20 px-6 py-3 flex text-center"
182+
style={{
183+
fontSize: (size / 1024) * 36,
184+
}}
185+
>
161186
{show.venue?.name} {show.venue?.location ? `• ${show.venue.location}` : ''}
162187
</div>
163188
)}
164189
</div>
165190
</div>
166191

167-
<div tw="absolute bottom-6 right-6 text-4xl font-bold">Relisten.net</div>
192+
<div
193+
tw="absolute bottom-6 right-6 font-bold"
194+
style={{
195+
fontSize: (size / 1024) * 36,
196+
}}
197+
>
198+
Relisten.net
199+
</div>
168200
</div>
169201
),
170202
{
171-
width: 1024,
172-
height: 1024,
203+
width: size,
204+
height: size,
173205
fonts: [
174206
{
175207
name: 'Roboto',
@@ -192,8 +224,4 @@ export async function GET(request: NextRequest) {
192224
],
193225
}
194226
);
195-
} catch (error) {
196-
console.error('Error generating album art:', error);
197-
return new Response('Error generating album art', { status: 500 });
198-
}
199-
}
227+
});

0 commit comments

Comments
 (0)