mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-25 11:04:00 +00:00
Improve OG images
This commit is contained in:
parent
c434225c56
commit
e08ebdd21b
4 changed files with 103 additions and 104 deletions
|
|
@ -1,5 +0,0 @@
|
|||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||
|
||||
export default function handler(req, res) {
|
||||
res.status(200).json({ name: 'John Doe' })
|
||||
}
|
||||
|
|
@ -1,42 +1,28 @@
|
|||
import { ImageResponse } from "@vercel/og";
|
||||
import Frame from "../../src/og/Frame";
|
||||
import { fetchGraphql, stripExt } from "../../src/og/ogUtils";
|
||||
|
||||
export const config = {
|
||||
runtime: "experimental-edge",
|
||||
};
|
||||
|
||||
async function fetchGraphql(query, variables) {
|
||||
const response = await fetch("https://api.webampskins.org/graphql", {
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
"content-type": "application/json",
|
||||
},
|
||||
referrer: "https://skins.webamp.org/",
|
||||
referrerPolicy: "strict-origin-when-cross-origin",
|
||||
body: JSON.stringify({ query, variables }),
|
||||
method: "POST",
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch skin info");
|
||||
}
|
||||
const json = await response.json();
|
||||
const { data } = json;
|
||||
return data;
|
||||
}
|
||||
|
||||
function stripExt(filename) {
|
||||
return filename.replace(/\.[^/.]+$/, "");
|
||||
}
|
||||
|
||||
export const SCREENSHOT_WIDTH = 275;
|
||||
export const SCREENSHOT_HEIGHT = 348;
|
||||
|
||||
const QUERY = `
|
||||
query Skin($md5: String!) {
|
||||
skin: fetch_skin_by_md5(md5: $md5) {
|
||||
filename
|
||||
screenshot_url
|
||||
}
|
||||
}`;
|
||||
const aspectRatio = SCREENSHOT_WIDTH / SCREENSHOT_HEIGHT;
|
||||
|
||||
export default async function (req) {
|
||||
const { searchParams } = req.nextUrl;
|
||||
const skinMd5 = searchParams.get("md5");
|
||||
const query = searchParams.get("query");
|
||||
if (query) {
|
||||
return searchImage(query);
|
||||
}
|
||||
if (skinMd5) {
|
||||
return permalinkImage(skinMd5);
|
||||
}
|
||||
throw new Error("Expected skin md5 or query");
|
||||
}
|
||||
|
||||
async function searchImage(query) {
|
||||
const data = await fetchGraphql(
|
||||
|
|
@ -52,7 +38,6 @@ async function searchImage(query) {
|
|||
}`,
|
||||
{ query }
|
||||
);
|
||||
const aspectRatio = SCREENSHOT_WIDTH / SCREENSHOT_HEIGHT;
|
||||
return new ImageResponse(
|
||||
(
|
||||
<Frame>
|
||||
|
|
@ -111,19 +96,18 @@ async function searchImage(query) {
|
|||
);
|
||||
}
|
||||
|
||||
export default async function (req) {
|
||||
const { searchParams } = req.nextUrl;
|
||||
const skinMd5 = searchParams.get("md5");
|
||||
const query = searchParams.get("query");
|
||||
if (query) {
|
||||
return searchImage(query);
|
||||
}
|
||||
if (skinMd5 == null) {
|
||||
throw new Error("Expected skin md5");
|
||||
}
|
||||
const data = await fetchGraphql(QUERY, { md5: skinMd5 });
|
||||
const aspectRatio = SCREENSHOT_WIDTH / SCREENSHOT_HEIGHT;
|
||||
const FOO = 900;
|
||||
async function permalinkImage(skinMd5) {
|
||||
const data = await fetchGraphql(
|
||||
`
|
||||
query Skin($md5: String!) {
|
||||
skin: fetch_skin_by_md5(md5: $md5) {
|
||||
filename
|
||||
screenshot_url
|
||||
}
|
||||
}`,
|
||||
{ md5: skinMd5 }
|
||||
);
|
||||
const size = 900;
|
||||
return new ImageResponse(
|
||||
(
|
||||
<Frame>
|
||||
|
|
@ -139,12 +123,12 @@ export default async function (req) {
|
|||
>
|
||||
<div style={{ display: "flex", marginTop: "40" }}>
|
||||
<div
|
||||
style={{ display: "flex", height: FOO / 3, overflow: "hidden" }}
|
||||
style={{ display: "flex", height: size / 3, overflow: "hidden" }}
|
||||
>
|
||||
<img
|
||||
src={data.skin.screenshot_url}
|
||||
height={String(FOO)}
|
||||
width={String(FOO * aspectRatio)}
|
||||
height={String(size)}
|
||||
width={String(size * aspectRatio)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -171,8 +155,8 @@ export default async function (req) {
|
|||
>
|
||||
<img
|
||||
src={data.skin.screenshot_url}
|
||||
height={String(FOO / 2)}
|
||||
width={String((FOO / 2) * aspectRatio)}
|
||||
height={String(size / 2)}
|
||||
width={String((size / 2) * aspectRatio)}
|
||||
/>
|
||||
</div>
|
||||
</Frame>
|
||||
|
|
@ -183,53 +167,3 @@ export default async function (req) {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
function Frame({ children }) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background: "black",
|
||||
color: "white",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
textAlign: "center",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
justifyContent: "space-between",
|
||||
background: "linear-gradient(45deg,#000,#191927 66%,#000)",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
justifyItems: "center",
|
||||
width: "100%",
|
||||
flexGrow: 10,
|
||||
// border: "1px solid red",
|
||||
alignItems: "stretch",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 20,
|
||||
background: "linear-gradient(90deg,#111119,#282742 66%,#191927)",
|
||||
color: "white",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
padding: "20px 30px",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<div>Winamp Skin Museum</div>
|
||||
<div>skins.webamp.org</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
48
packages/skin-museum-og/src/og/Frame.js
Normal file
48
packages/skin-museum-og/src/og/Frame.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
export default function Frame({ children }) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background: "black",
|
||||
color: "white",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
textAlign: "center",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
justifyContent: "space-between",
|
||||
background: "linear-gradient(45deg,#000,#191927 66%,#000)",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
justifyItems: "center",
|
||||
width: "100%",
|
||||
flexGrow: 10,
|
||||
alignItems: "stretch",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 20,
|
||||
background: "linear-gradient(90deg,#111119,#282742 66%,#191927)",
|
||||
color: "white",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
padding: "20px 30px",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<div>Winamp Skin Museum</div>
|
||||
<div>skins.webamp.org</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
22
packages/skin-museum-og/src/og/ogUtils.js
Normal file
22
packages/skin-museum-og/src/og/ogUtils.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export async function fetchGraphql(query, variables) {
|
||||
const response = await fetch("https://api.webampskins.org/graphql", {
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
"content-type": "application/json",
|
||||
},
|
||||
referrer: "https://skins.webamp.org/",
|
||||
referrerPolicy: "strict-origin-when-cross-origin",
|
||||
body: JSON.stringify({ query, variables }),
|
||||
method: "POST",
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch skin info");
|
||||
}
|
||||
const json = await response.json();
|
||||
const { data } = json;
|
||||
return data;
|
||||
}
|
||||
|
||||
export function stripExt(filename) {
|
||||
return filename.replace(/\.[^/.]+$/, "");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue