GlobalBadges: Use ManaSelect & Drop Badge Modal
This commit is contained in:
parent
02e854ea1b
commit
c148127818
6 changed files with 173 additions and 232 deletions
|
|
@ -19,7 +19,7 @@
|
|||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import globalBadges from "@equicordplugins/globalBadges";
|
||||
import BadgeAPIPlugin from "@plugins/_api/badges";
|
||||
import { ComponentType, HTMLProps } from "react";
|
||||
import { ComponentType, HTMLProps, ReactNode } from "react";
|
||||
|
||||
import { isPluginEnabled } from "./PluginManager";
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ export interface ProfileBadge {
|
|||
*/
|
||||
id: string,
|
||||
/** The tooltip to show on hover. Required for image badges */
|
||||
description?: string;
|
||||
description?: string | ReactNode;
|
||||
/** Custom component for the badge (tooltip not included) */
|
||||
component?: ComponentType<ProfileBadge & BadgeUserArgs>;
|
||||
/** The custom image to use */
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { HeadingTertiary } from "@components/Heading";
|
||||
import { Paragraph } from "@components/Paragraph";
|
||||
import { openInviteModal } from "@utils/discord";
|
||||
import { RenderModalProps, User } from "@vencord/discord-types";
|
||||
import { Modal, openModal, React, Tooltip } from "@webpack/common";
|
||||
|
||||
import { cl, GlobalBadges, INVITE_LINK } from "./utils";
|
||||
|
||||
export const BadgeModalComponent = ({ key, tooltip, badge }: { key: string, tooltip: string, badge: string; }) => {
|
||||
return (
|
||||
<>
|
||||
<Tooltip text={tooltip} >
|
||||
{(tooltipProps: any) => (
|
||||
<img
|
||||
className={cl("modal-badge")}
|
||||
key={key}
|
||||
{...tooltipProps}
|
||||
src={badge}
|
||||
/>
|
||||
)}
|
||||
</Tooltip>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export function openBadgeModal(user: User) {
|
||||
const badgeDataElements = GlobalBadges[user.id].map(badge => (
|
||||
<BadgeModalComponent key={badge.key} tooltip={badge.tooltip} badge={badge.badge} />
|
||||
));
|
||||
|
||||
openModal((modalprops: RenderModalProps) => (
|
||||
<Modal
|
||||
{...modalprops}
|
||||
size="sm"
|
||||
title={
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "10px" }}>
|
||||
<img
|
||||
className={cl("modal-avatar")}
|
||||
src={user.getAvatarURL(undefined, 512, true)}
|
||||
alt=""
|
||||
/>
|
||||
<HeadingTertiary className={cl("modal-name")} style={{ color: "white" }}>
|
||||
{user.username}
|
||||
</HeadingTertiary>
|
||||
</div>
|
||||
}
|
||||
actions={[
|
||||
{
|
||||
text: "Join GlobalBadges Server",
|
||||
variant: "link",
|
||||
onClick: () => openInviteModal(INVITE_LINK)
|
||||
}
|
||||
]}
|
||||
>
|
||||
<ErrorBoundary>
|
||||
<div className={cl("modal-description")}>
|
||||
{badgeDataElements.length ? (
|
||||
<>
|
||||
<Paragraph className={cl("modal-text")}>
|
||||
{badgeDataElements.length} global badge
|
||||
{badgeDataElements.length > 1 ? "s" : ""}.
|
||||
</Paragraph>
|
||||
<div className={cl("modal-badges")}>
|
||||
{badgeDataElements}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<Paragraph>
|
||||
No global badges.
|
||||
</Paragraph>
|
||||
)}
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
</Modal>
|
||||
));
|
||||
}
|
||||
|
|
@ -13,9 +13,8 @@ import { BadgeContextMenu } from "@plugins/_api/badges";
|
|||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import { openInviteModal } from "@utils/discord";
|
||||
import definePlugin from "@utils/types";
|
||||
import { ContextMenuApi, React, Toasts, UserStore } from "@webpack/common";
|
||||
import { ContextMenuApi, React, Toasts } from "@webpack/common";
|
||||
|
||||
import { openBadgeModal } from "./badgeModal";
|
||||
import { settings } from "./settings";
|
||||
import { cl, GlobalBadges, INVITE_LINK, loadBadges } from "./utils";
|
||||
|
||||
|
|
@ -75,9 +74,6 @@ export default definePlugin({
|
|||
onContextMenu(event, badge) {
|
||||
ContextMenuApi.openContextMenu(event, () => <BadgeContextMenu badge={badge} />);
|
||||
},
|
||||
onClick() {
|
||||
return openBadgeModal(UserStore.getUser(userId));
|
||||
},
|
||||
} satisfies ProfileBadge));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,6 +6,58 @@
|
|||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { OptionType } from "@utils/types";
|
||||
import { findComponentByCodeLazy } from "@webpack";
|
||||
|
||||
import { loadBadges } from "./utils";
|
||||
|
||||
const ManaSelect = findComponentByCodeLazy('"data-mana-component":"select"');
|
||||
const badgeOptions = [
|
||||
{ label: "BadgeVault", value: "showCustom" },
|
||||
{ label: "Nekocord", value: "showNekocord" },
|
||||
{ label: "ReviewDB", value: "showReviewDB" },
|
||||
{ label: "Aero", value: "showAero" },
|
||||
{ label: "Aliucord", value: "showAliucord" },
|
||||
{ label: "Raincord", value: "showRaincord" },
|
||||
{ label: "Velocity", value: "showVelocity" },
|
||||
{ label: "Enmity", value: "showEnmity" },
|
||||
{ label: "Paicord", value: "showPaicord" },
|
||||
{ label: "Bunny", value: "showBunny" },
|
||||
{ label: "GooseMod", value: "showGooseMod" },
|
||||
{ label: "Replugged", value: "showReplugged" },
|
||||
{ label: "BetterDiscord", value: "showBetterDiscord" },
|
||||
{ label: "Vendroid Enhanced", value: "showVendroidEnhanced" },
|
||||
{ label: "Revenge", value: "showRevenge" },
|
||||
{ label: "ReCord", value: "showReCord" }
|
||||
] as const;
|
||||
|
||||
const badgeManaOptions = badgeOptions.map(opt => ({ ...opt, id: opt.value }));
|
||||
|
||||
function ShowXSettings() {
|
||||
const currentSettings = settings.use(badgeOptions.map(o => o.value));
|
||||
const selectedValues = badgeOptions.filter(o => currentSettings[o.value]).map(o => o.value);
|
||||
|
||||
async function updateSelection(value) {
|
||||
const selectedKeys = new Set(Array.isArray(value) ? value : value ? [value] : []);
|
||||
for (const o of badgeOptions) {
|
||||
settings.store[o.value] = selectedKeys.has(o.value);
|
||||
}
|
||||
|
||||
await loadBadges();
|
||||
}
|
||||
|
||||
return (
|
||||
<ManaSelect
|
||||
label="Specific Client Mods"
|
||||
options={badgeManaOptions}
|
||||
value={selectedValues}
|
||||
closeOnSelect={false}
|
||||
maxOptionsVisible={7}
|
||||
selectionMode="multiple"
|
||||
wrapTags={true}
|
||||
onSelectionChange={updateSelection}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const settings = definePluginSettings({
|
||||
showPrefix: {
|
||||
|
|
@ -30,102 +82,6 @@ export const settings = definePluginSettings({
|
|||
}
|
||||
})
|
||||
},
|
||||
showCustom: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Custom Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showNekocord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Nekocord Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showReviewDB: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show ReviewDB Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showAero: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Aero Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showAliucord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Aliucord Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showRaincord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Raincord Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showVelocity: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Velocity Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showEnmity: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Enmity Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showPaicord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Paicord Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showBunny: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Bunny Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showGooseMod: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show GooseMod Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showReplugged: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Replugged Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showBetterDiscord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show BetterDiscord Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showVendroidEnhanced: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Vendroid Enhanced Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showRevenge: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Revenge Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
showReCord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show ReCord Badges",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
},
|
||||
apiUrl: {
|
||||
type: OptionType.STRING,
|
||||
description: "API to use",
|
||||
|
|
@ -135,5 +91,121 @@ export const settings = definePluginSettings({
|
|||
if (!value) return false;
|
||||
return true;
|
||||
})
|
||||
},
|
||||
showClientMods: {
|
||||
type: OptionType.COMPONENT,
|
||||
component: ShowXSettings,
|
||||
},
|
||||
showCustom: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Custom Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showNekocord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Nekocord Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showReviewDB: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show ReviewDB Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showAero: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Aero Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showAliucord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Aliucord Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showRaincord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Raincord Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showVelocity: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Velocity Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showEnmity: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Enmity Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showPaicord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Paicord Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showBunny: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Bunny Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showGooseMod: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show GooseMod Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showReplugged: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Replugged Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showBetterDiscord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show BetterDiscord Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showVendroidEnhanced: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Vendroid Enhanced Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showRevenge: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show Revenge Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
},
|
||||
showReCord: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show ReCord Badges",
|
||||
default: true,
|
||||
restartNeeded: false,
|
||||
hidden: true
|
||||
}
|
||||
});
|
||||
|
|
@ -1,49 +1,3 @@
|
|||
.vc-global-badges-modal-name {
|
||||
text-transform: none;
|
||||
flex-grow: 0;
|
||||
background: var(--background-base-lowest);
|
||||
border-radius: 0 9999px 9999px 0;
|
||||
padding: 6px 0.8em 6px 0.5em;
|
||||
font-size: 20px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
.vc-global-badges-modal-name::before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 32px;
|
||||
background: var(--background-base-lowest);
|
||||
z-index: -1;
|
||||
left: -32px;
|
||||
top: 0;
|
||||
border-top-left-radius: 9999px;
|
||||
border-bottom-left-radius: 9999px;
|
||||
}
|
||||
|
||||
.vc-global-badges-modal-avatar {
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.vc-global-badges-modal-description {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.vc-global-badges-modal-text {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.vc-global-badges-modal-badge {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.vc-global-badges-settings-button {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ export const serviceMap: Record<string, string> = {
|
|||
vendroidenhanced: "VendroidEnhanced",
|
||||
revenge: "Revenge",
|
||||
record: "ReCord",
|
||||
vencord: "Vencord",
|
||||
equicord: "Equicord"
|
||||
};
|
||||
|
||||
const blockedMods = ["vencord", "equicord"];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue