feat(card): implement clan tags

This commit is contained in:
Hexagonn
2024-09-17 21:24:28 +07:00
parent c783ae1dff
commit 08dd29fd05
5 changed files with 81 additions and 3 deletions

View File

@@ -11,12 +11,14 @@
"dependencies": { "dependencies": {
"@types/escape-html": "^1.0.1", "@types/escape-html": "^1.0.1",
"@types/ioredis": "^4.28.8", "@types/ioredis": "^4.28.8",
"@types/json-bigint": "^1.0.4",
"@types/styled-components": "^5.1.10", "@types/styled-components": "^5.1.10",
"axios": "^0.21.1", "axios": "^0.21.1",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"framer-motion": "^4.1.17", "framer-motion": "^4.1.17",
"image-to-base64": "^2.2.0", "image-to-base64": "^2.2.0",
"ioredis": "^4.28.5", "ioredis": "^4.28.5",
"json-bigint": "^1.0.0",
"next": "12.2.5", "next": "12.2.5",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",

View File

@@ -3,6 +3,7 @@ import axios from "axios";
import renderCard from "../../src/renderCard"; import renderCard from "../../src/renderCard";
import { isSnowflake } from "../../src/snowflake"; import { isSnowflake } from "../../src/snowflake";
import redis from "../../src/redis"; import redis from "../../src/redis";
import JSONbig from "json-bigint";
type Data = { type Data = {
id?: string | string[]; id?: string | string[];
@@ -20,8 +21,24 @@ type Parameters = {
animated?: string; animated?: string;
}; };
const convertBigIntToString = (obj: { [key: string]: any }): { [key: string]: any } => {
const result: { [key: string]: any } = Array.isArray(obj) ? [] : {};
for (const key in obj) {
if (typeof obj[key] === "bigint") {
result[key] = obj[key].toString();
} else if (typeof obj[key] === "object" && obj[key] !== null) {
result[key] = convertBigIntToString(obj[key]);
} else {
result[key] = obj[key];
}
}
return result;
};
export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) { export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
let getUser; let getUser: any = {};
if (!req.query.id) if (!req.query.id)
return res.send({ return res.send({
@@ -37,7 +54,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
}); });
try { try {
getUser = await axios(`https://api.lanyard.rest/v1/users/${userId}`); getUser.data = await fetch(`https://api.lanyard.rest/v1/users/${userId}`)
.then(res => res.text())
.then(res => convertBigIntToString(JSONbig.parse(res)));
} catch (error: any) { } catch (error: any) {
if (error.response.data && error.response.data.error.message) if (error.response.data && error.response.data.error.message)
return res return res

View File

@@ -37,6 +37,14 @@ export interface DiscordUser {
avatar: string; avatar: string;
global_name: string; global_name: string;
display_name: string; display_name: string;
clan: ClanTag | null;
}
export interface ClanTag {
tag: string;
badge: string;
identity_enabled: boolean;
identity_guild_id: number;
} }
export interface Activity { export interface Activity {

View File

@@ -9,6 +9,7 @@ import escape from "escape-html";
type Parameters = { type Parameters = {
theme?: string; theme?: string;
bg?: string; bg?: string;
clanbg?: string;
animated?: string; animated?: string;
hideDiscrim?: string; hideDiscrim?: string;
hideStatus?: string; hideStatus?: string;
@@ -17,6 +18,7 @@ type Parameters = {
hideProfile?: string; hideProfile?: string;
hideActivity?: string; hideActivity?: string;
hideSpotify?: string; hideSpotify?: string;
hideClanTag?: string;
ignoreAppId?: string; ignoreAppId?: string;
showDisplayName?: string; showDisplayName?: string;
borderRadius?: string; borderRadius?: string;
@@ -71,12 +73,13 @@ const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise<
let hideProfile = parseBool(params.hideProfile); let hideProfile = parseBool(params.hideProfile);
let hideActivity = params.hideActivity ?? "false"; let hideActivity = params.hideActivity ?? "false";
let hideSpotify = parseBool(params.hideSpotify); let hideSpotify = parseBool(params.hideSpotify);
let hideClanTag = parseBool(params.hideClanTag);
let ignoreAppId = parseAppId(params.ignoreAppId); let ignoreAppId = parseAppId(params.ignoreAppId);
let hideDiscrim = parseBool(params.hideDiscrim); let hideDiscrim = parseBool(params.hideDiscrim);
let showDisplayName = parseBool(params.showDisplayName); let showDisplayName = parseBool(params.showDisplayName);
if (parseBool(params.hideDiscrim) || body.data.discord_user.discriminator === "0") hideDiscrim = true; if (parseBool(params.hideDiscrim) || body.data.discord_user.discriminator === "0") hideDiscrim = true;
if (!body.data.discord_user.clan) hideClanTag = true;
if (data.activities[0]?.emoji?.animated) statusExtension = "gif"; if (data.activities[0]?.emoji?.animated) statusExtension = "gif";
if (data.discord_user.avatar && data.discord_user.avatar.startsWith("a_")) avatarExtension = "gif"; if (data.discord_user.avatar && data.discord_user.avatar.startsWith("a_")) avatarExtension = "gif";
if (params.animated === "false") avatarExtension = "webp"; if (params.animated === "false") avatarExtension = "webp";
@@ -85,6 +88,8 @@ const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise<
theme = "light"; theme = "light";
} }
if (params.bg) backgroundColor = params.bg; if (params.bg) backgroundColor = params.bg;
let clanBackgroundColor: string = theme === "light" ? "#e0dede" : "#111214";
if (params.clanbg) clanBackgroundColor = params.clanbg;
if (params.idleMessage) idleMessage = params.idleMessage; if (params.idleMessage) idleMessage = params.idleMessage;
if (params.borderRadius) borderRadius = params.borderRadius; if (params.borderRadius) borderRadius = params.borderRadius;
@@ -103,6 +108,13 @@ const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise<
); );
} }
let clanBadge: string;
if (data.discord_user.clan) {
clanBadge = await encodeBase64(
`https://cdn.discordapp.com/clan-badges/${data.discord_user.clan.identity_guild_id}/${data.discord_user.clan.badge}.png?size=16`
);
}
switch (data.discord_status) { switch (data.discord_status) {
case "online": case "online":
avatarBorderColor = "#43B581"; avatarBorderColor = "#43B581";
@@ -230,6 +242,26 @@ const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise<
} }
</h1> </h1>
${hideClanTag ? "" : `
<span style="
background-color: ${clanBackgroundColor};
border-radius: 0.375rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
margin-left: -6px;
margin-right: 12px;
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 16px;
font-weight: 500;
height: 100%;
">
<img src="data:image/png;base64,${clanBadge!}" />
<p style="margin-bottom: 1.1rem">${escape(data.discord_user.clan!.tag)}</p>
</span>
`}
${hideBadges ? "" : flags.map(v => ` ${hideBadges ? "" : flags.map(v => `
<img src="data:image/png;base64,${Badges[v]}" style=" <img src="data:image/png;base64,${Badges[v]}" style="
width: auto; width: auto;

View File

@@ -364,6 +364,11 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/json-bigint@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/json-bigint/-/json-bigint-1.0.4.tgz#250d29e593375499d8ba6efaab22d094c3199ef3"
integrity sha512-ydHooXLbOmxBbubnA7Eh+RpBzuaIiQjh8WGJYQB50JFGFrdxW7JzVlyEV7fAXw0T2sqJ1ysTneJbiyNLqZRAag==
"@types/json5@^0.0.29": "@types/json5@^0.0.29":
version "0.0.29" version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@@ -652,6 +657,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
bignumber.js@^9.0.0:
version "9.1.2"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c"
integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==
brace-expansion@^1.1.7: brace-expansion@^1.1.7:
version "1.1.11" version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -1709,6 +1719,13 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json-bigint@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1"
integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==
dependencies:
bignumber.js "^9.0.0"
json-buffer@3.0.1: json-buffer@3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"