add context menu options to vencord badges
This commit is contained in:
parent
8807564053
commit
17b90beee1
2 changed files with 75 additions and 18 deletions
|
|
@ -34,7 +34,9 @@ export interface ProfileBadge {
|
||||||
image?: string;
|
image?: string;
|
||||||
link?: string;
|
link?: string;
|
||||||
/** Action to perform when you click the badge */
|
/** Action to perform when you click the badge */
|
||||||
onClick?(event: React.MouseEvent<HTMLButtonElement, MouseEvent>, props: BadgeUserArgs): void;
|
onClick?(event: React.MouseEvent, props: ProfileBadge & BadgeUserArgs): void;
|
||||||
|
/** Action to perform when you right click the badge */
|
||||||
|
onContextMenu?(event: React.MouseEvent, props: BadgeUserArgs & BadgeUserArgs): void;
|
||||||
/** Should the user display this badge? */
|
/** Should the user display this badge? */
|
||||||
shouldShow?(userInfo: BadgeUserArgs): boolean;
|
shouldShow?(userInfo: BadgeUserArgs): boolean;
|
||||||
/** Optional props (e.g. style) for the badge, ignored for component badges */
|
/** Optional props (e.g. style) for the badge, ignored for component badges */
|
||||||
|
|
@ -76,21 +78,34 @@ export function removeProfileBadge(badge: ProfileBadge) {
|
||||||
export function _getBadges(args: BadgeUserArgs) {
|
export function _getBadges(args: BadgeUserArgs) {
|
||||||
const badges = [] as ProfileBadge[];
|
const badges = [] as ProfileBadge[];
|
||||||
for (const badge of Badges) {
|
for (const badge of Badges) {
|
||||||
if (!badge.shouldShow || badge.shouldShow(args)) {
|
if (badge.shouldShow && !badge.shouldShow(args)) {
|
||||||
const b = badge.getBadges
|
continue;
|
||||||
? badge.getBadges(args).map(b => {
|
}
|
||||||
b.component &&= ErrorBoundary.wrap(b.component, { noop: true });
|
|
||||||
return b;
|
|
||||||
})
|
|
||||||
: [{ ...badge, ...args }];
|
|
||||||
|
|
||||||
badge.position === BadgePosition.START
|
const b = badge.getBadges
|
||||||
? badges.unshift(...b)
|
? badge.getBadges(args).map(badge => ({
|
||||||
: badges.push(...b);
|
...args,
|
||||||
|
...badge,
|
||||||
|
component: badge.component && ErrorBoundary.wrap(badge.component, { noop: true })
|
||||||
|
}))
|
||||||
|
: [{ ...args, ...badge }];
|
||||||
|
|
||||||
|
if (badge.position === BadgePosition.START) {
|
||||||
|
badges.unshift(...b);
|
||||||
|
} else {
|
||||||
|
badges.push(...b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const donorBadges = BadgeAPIPlugin.getDonorBadges(args.userId);
|
const donorBadges = BadgeAPIPlugin.getDonorBadges(args.userId);
|
||||||
if (donorBadges) badges.unshift(...donorBadges);
|
if (donorBadges) {
|
||||||
|
badges.unshift(
|
||||||
|
...donorBadges.map(badge => ({
|
||||||
|
...args,
|
||||||
|
...badge,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return badges;
|
return badges;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ import { openContributorModal } from "@components/settings/tabs";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { shouldShowContributorBadge } from "@utils/misc";
|
import { copyWithToast, shouldShowContributorBadge } from "@utils/misc";
|
||||||
import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal";
|
import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { User } from "@vencord/discord-types";
|
import { User } from "@vencord/discord-types";
|
||||||
import { Forms, Toasts, UserStore } from "@webpack/common";
|
import { ContextMenuApi, Forms, Menu, Toasts, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
const CONTRIBUTOR_BADGE = "https://cdn.discordapp.com/emojis/1092089799109775453.png?size=64";
|
const CONTRIBUTOR_BADGE = "https://cdn.discordapp.com/emojis/1092089799109775453.png?size=64";
|
||||||
|
|
||||||
|
|
@ -56,9 +56,35 @@ async function loadBadges(noCache = false) {
|
||||||
|
|
||||||
let intervalId: any;
|
let intervalId: any;
|
||||||
|
|
||||||
|
function BadgeContextMenu({ badge }: { badge: ProfileBadge & BadgeUserArgs; }) {
|
||||||
|
console.log(badge);
|
||||||
|
return (
|
||||||
|
<Menu.Menu
|
||||||
|
navId="vc-badge-context"
|
||||||
|
onClose={ContextMenuApi.closeContextMenu}
|
||||||
|
aria-label="Badge Options"
|
||||||
|
>
|
||||||
|
{badge.description && (
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="vc-badge-copy-name"
|
||||||
|
label="Copy Badge Name"
|
||||||
|
action={() => copyWithToast(badge.description!)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{badge.image && (
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="vc-badge-copy-link"
|
||||||
|
label="Copy Badge Image Link"
|
||||||
|
action={() => copyWithToast(badge.image!)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Menu.Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "BadgeAPI",
|
name: "BadgeAPI",
|
||||||
description: "API to add badges to users.",
|
description: "API to add badges to users",
|
||||||
authors: [Devs.Megu, Devs.Ven, Devs.TheSun],
|
authors: [Devs.Megu, Devs.Ven, Devs.TheSun],
|
||||||
required: true,
|
required: true,
|
||||||
patches: [
|
patches: [
|
||||||
|
|
@ -80,10 +106,10 @@ export default definePlugin({
|
||||||
match: /(?<="aria-label":(\i)\.description,.{0,200})children:/,
|
match: /(?<="aria-label":(\i)\.description,.{0,200})children:/,
|
||||||
replace: "children:$1.component?$self.renderBadgeComponent({...$1}) :"
|
replace: "children:$1.component?$self.renderBadgeComponent({...$1}) :"
|
||||||
},
|
},
|
||||||
// conditionally override their onClick with badge.onClick if it exists
|
// handle onClick and onContextMenu
|
||||||
{
|
{
|
||||||
match: /href:(\i)\.link/,
|
match: /href:(\i)\.link/,
|
||||||
replace: "...($1.onClick&&{onClick:vcE=>$1.onClick(vcE,$1)}),$&"
|
replace: "...$self.getBadgeMouseEventHandlers($1),$&"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -137,6 +163,19 @@ export default definePlugin({
|
||||||
}, { noop: true }),
|
}, { noop: true }),
|
||||||
|
|
||||||
|
|
||||||
|
getBadgeMouseEventHandlers(badge: ProfileBadge & BadgeUserArgs) {
|
||||||
|
const handlers = {} as Record<string, (e: React.MouseEvent) => void>;
|
||||||
|
|
||||||
|
if (!badge) return handlers; // sanity check
|
||||||
|
|
||||||
|
const { onClick, onContextMenu } = badge;
|
||||||
|
|
||||||
|
if (onClick) handlers.onClick = e => onClick(e, badge);
|
||||||
|
if (onContextMenu) handlers.onContextMenu = e => onContextMenu(e, badge);
|
||||||
|
|
||||||
|
return handlers;
|
||||||
|
},
|
||||||
|
|
||||||
getDonorBadges(userId: string) {
|
getDonorBadges(userId: string) {
|
||||||
return DonorBadges[userId]?.map(badge => ({
|
return DonorBadges[userId]?.map(badge => ({
|
||||||
image: badge.badge,
|
image: badge.badge,
|
||||||
|
|
@ -148,6 +187,9 @@ export default definePlugin({
|
||||||
transform: "scale(0.9)" // The image is a bit too big compared to default badges
|
transform: "scale(0.9)" // The image is a bit too big compared to default badges
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onContextMenu(event, badge) {
|
||||||
|
ContextMenuApi.openContextMenu(event, () => <BadgeContextMenu badge={badge} />);
|
||||||
|
},
|
||||||
onClick() {
|
onClick() {
|
||||||
const modalKey = openModal(props => (
|
const modalKey = openModal(props => (
|
||||||
<ErrorBoundary noop onError={() => {
|
<ErrorBoundary noop onError={() => {
|
||||||
|
|
@ -203,6 +245,6 @@ export default definePlugin({
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
}));
|
} satisfies ProfileBadge));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue