/* * Vencord, a modification for Discord's desktop app * Copyright (c) 2022 Vendicated and contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import { BadgePosition, BadgeUserArgs, ProfileBadge } from "@api/Badges"; import DonateButton from "@components/DonateButton"; import ErrorBoundary from "@components/ErrorBoundary"; import { Flex } from "@components/Flex"; import { Heart } from "@components/Heart"; import { Devs } from "@utils/constants"; import { Margins } from "@utils/margins"; import { isPluginDev } from "@utils/misc"; import { closeModal, Modals, openModal } from "@utils/modal"; import definePlugin from "@utils/types"; import { Forms, Toasts } from "@webpack/common"; const CONTRIBUTOR_BADGE = "https://vencord.dev/assets/favicon.png"; const ContributorBadge: ProfileBadge = { description: "Vencord Contributor", image: CONTRIBUTOR_BADGE, position: BadgePosition.START, shouldShow: ({ user }) => isPluginDev(user.id), onClick(_, { user }) { // circular import shenanigans const { openContributorModal } = require("@components/PluginSettings/ContributorModal") as typeof import("@components/PluginSettings/ContributorModal"); // setImmediate is needed to run on later tick to workaround limitation in proxyLazy setImmediate(() => openContributorModal(user)); } }; let DonorBadges = {} as Record>>; async function loadBadges(noCache = false) { DonorBadges = {}; const init = {} as RequestInit; if (noCache) init.cache = "no-cache"; DonorBadges = await fetch("https://badges.vencord.dev/badges.json", init) .then(r => r.json()); } export default definePlugin({ name: "BadgeAPI", description: "API to add badges to users.", authors: [Devs.Megu, Devs.Ven, Devs.TheSun], required: true, patches: [ /* Patch the badge list component on user profiles */ { find: 'id:"premium",', replacement: [ { match: /&&(\i)\.push\(\{id:"premium".+?\}\);/, replace: "$&$1.unshift(...Vencord.Api.Badges._getBadges(arguments[0]));", }, { // alt: "", aria-hidden: false, src: originalSrc match: /alt:" ","aria-hidden":!0,src:(?=(\i)\.src)/, // ...badge.props, ..., src: badge.image ?? ... replace: "...$1.props,$& $1.image??" }, // replace their component with ours if applicable { match: /(?<=text:(\i)\.description,spacing:12,.{0,50})children:/, replace: "children:$1.component ? () => $self.renderBadgeComponent($1) :" }, // conditionally override their onClick with badge.onClick if it exists { match: /href:(\i)\.link/, replace: "...($1.onClick && { onClick: vcE => $1.onClick(vcE, arguments[0]) }),$&" } ] } ], toolboxActions: { async "Refetch Badges"() { await loadBadges(true); Toasts.show({ id: Toasts.genId(), message: "Successfully refetched badges!", type: Toasts.Type.SUCCESS }); } }, async start() { Vencord.Api.Badges.addBadge(ContributorBadge); await loadBadges(); }, renderBadgeComponent: ErrorBoundary.wrap((badge: ProfileBadge & BadgeUserArgs) => { const Component = badge.component!; return ; }, { noop: true }), getDonorBadges(userId: string) { return DonorBadges[userId]?.map(badge => ({ image: badge.badge, description: badge.tooltip, position: BadgePosition.START, props: { style: { borderRadius: "50%", transform: "scale(0.9)" // The image is a bit too big compared to default badges } }, onClick() { const modalKey = openModal(props => ( { closeModal(modalKey); VencordNative.native.openExternal("https://github.com/sponsors/Vendicated"); }}> Vencord Donor
This Badge is a special perk for Vencord Donors Please consider supporting the development of Vencord by becoming a donor. It would mean a lot!!
)); }, })); } });