GlobalBadges & UserPFP: Update Modals & Settings
This commit is contained in:
parent
832ac62f8e
commit
078914a40f
9 changed files with 148 additions and 95 deletions
|
|
@ -26,8 +26,6 @@ import { PluginCard } from "./PluginCard";
|
|||
|
||||
const cl = classNameFactory("vc-author-modal-");
|
||||
|
||||
type PluginFilter = "all" | "equicord" | "vencord" | "modified" | "user";
|
||||
|
||||
export function openContributorModal(user: User) {
|
||||
openModal(modalProps =>
|
||||
<ModalRoot {...modalProps}>
|
||||
|
|
|
|||
|
|
@ -7,12 +7,17 @@
|
|||
import { React, Tooltip, UserStore } from "@webpack/common";
|
||||
import { JSX } from "react";
|
||||
|
||||
import { BadgeModalComponent, openBadgeModal } from "./badgeModal";
|
||||
import { openBadgeModal } from "./badgeModal";
|
||||
import { settings } from "./settings";
|
||||
import { BadgeCache } from "./types";
|
||||
import { cl, fetchBadges, serviceMap } from "./utils";
|
||||
import { cl, fetchBadges } from "./utils";
|
||||
|
||||
export let badgeImages;
|
||||
interface BadgeModalItem {
|
||||
name: string;
|
||||
rawName: string;
|
||||
}
|
||||
|
||||
export let badgeData;
|
||||
|
||||
export const BadgeComponent = ({ name, img }: { name: string, img: string; }) => {
|
||||
return (
|
||||
|
|
@ -38,7 +43,7 @@ export const GlobalBadges = ({ userId }: { userId: string; }) => {
|
|||
|
||||
if (!badges) return null;
|
||||
const globalBadges: JSX.Element[] = [];
|
||||
const badgeModal: JSX.Element[] = [];
|
||||
const badgeModal: BadgeModalItem[] = [];
|
||||
|
||||
Object.keys(badges).forEach(mod => {
|
||||
if (!badges[mod] || !Array.isArray(badges[mod]) || badges[mod].length === 0) return;
|
||||
|
|
@ -46,20 +51,23 @@ export const GlobalBadges = ({ userId }: { userId: string; }) => {
|
|||
badges[mod].forEach(badge => {
|
||||
if (!badge || !badge.tooltip || !badge.badge) return;
|
||||
|
||||
const modDisplay = serviceMap[mod.toLowerCase()] || mod;
|
||||
const prefix = settings.store.showPrefix ? `(${modDisplay})` : "";
|
||||
const suffix = settings.store.showSuffix ? `(${modDisplay})` : "";
|
||||
const prefix = settings.store.showPrefix ? `(${mod})` : "";
|
||||
const suffix = settings.store.showSuffix ? `(${mod})` : "";
|
||||
const displayName = `${prefix} ${badge.tooltip} ${suffix}`;
|
||||
|
||||
if (mod.toLowerCase() === "badgevault") {
|
||||
if (mod === "BadgeVault") {
|
||||
badge.custom = true;
|
||||
}
|
||||
|
||||
globalBadges.push(<BadgeComponent name={displayName} img={badge.badge} />);
|
||||
badgeModal.push(<BadgeModalComponent name={displayName} img={badge.badge} />);
|
||||
badgeModal.push({
|
||||
name: displayName,
|
||||
rawName: badge.tooltip,
|
||||
...badge
|
||||
});
|
||||
});
|
||||
});
|
||||
badgeImages = badgeModal;
|
||||
badgeData = badgeModal;
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -4,65 +4,78 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { Button } from "@components/Button";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { HeadingTertiary } from "@components/Heading";
|
||||
import { ModalContent, ModalRoot, openModal } from "@utils/modal";
|
||||
import { Paragraph } from "@components/Paragraph";
|
||||
import { openInviteModal } from "@utils/discord";
|
||||
import { ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal";
|
||||
import { User } from "@vencord/discord-types";
|
||||
import { React, Tooltip } from "@webpack/common";
|
||||
|
||||
import { badgeImages } from "./badgeComponent";
|
||||
import { cl } from "./utils";
|
||||
import { badgeData } from "./badgeComponent";
|
||||
import { cl, INVITE_LINK } from "./utils";
|
||||
|
||||
export const BadgeModalComponent = ({ name, img }: { name: string, img: string; }) => {
|
||||
return (
|
||||
<Tooltip text={name} >
|
||||
{(tooltipProps: any) => (
|
||||
<img
|
||||
className={cl("modal-badges")}
|
||||
{...tooltipProps}
|
||||
src={img}
|
||||
/>
|
||||
)}
|
||||
</Tooltip>
|
||||
<>
|
||||
<Tooltip text={name} >
|
||||
{(tooltipProps: any) => (
|
||||
<img
|
||||
className={cl("modal-badge")}
|
||||
{...tooltipProps}
|
||||
src={img}
|
||||
/>
|
||||
)}
|
||||
</Tooltip>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export function BadgeModal({ user }: { user: User; }) {
|
||||
return (
|
||||
<>
|
||||
<div className={cl("header")}>
|
||||
<img
|
||||
className={cl("avatar")}
|
||||
src={user.getAvatarURL(void 0, 512, true)}
|
||||
alt=""
|
||||
/>
|
||||
{badgeImages.length ? (
|
||||
<HeadingTertiary className={cl("name")}>
|
||||
{user.username} has {badgeImages.length} global badges
|
||||
</HeadingTertiary>
|
||||
) : (
|
||||
<HeadingTertiary className={cl("name")}>
|
||||
{user.username} has no global badges
|
||||
</HeadingTertiary>
|
||||
)}
|
||||
</div>
|
||||
{!!badgeImages.length && (
|
||||
<div className={cl("badges")}>
|
||||
{badgeImages}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function openBadgeModal(user: User) {
|
||||
openModal(modalprops =>
|
||||
const badgeDataElements = badgeData.map(badge => (
|
||||
<BadgeModalComponent key={badge.rawName} name={badge.name} img={badge.badge} />
|
||||
));
|
||||
|
||||
openModal(modalprops => (
|
||||
<ModalRoot {...modalprops}>
|
||||
<ErrorBoundary>
|
||||
<ModalContent className={cl("root")}>
|
||||
<BadgeModal user={user} />
|
||||
<ModalHeader>
|
||||
<img
|
||||
className={cl("modal-avatar")}
|
||||
src={user.getAvatarURL(undefined, 512, true)}
|
||||
alt=""
|
||||
/>
|
||||
<HeadingTertiary className={cl("modal-name")}>
|
||||
{user.username}
|
||||
</HeadingTertiary>
|
||||
</ModalHeader>
|
||||
<ModalContent 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>
|
||||
)}
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<Button
|
||||
variant="link"
|
||||
onClick={() => openInviteModal(INVITE_LINK)}
|
||||
>
|
||||
Join GlobalBadges Server
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ErrorBoundary>
|
||||
</ModalRoot>
|
||||
);
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,15 @@
|
|||
import "./styles.css";
|
||||
|
||||
import { addProfileBadge, BadgePosition, ProfileBadge, removeProfileBadge } from "@api/Badges";
|
||||
import { Button } from "@components/Button";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import { openInviteModal } from "@utils/discord";
|
||||
import definePlugin from "@utils/types";
|
||||
import { React } from "@webpack/common";
|
||||
|
||||
import { GlobalBadges } from "./badgeComponent";
|
||||
import { settings } from "./settings";
|
||||
import { fetchBadges } from "./utils";
|
||||
import { cl, fetchBadges, INVITE_LINK } from "./utils";
|
||||
|
||||
const Badge: ProfileBadge = {
|
||||
component: b => <GlobalBadges {...b} />,
|
||||
|
|
@ -27,6 +29,17 @@ export default definePlugin({
|
|||
description: "Adds global badges from other client mods",
|
||||
authors: [Devs.HypedDomi, EquicordDevs.Wolfie],
|
||||
settings,
|
||||
settingsAboutComponent: () => (
|
||||
<>
|
||||
<Button
|
||||
className={cl("settings-button")}
|
||||
variant="link"
|
||||
onClick={() => openInviteModal(INVITE_LINK)}
|
||||
>
|
||||
Join GlobalBadges Server
|
||||
</Button>
|
||||
</>
|
||||
),
|
||||
start: () => addProfileBadge(Badge),
|
||||
stop: () => removeProfileBadge(Badge),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,13 +12,23 @@ export const settings = definePluginSettings({
|
|||
type: OptionType.BOOLEAN,
|
||||
description: "Shows the Mod as Prefix",
|
||||
default: true,
|
||||
restartNeeded: false
|
||||
restartNeeded: false,
|
||||
onChange: (e => {
|
||||
if (e && settings.store.showSuffix) {
|
||||
settings.store.showSuffix = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
showSuffix: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Shows the Mod as Suffix",
|
||||
default: false,
|
||||
restartNeeded: false
|
||||
restartNeeded: false,
|
||||
onChange: (e => {
|
||||
if (e && settings.store.showPrefix) {
|
||||
settings.store.showPrefix = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
showCustom: {
|
||||
type: OptionType.BOOLEAN,
|
||||
|
|
|
|||
|
|
@ -4,13 +4,7 @@
|
|||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.vc-global-badges-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.vc-global-badges-name {
|
||||
.vc-global-badges-modal-name {
|
||||
text-transform: none;
|
||||
flex-grow: 0;
|
||||
background: var(--background-base-lowest);
|
||||
|
|
@ -22,7 +16,7 @@
|
|||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
.vc-global-badges-name::before {
|
||||
.vc-global-badges-modal-name::before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
|
|
@ -36,19 +30,27 @@
|
|||
border-bottom-left-radius: 9999px;
|
||||
}
|
||||
|
||||
.vc-global-badges-avatar {
|
||||
.vc-global-badges-modal-avatar {
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.vc-global-badges-description {
|
||||
.vc-global-badges-modal-description {
|
||||
font-size: 16px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.vc-global-badges-modal-badges {
|
||||
.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;
|
||||
}
|
||||
|
|
@ -13,17 +13,7 @@ const cache = new Map<string, BadgeCache>();
|
|||
const EXPIRES = 1000 * 60 * 15;
|
||||
|
||||
export const cl = classNameFactory("vc-global-badges-");
|
||||
export const serviceMap = {
|
||||
"nekocord": "Nekocord",
|
||||
"reviewdb": "ReviewDB",
|
||||
"aero": "Aero",
|
||||
"aliucord": "Aliucord",
|
||||
"ra1ncord": "Ra1ncord",
|
||||
"velocity": "Velocity",
|
||||
"enmity": "Enmity",
|
||||
"replugged": "Replugged",
|
||||
"badgevault": "BadgeVault"
|
||||
};
|
||||
export const INVITE_LINK = "https://discord.gg/kwHCJPxp8t";
|
||||
|
||||
export const fetchBadges = (id: string): BadgeCache["badges"] | undefined => {
|
||||
const cachedValue = cache.get(id);
|
||||
|
|
@ -44,7 +34,7 @@ export const fetchBadges = (id: string): BadgeCache["badges"] | undefined => {
|
|||
return {};
|
||||
}
|
||||
|
||||
fetch(`${settings.store.apiUrl}${id}?seperated=true&services=${services.join(",")}`)
|
||||
fetch(`${settings.store.apiUrl}${id}?seperated=true&capitalize=true&services=${services.join(",")}`)
|
||||
.then(res => res.json() as Promise<{ status: number; badges: BadgeCache["badges"]; }>)
|
||||
.then(body => {
|
||||
cache.set(id, { badges: body.badges, expires: Date.now() + EXPIRES });
|
||||
|
|
|
|||
|
|
@ -4,12 +4,20 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import "./styles.css";
|
||||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Link } from "@components/Link";
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import { Button } from "@components/Button";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import { openInviteModal } from "@utils/discord";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { User } from "@vencord/discord-types";
|
||||
|
||||
const cl = classNameFactory("vc-userpfp-");
|
||||
const DONO_URL = "https://ko-fi.com/coolesding";
|
||||
const INVITE_LINK = "https://discord.gg/userpfp-1129784704267210844";
|
||||
|
||||
let data = { avatars: {} as Record<string, string> };
|
||||
const settings = definePluginSettings({
|
||||
preferNitro: {
|
||||
|
|
@ -20,32 +28,39 @@ const settings = definePluginSettings({
|
|||
{ label: "Nitro", value: true, default: true },
|
||||
],
|
||||
},
|
||||
dbSource: {
|
||||
databaseSource: {
|
||||
description: "URL to load database from",
|
||||
type: OptionType.STRING,
|
||||
default: "https://userpfp.github.io/UserPFP/source/data.json",
|
||||
onChange: (e => {
|
||||
if (!e) return settings.store.dbSource = "https://userpfp.github.io/UserPFP/source/data.json";
|
||||
if (!e) return settings.store.databaseSource = "https://userpfp.github.io/UserPFP/source/data.json";
|
||||
return e;
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
data,
|
||||
name: "UserPFP",
|
||||
description: "Allows you to use an animated avatar without Nitro",
|
||||
authors: [EquicordDevs.nexpid, Devs.thororen],
|
||||
settings,
|
||||
settingsAboutComponent: () => (
|
||||
<>
|
||||
<Link href="https://userpfp.github.io/UserPFP/#how-to-request-a-profile-picture-pfp">
|
||||
<b>Submit your own PFP here!</b>
|
||||
</Link>
|
||||
<Button
|
||||
variant="link"
|
||||
className={cl("settings-button")}
|
||||
onClick={() => openInviteModal(INVITE_LINK)}
|
||||
>
|
||||
Join UserPFP Server
|
||||
</Button>
|
||||
<br />
|
||||
<Link href="https://ko-fi.com/coolesding">
|
||||
<b>Support UserPFP here!</b>
|
||||
</Link>
|
||||
<Button
|
||||
variant="link"
|
||||
className={cl("settings-button")}
|
||||
onClick={() => VencordNative.native.openExternal(DONO_URL)}
|
||||
>
|
||||
Support UserPFP here
|
||||
</Button>
|
||||
</>
|
||||
),
|
||||
patches: [
|
||||
|
|
@ -72,9 +87,9 @@ export default definePlugin({
|
|||
return res.toString();
|
||||
},
|
||||
async start() {
|
||||
await fetch(settings.store.dbSource)
|
||||
await fetch(settings.store.databaseSource)
|
||||
.then(async res => {
|
||||
if (res.ok) this.data = data = await res.json();
|
||||
if (res.ok) data = await res.json();
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
|
|
|
|||
4
src/equicordplugins/userpfp/styles.css
Normal file
4
src/equicordplugins/userpfp/styles.css
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
.vc-userpfp-settings-button {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue