//probably the messiest code i've ever written but it works so :) import { Badges } from "../public/assets/badges/BadgesEncoded"; import { getFlags } from "./getFlags"; import * as LanyardTypes from "./LanyardTypes"; import { encodeBase64 } from "./toBase64"; import { blue, green, gray, gold, red } from "./defaultAvatars"; import escape from "escape-html"; type Parameters = { theme?: string; bg?: string; animated?: string; hideDiscrim?: string; hideStatus?: string; hideTimestamp?: string; hideBadges?: string; hideProfile?: string; borderRadius?: string; idleMessage?: string; }; const elapsedTime = (timestamp: any) => { let startTime = timestamp; let endTime = Number(new Date()); let difference = (endTime - startTime) / 1000; // we only calculate them, but we don't display them. // this fixes a bug in the Discord API that does not send the correct timestamp to presence. let daysDifference = Math.floor(difference / 60 / 60 / 24); difference -= daysDifference * 60 * 60 * 24; let hoursDifference = Math.floor(difference / 60 / 60); difference -= hoursDifference * 60 * 60; let minutesDifference = Math.floor(difference / 60); difference -= minutesDifference * 60; let secondsDifference = Math.floor(difference); return `${hoursDifference >= 1 ? ("0" + hoursDifference).slice(-2) + ":" : ""}${("0" + minutesDifference).slice( -2 )}:${("0" + secondsDifference).slice(-2)}`; }; const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise => { let { data } = body; let avatarBorderColor: string = "#747F8D", avatarExtension: string = "webp", statusExtension: string = "webp", activity: any = false, backgroundColor: string = "1a1c1f", theme = "dark", discrim = "show", hideStatus = "false", hideTimestamp = "false", hideBadges = "false", hideProfile = "false", borderRadius = "10px", idleMessage = "I'm not currently doing anything!"; if (data.activities[0]?.emoji?.animated) statusExtension = "gif"; if (data.discord_user.avatar && data.discord_user.avatar.startsWith("a_")) avatarExtension = "gif"; if (params.animated === "false") avatarExtension = "webp"; if (params.hideStatus === "true") hideStatus = "true"; if (params.hideTimestamp === "true") hideTimestamp = "true"; if (params.hideBadges === "true") hideBadges = "true"; if (params.hideDiscrim === "true") discrim = "hide"; if (params.hideProfile === "true") hideProfile = "true"; if (params.theme === "light") { backgroundColor = "#eee"; theme = "light"; } if (params.bg) backgroundColor = params.bg; if (params.idleMessage) idleMessage = params.idleMessage; if (params.borderRadius) borderRadius = params.borderRadius; let avatar: String; if (data.discord_user.avatar) { avatar = await encodeBase64( `https://cdn.discordapp.com/avatars/${data.discord_user.id}/${ data.discord_user.avatar }.${avatarExtension}?size=${avatarExtension === "gif" ? "64" : "256"}` ); } else { let lastDigit = Number(data.discord_user.discriminator.substr(-1)); if (lastDigit >= 5) { lastDigit -= 5; } // the default avatar that discord uses depends on the last digit of the user's discriminator switch (lastDigit) { case 1: avatar = gray; break; case 2: avatar = green; break; case 3: avatar = gold; break; case 4: avatar = red; break; default: avatar = blue; } } switch (data.discord_status) { case "online": avatarBorderColor = "#43B581"; break; case "idle": avatarBorderColor = "#FAA61A"; break; case "dnd": avatarBorderColor = "#F04747"; break; case "offline": avatarBorderColor = "#747F8D"; break; } let flags: string[] = getFlags(data.discord_user.public_flags); if (data.discord_user.avatar && data.discord_user.avatar.includes("a_")) flags.push("Nitro"); let userStatus: Record | null = null; if (data.activities[0] && data.activities[0].type === 4) userStatus = data.activities[0]; // Filter only type 0 const activities = data.activities.filter(activity => activity.type === 0); // Take the highest one activity = Array.isArray(activities) ? activities[0] : activities; return `
${ hideProfile === "true" ? "" : `

${escape(data.discord_user.username)}${ discrim !== "hide" ? `#${ data.discord_user.discriminator }` : "" }

${ hideBadges == "true" ? "" : flags.map(v => ` `).join("") }
${ userStatus && hideStatus !== "true" ? `

${ userStatus.emoji?.id ? ` ` : '' } ${ userStatus.state && userStatus.emoji?.name && !userStatus.emoji.id ? `${userStatus.emoji.name} ${escape(userStatus.state)}` : userStatus.state ? escape(userStatus.state) : !userStatus.state && userStatus.emoji?.name && !userStatus.emoji.id ? escape(userStatus.emoji.name) : '' }

` : `` }
` } ${ activity ? `
${ activity.assets?.large_image ? ` ` : ` `} ${ activity.assets?.small_image ? ` ` : `` }

${escape(activity.name)}

${ activity.details ? `

${escape(activity.details)}

` : `` } ${ activity.state ? `

${escape(activity.state)}${ activity.party?.size ? ` (${activity.party.size[0]} of ${activity.party.size[1]})` : "" }

` : `` } ${ activity.timestamps?.start && hideTimestamp !== "true" ? `

${elapsedTime(new Date(activity.timestamps.start).getTime())} elapsed

` : `` }
` : `` } ${ data.listening_to_spotify === true && !activity && data.activities[Object.keys(data.activities).length - 1].type === 2 ? `

LISTENING TO SPOTIFY...

${escape(data.spotify.song)}

By ${escape(data.spotify.artist)}

` : `` } ${ !activity && data.listening_to_spotify === false ? `

${escape(idleMessage)}

` : `` }
`; }; export default renderCard;