import { ImageResponse } from "@vercel/og"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; import React from "react"; import { formatNumberWithCommas, formatPp } from "@ssr/common/utils/number-utils"; import { getDifficultyFromScoreSaberDifficulty } from "@ssr/common/utils/scoresaber-utils"; import { StarIcon } from "../../components/star-icon"; import { GlobeIcon } from "../../components/globe-icon"; import NodeCache from "node-cache"; import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token"; import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token"; const cache = new NodeCache({ stdTTL: 60 * 60, // 1 hour checkperiod: 120, }); export class ImageService { /** * The base of the OpenGraph image * * @param children the content of the image * @private */ public static BaseImage({ children }: { children: React.ReactNode }) { return (
{children}
); } /** * Generates the OpenGraph image for the player * * @param id the player's id */ public static async generatePlayerImage(id: string) { const cacheKey = `player-${id}`; let player: undefined | ScoreSaberPlayerToken; if (cache.has(cacheKey)) { player = cache.get(cacheKey); } else { player = await scoresaberService.lookupPlayer(id); if (player != undefined) { cache.set(cacheKey, player); } } if (player == undefined) { return undefined; } return new ImageResponse( ( Player's Avatar

{player.name}

{formatPp(player.pp)}pp

#{formatNumberWithCommas(player.rank)}

{/* eslint-disable-next-line @next/next/no-img-element */} Player's Country

#{formatNumberWithCommas(player.countryRank)}

), { width: 1200, height: 630, emoji: "twemoji", } ); } /** * Generates the OpenGraph image for the player * * @param id the player's id */ public static async generateLeaderboardImage(id: string) { const cacheKey = `leaderboard-${id}`; let leaderboard: undefined | ScoreSaberLeaderboardToken; if (cache.has(cacheKey)) { leaderboard = cache.get(cacheKey) as ScoreSaberLeaderboardToken; } else { leaderboard = await scoresaberService.lookupLeaderboard(id); if (leaderboard != undefined) { cache.set(cacheKey, leaderboard); } } if (leaderboard == undefined) { return undefined; } const ranked = leaderboard.stars > 0; return new ImageResponse( ( Player's Avatar

{leaderboard.songName} {leaderboard.songSubName}

{ranked && (

{leaderboard.stars}

)}

{getDifficultyFromScoreSaberDifficulty(leaderboard.difficulty.difficulty)}

Mapped by {leaderboard.levelAuthorName}

), { width: 1200, height: 630, emoji: "twemoji", } ); } }