| author | |
| committer | |
| log | a465df835ca978dd2cd1d1ac7c75daf5a49f350a |
| tree | fcb38f08a2ef1391d952915b05607d39dc2bfffd |
| parent | 898b567540e271981e6be16f337063ba7c9df934 |
| signature | Commit is signed but in an unrecognized format. |
this fixes multiple issues:
- the font files were not avaialble
- the user-agent detection was wrong
- the opengraph object format changed
these all happened with the move to sitegen and not testing things. i
never noticed any of these bugs since i don't use discord much these
days, but i really do like having this feature. now, puppeteer is set to
open against localhost, which loads the exact page experience as normal. 3 files changed, 16 insertions(+), 6 deletions(-)
src/q+a/backend.ts+3| ... | @@ -127,6 +127,9 @@ app.get("/q+a/:id", async (c, next) => { | ... | @@ -127,6 +127,9 @@ app.get("/q+a/:id", async (c, next) => { |
| 127 | if (image) { | 127 | if (image) { |
| 128 | return getQuestionImage(question, c.req.method === "HEAD"); | 128 | return getQuestionImage(question, c.req.method === "HEAD"); |
| 129 | } | 129 | } |
| 130 | if (c.req.header("User-Agent")?.includes("clover-qa-image")) { | ||
| 131 | return view.serve(c, "q+a/image-embed", { question }); | ||
| 132 | } | ||
| 130 | return view.serve(c, "q+a/permalink", { question }); | 133 | return view.serve(c, "q+a/permalink", { question }); |
| 131 | }); | 134 | }); |
| 132 | 135 |
src/q+a/image.tsx+4-3| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | const port = Number(process.env.PORT ?? 3000); | ||
| 1 | const width = 768; | 2 | const width = 768; |
| 2 | const cacheImageDir = path.resolve(".clover/question_images"); | 3 | const cacheImageDir = path.resolve(".clover/question_images"); |
| 3 | 4 | ||
| ... | @@ -11,8 +12,6 @@ const getBrowser = RefCountedExpirable( | ... | @@ -11,8 +12,6 @@ const getBrowser = RefCountedExpirable( |
| 11 | ); | 12 | ); |
| 12 | 13 | ||
| 13 | export async function renderQuestionImage(question: Question) { | 14 | export async function renderQuestionImage(question: Question) { |
| 14 | const html = await view.renderToString("q+a/image-embed", { question }); | ||
| 15 | |||
| 16 | // this browser session will be reused if multiple images are generated | 15 | // this browser session will be reused if multiple images are generated |
| 17 | // either at the same time or within a 5-minute time span. the dispose | 16 | // either at the same time or within a 5-minute time span. the dispose |
| 18 | // symbol | 17 | // symbol |
| ... | @@ -20,12 +19,14 @@ export async function renderQuestionImage(question: Question) { | ... | @@ -20,12 +19,14 @@ export async function renderQuestionImage(question: Question) { |
| 20 | const b = sharedBrowser.value; | 19 | const b = sharedBrowser.value; |
| 21 | 20 | ||
| 22 | const p = await b.newPage(); | 21 | const p = await b.newPage(); |
| 22 | await p.setUserAgent({ userAgent: "clover-qa-image" }); | ||
| 23 | await p.setViewport({ width, height: 400 }); | 23 | await p.setViewport({ width, height: 400 }); |
| 24 | await p.setContent(html); | 24 | await p.goto(`http://localhost:${port}/q+a/${question.id}`); |
| 25 | try { | 25 | try { |
| 26 | await p.waitForNetworkIdle({ idleTime: 100, timeout: 500 }); | 26 | await p.waitForNetworkIdle({ idleTime: 100, timeout: 500 }); |
| 27 | } catch (e) {} | 27 | } catch (e) {} |
| 28 | const height = await p.evaluate(() => { | 28 | const height = await p.evaluate(() => { |
| 29 | document.body.style.background = "#1a1b1c"; | ||
| 29 | const e = document.querySelector("main")!; | 30 | const e = document.querySelector("main")!; |
| 30 | return e.getBoundingClientRect().height; | 31 | return e.getBoundingClientRect().height; |
| 31 | }); | 32 | }); |
src/q+a/views/permalink.marko+9-3| ... | @@ -4,14 +4,16 @@ export interface Input { | ... | @@ -4,14 +4,16 @@ export interface Input { |
| 4 | } | 4 | } |
| 5 | 5 | ||
| 6 | server export function meta({ context, question }) { | 6 | server export function meta({ context, question }) { |
| 7 | const isDiscord = context.get("user-agent") | 7 | console.log(context.req.header("user-agent")); |
| 8 | const isDiscord = context.req.header("user-agent") | ||
| 8 | ?.toLowerCase() | 9 | ?.toLowerCase() |
| 9 | .includes("discordbot"); | 10 | .includes("discord"); |
| 10 | if (question.type === QuestionType.normal) { | 11 | if (question.type === QuestionType.normal) { |
| 11 | return { | 12 | return { |
| 12 | title: "question permalink", | 13 | title: "question permalink", |
| 13 | openGraph: { | 14 | openGraph: { |
| 14 | images: [{ url: `https://paperclover.net/q+a/${question.id}.png` }], | 15 | title: isDiscord ? undefined : `question at ${formatQuestionTimestamp(question.date)}`, |
| 16 | image: `https://paperclover.net/q+a/${question.id}.png` | ||
| 15 | }, | 17 | }, |
| 16 | twitter: { card: "summary_large_image" }, | 18 | twitter: { card: "summary_large_image" }, |
| 17 | themeColor: isDiscord | 19 | themeColor: isDiscord |
| ... | @@ -46,4 +48,8 @@ server export function meta({ context, question }) { | ... | @@ -46,4 +48,8 @@ server export function meta({ context, question }) { |
| 46 | <pre>${JSON.stringify(question, null, 2)}</pre> | 48 | <pre>${JSON.stringify(question, null, 2)}</pre> |
| 47 | </> | 49 | </> |
| 48 | 50 | ||
| 51 | <a href="/q+a">view more questions</a> | ||
| 52 | |||
| 49 | import { Question, QuestionType } from '@/q+a/models/Question.ts'; | 53 | import { Question, QuestionType } from '@/q+a/models/Question.ts'; |
| 54 | import { transitionDate } from "@/q+a/tags/question.marko"; | ||
| 55 | import { formatQuestionTimestamp } from "@/q+a/format.ts"; |