improve contributor modal & badge
This commit is contained in:
parent
5bc20ba162
commit
f54dcb74d7
5 changed files with 59 additions and 33 deletions
|
@ -36,7 +36,7 @@ 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?(): void;
|
onClick?(event: React.MouseEvent<HTMLButtonElement, MouseEvent>, props: 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 */
|
||||||
|
@ -87,9 +87,7 @@ export function _getBadges(args: BadgeUserArgs) {
|
||||||
|
|
||||||
export interface BadgeUserArgs {
|
export interface BadgeUserArgs {
|
||||||
user: User;
|
user: User;
|
||||||
profile: Profile;
|
guildId: string;
|
||||||
premiumSince: Date;
|
|
||||||
premiumGuildSince?: Date;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ConnectedAccount {
|
interface ConnectedAccount {
|
||||||
|
|
|
@ -9,10 +9,12 @@ import "./contributorModal.css";
|
||||||
import { useSettings } from "@api/Settings";
|
import { useSettings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
|
import { Link } from "@components/Link";
|
||||||
import { DevsById } from "@utils/constants";
|
import { DevsById } from "@utils/constants";
|
||||||
import { fetchUserProfile, getTheme, Theme } from "@utils/discord";
|
import { fetchUserProfile, getTheme, Theme } from "@utils/discord";
|
||||||
|
import { pluralise } from "@utils/misc";
|
||||||
import { ModalContent, ModalRoot, openModal } from "@utils/modal";
|
import { ModalContent, ModalRoot, openModal } from "@utils/modal";
|
||||||
import { Forms, MaskedLink, showToast, useEffect, useMemo, UserProfileStore, useStateFromStores } from "@webpack/common";
|
import { Forms, MaskedLink, showToast, Tooltip, useEffect, useMemo, UserProfileStore, useStateFromStores } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
|
|
||||||
import Plugins from "~plugins";
|
import Plugins from "~plugins";
|
||||||
|
@ -72,6 +74,8 @@ function ContributorModal({ user }: { user: User; }) {
|
||||||
.sort((a, b) => Number(a.required ?? false) - Number(b.required ?? false));
|
.sort((a, b) => Number(a.required ?? false) - Number(b.required ?? false));
|
||||||
}, [user.id, user.username]);
|
}, [user.id, user.username]);
|
||||||
|
|
||||||
|
const ContributedHyperLink = <Link href="https://vencord.dev/source">contributed</Link>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={cl("header")}>
|
<div className={cl("header")}>
|
||||||
|
@ -84,20 +88,37 @@ function ContributorModal({ user }: { user: User; }) {
|
||||||
|
|
||||||
<div className={cl("links")}>
|
<div className={cl("links")}>
|
||||||
{website && (
|
{website && (
|
||||||
<MaskedLink
|
<Tooltip text={website}>
|
||||||
href={"https://" + website}
|
{props => (
|
||||||
>
|
<MaskedLink {...props} href={"https://" + website}>
|
||||||
<WebsiteIcon />
|
<WebsiteIcon />
|
||||||
</MaskedLink>
|
</MaskedLink>
|
||||||
)}
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
{githubName && (
|
{githubName && (
|
||||||
<MaskedLink href={`https://github.com/${githubName}`}>
|
<Tooltip text={githubName}>
|
||||||
|
{props => (
|
||||||
|
<MaskedLink {...props} href={`https://github.com/${githubName}`}>
|
||||||
<GithubIcon />
|
<GithubIcon />
|
||||||
</MaskedLink>
|
</MaskedLink>
|
||||||
)}
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{plugins.length ? (
|
||||||
|
<Forms.FormText>
|
||||||
|
This person has {ContributedHyperLink} to {pluralise(plugins.length, "plugin")}!
|
||||||
|
</Forms.FormText>
|
||||||
|
) : (
|
||||||
|
<Forms.FormText>
|
||||||
|
This person has not made any plugins. They likely {ContributedHyperLink} to Vencord in other ways!
|
||||||
|
</Forms.FormText>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!!plugins.length && (
|
||||||
<div className={cl("plugins")}>
|
<div className={cl("plugins")}>
|
||||||
{plugins.map(p =>
|
{plugins.map(p =>
|
||||||
<PluginCard
|
<PluginCard
|
||||||
|
@ -108,6 +129,7 @@ function ContributorModal({ user }: { user: User; }) {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,13 @@
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 16px;
|
width: 32px;
|
||||||
background: var(--background-tertiary);
|
background: var(--background-tertiary);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
left: -16px;
|
left: -32px;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
border-top-left-radius: 9999px;
|
||||||
|
border-bottom-left-radius: 9999px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-author-modal-avatar {
|
.vc-author-modal-avatar {
|
||||||
|
@ -55,4 +57,5 @@
|
||||||
.vc-author-modal-plugins {
|
.vc-author-modal-plugins {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
|
margin-top: 0.75em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,14 +34,13 @@ const ContributorBadge: ProfileBadge = {
|
||||||
description: "Vencord Contributor",
|
description: "Vencord Contributor",
|
||||||
image: CONTRIBUTOR_BADGE,
|
image: CONTRIBUTOR_BADGE,
|
||||||
position: BadgePosition.START,
|
position: BadgePosition.START,
|
||||||
props: {
|
|
||||||
style: {
|
|
||||||
borderRadius: "50%",
|
|
||||||
transform: "scale(0.9)" // The image is a bit too big compared to default badges
|
|
||||||
}
|
|
||||||
},
|
|
||||||
shouldShow: ({ user }) => isPluginDev(user.id),
|
shouldShow: ({ user }) => isPluginDev(user.id),
|
||||||
link: "https://github.com/Vendicated/Vencord"
|
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<string, Array<Record<"tooltip" | "badge", string>>>;
|
let DonorBadges = {} as Record<string, Array<Record<"tooltip" | "badge", string>>>;
|
||||||
|
@ -85,7 +84,7 @@ export default definePlugin({
|
||||||
// conditionally override their onClick with badge.onClick if it exists
|
// conditionally override their onClick with badge.onClick if it exists
|
||||||
{
|
{
|
||||||
match: /href:(\i)\.link/,
|
match: /href:(\i)\.link/,
|
||||||
replace: "...($1.onClick && { onClick: $1.onClick }),$&"
|
replace: "...($1.onClick && { onClick: vcE => $1.onClick(vcE, arguments[0]) }),$&"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,3 +114,7 @@ export function identity<T>(value: T): T {
|
||||||
export const isMobile = navigator.userAgent.includes("Mobi");
|
export const isMobile = navigator.userAgent.includes("Mobi");
|
||||||
|
|
||||||
export const isPluginDev = (id: string) => Object.hasOwn(DevsById, id);
|
export const isPluginDev = (id: string) => Object.hasOwn(DevsById, id);
|
||||||
|
|
||||||
|
export function pluralise(amount: number, singular: string, plural = singular + "s") {
|
||||||
|
return amount === 1 ? `${amount} ${singular}` : `${amount} ${plural}`;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue