From 49396451ec8c877aebd27299a98c1b9e5b1e6cd4 Mon Sep 17 00:00:00 2001 From: devin ivy Date: Thu, 27 Jun 2024 13:02:29 -0400 Subject: bskyogcard: support emoji, more languages, long starter pack names (#4668) --- bskyogcard/src/assets/Inter-Bold.ttf | Bin 316584 -> 0 bytes bskyogcard/src/assets/fonts/Inter-Bold.ttf | Bin 0 -> 316584 bytes bskyogcard/src/components/StarterPack.tsx | 5 +++- bskyogcard/src/context.ts | 20 +++++++++------- bskyogcard/src/logger.ts | 1 + bskyogcard/src/routes/starter-pack.tsx | 6 +++++ bskyogcard/src/util.ts | 37 +++++++++++++++++++++++++++++ 7 files changed, 59 insertions(+), 10 deletions(-) delete mode 100644 bskyogcard/src/assets/Inter-Bold.ttf create mode 100644 bskyogcard/src/assets/fonts/Inter-Bold.ttf create mode 100644 bskyogcard/src/util.ts (limited to 'bskyogcard/src') diff --git a/bskyogcard/src/assets/Inter-Bold.ttf b/bskyogcard/src/assets/Inter-Bold.ttf deleted file mode 100644 index fe23eeb9c..000000000 Binary files a/bskyogcard/src/assets/Inter-Bold.ttf and /dev/null differ diff --git a/bskyogcard/src/assets/fonts/Inter-Bold.ttf b/bskyogcard/src/assets/fonts/Inter-Bold.ttf new file mode 100644 index 000000000..fe23eeb9c Binary files /dev/null and b/bskyogcard/src/assets/fonts/Inter-Bold.ttf differ diff --git a/bskyogcard/src/components/StarterPack.tsx b/bskyogcard/src/components/StarterPack.tsx index f73442190..29bb8f32a 100644 --- a/bskyogcard/src/components/StarterPack.tsx +++ b/bskyogcard/src/components/StarterPack.tsx @@ -43,6 +43,7 @@ export function StarterPack(props: { } else { imagesAcross.push(...imagesExceptCreator.slice(0, 7)) } + const isLongTitle = record ? record.name.length > 30 : false return (
{record?.name || 'Starter Pack'}
diff --git a/bskyogcard/src/context.ts b/bskyogcard/src/context.ts index f92651caf..0c972c94d 100644 --- a/bskyogcard/src/context.ts +++ b/bskyogcard/src/context.ts @@ -1,8 +1,8 @@ -import {readFileSync} from 'node:fs' +import {readdirSync, readFileSync} from 'node:fs' +import * as path from 'node:path' +import {fileURLToPath} from 'node:url' import {AtpAgent} from '@atproto/api' -import * as path from 'path' -import {fileURLToPath} from 'url' import {Config} from './config.js' @@ -28,12 +28,14 @@ export class AppContext { static async fromConfig(cfg: Config, overrides?: Partial) { const appviewAgent = new AtpAgent({service: cfg.service.appviewUrl}) - const fonts = [ - { - name: 'Inter', - data: readFileSync(path.join(__DIRNAME, 'assets', 'Inter-Bold.ttf')), - }, - ] + const fontDirectory = path.join(__DIRNAME, 'assets', 'fonts') + const fontFiles = readdirSync(fontDirectory) + const fonts = fontFiles.map(file => { + return { + name: path.basename(file, path.extname(file)), + data: readFileSync(path.join(fontDirectory, file)), + } + }) return new AppContext({ cfg, appviewAgent, diff --git a/bskyogcard/src/logger.ts b/bskyogcard/src/logger.ts index 04b5d9046..320206513 100644 --- a/bskyogcard/src/logger.ts +++ b/bskyogcard/src/logger.ts @@ -1,3 +1,4 @@ import {subsystemLogger} from '@atproto/common' export const httpLogger = subsystemLogger('bskyogcard') +export const renderLogger = subsystemLogger('bskyogcard:render') diff --git a/bskyogcard/src/routes/starter-pack.tsx b/bskyogcard/src/routes/starter-pack.tsx index cb3a55327..06cd6977c 100644 --- a/bskyogcard/src/routes/starter-pack.tsx +++ b/bskyogcard/src/routes/starter-pack.tsx @@ -13,6 +13,7 @@ import { } from '../components/StarterPack.js' import {AppContext} from '../context.js' import {httpLogger} from '../logger.js' +import {loadEmojiAsSvg} from '../util.js' import {handler, originVerifyMiddleware} from './util.js' export default function (ctx: AppContext, app: Express) { @@ -65,6 +66,11 @@ export default function (ctx: AppContext, app: Express) { fonts: ctx.fonts, height: STARTERPACK_HEIGHT, width: STARTERPACK_WIDTH, + loadAdditionalAsset: async (code, text) => { + if (code === 'emoji') { + return await loadEmojiAsSvg(text) + } + }, }, ) const output = await resvg.renderAsync(svg) diff --git a/bskyogcard/src/util.ts b/bskyogcard/src/util.ts new file mode 100644 index 000000000..2b86ded06 --- /dev/null +++ b/bskyogcard/src/util.ts @@ -0,0 +1,37 @@ +import twemoji from 'twemoji' + +import {renderLogger} from './logger.js' + +const U200D = String.fromCharCode(0x200d) +const UFE0F_REGEXP = /\uFE0F/g + +export async function loadEmojiAsSvg(chars: string) { + const cached = emojiCache.get(chars) + if (cached) return cached + const iconCode = twemoji.convert.toCodePoint( + chars.indexOf(U200D) < 0 ? chars.replace(UFE0F_REGEXP, '') : chars, + ) + const res = await fetch(getEmojiUrl(iconCode)) + const body = await res.arrayBuffer() + if (!res.ok) { + renderLogger.warn( + {status: res.status, err: Buffer.from(body).toString()}, + 'could not fetch emoji', + ) + return + } + const svg = + 'data:image/svg+xml;base64,' + Buffer.from(body).toString('base64') + emojiCache.set(chars, svg) + return svg +} + +const emojiCache = new Map() + +function getEmojiUrl(code: string) { + return ( + 'https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/' + + code.toLowerCase() + + '.svg' + ) +} -- cgit 1.4.1