1
0
Fork 1
mirror of https://github.com/Vendicated/Vencord.git synced 2025-01-10 09:56:24 +00:00

feat: donator & contributor cards in settings

This commit is contained in:
khcrysalis 2024-11-21 16:01:48 -08:00
parent a0308e03af
commit 661a0157a8
7 changed files with 223 additions and 16 deletions

View file

@ -0,0 +1,86 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 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 <https://www.gnu.org/licenses/>.
*/
import "./specialCard.css";
import { classNameFactory } from "@api/Styles";
import { Card, Forms, React } from "@webpack/common";
const cl = classNameFactory("vc-special-");
interface StyledCardProps {
title: string;
subtitle: string;
description: string;
cardImage?: string;
backgroundImage?: string;
backgroundColor?: string;
buttonTitle?: string;
buttonOnClick?: () => void;
}
export function SpecialCard({ title, subtitle, description, cardImage, backgroundImage, backgroundColor, buttonTitle, buttonOnClick: onClick }: StyledCardProps) {
const cardStyle: React.CSSProperties = {
backgroundColor: backgroundColor || "#9c85ef",
backgroundImage: `url(${backgroundImage || ""})`,
};
return (
<Card
className={cl("card", "card-special")}
style={cardStyle}
>
<div className={cl("card-flex")}>
<div className={cl("card-flex-main")}>
<Forms.FormTitle className={cl("title")} tag="h5">
{title}
</Forms.FormTitle>
<Forms.FormText className={cl("subtitle")}>
{subtitle}
</Forms.FormText>
<Forms.FormText className={cl("text")}>
{description.split("\n").map((line, index) => (
<React.Fragment key={index}>
{line}
<br />
</React.Fragment>
))}
</Forms.FormText>
</div>
<div className={cl("image-container")}>
<img
role="presentation"
src={cardImage}
alt=""
className={cl("image")}
/>
</div>
</div>
{
buttonTitle && (
<>
<Forms.FormDivider className={cl("seperator")} />
<Forms.FormText className={cl("hyperlink")} onClick={onClick} >
{buttonTitle}
</Forms.FormText>
</>
)
}
</Card>
);
}

View file

@ -20,29 +20,35 @@ import { openNotificationLogModal } from "@api/Notifications/notificationLog";
import { useSettings } from "@api/Settings";
import { classNameFactory } from "@api/Styles";
import DonateButton from "@components/DonateButton";
import { openContributorModal } from "@components/PluginSettings/ContributorModal";
import { openPluginModal } from "@components/PluginSettings/PluginModal";
import { gitRemote } from "@shared/vencordUserAgent";
import { DONOR_ROLE_ID, VENCORD_GUILD_ID } from "@utils/constants";
import { Margins } from "@utils/margins";
import { identity } from "@utils/misc";
import { identity, isPluginDev } from "@utils/misc";
import { relaunch, showItemInFolder } from "@utils/native";
import { useAwaiter } from "@utils/react";
import { Button, Card, Forms, React, Select, Switch } from "@webpack/common";
import { Button, Card, Forms, GuildMemberStore, React, Select, Switch, UserStore } from "@webpack/common";
import Plugins from "~plugins";
import { Flex, FolderIcon, GithubIcon, LogIcon, PaintbrushIcon, RestartIcon } from "..";
import { openNotificationSettingsModal } from "./NotificationSettings";
import { QuickAction, QuickActionCard } from "./quickActions";
import { SettingsTab, wrapTab } from "./shared";
import { SpecialCard } from "./SpecialCard";
const cl = classNameFactory("vc-settings-");
const DEFAULT_DONATE_IMAGE = "https://cdn.discordapp.com/emojis/1026533090627174460.png";
const SHIGGY_DONATE_IMAGE = "https://media.discordapp.net/stickers/1039992459209490513.png";
const VENNIE_DONATOR_IMAGE = "https://cdn.discordapp.com/emojis/1238120638020063377.png";
const COZY_CONTRIB_IMAGE = "https://cdn.discordapp.com/emojis/1026533070955872337.png";
type KeysOfType<Object, Type> = {
[K in keyof Object]: Object[K] extends Type ? K : never;
}[keyof Object];
function VencordSettings() {
const [settingsDir, , settingsDirPending] = useAwaiter(VencordNative.settings.getSettingsDir, {
fallbackValue: "Loading..."
@ -55,6 +61,8 @@ function VencordSettings() {
const isMac = navigator.platform.toLowerCase().startsWith("mac");
const needsVibrancySettings = IS_DISCORD_DESKTOP && isMac;
const user = UserStore.getCurrentUser();
const Switches: Array<false | {
key: KeysOfType<typeof settings, boolean>;
title: string;
@ -99,7 +107,30 @@ function VencordSettings() {
return (
<SettingsTab title="Vencord Settings">
<DonateCard image={donateImage} />
{
isDonor(user?.id) ? <SpecialCard
title="Donations"
subtitle="Thank you for donating!"
description={"People will be able to see your requested badge through Vencord, you're able to request to change it any time.\n\nDon't worry about your perks running out if you stop your subscription, you're keeping your perks forever!"}
cardImage={VENNIE_DONATOR_IMAGE}
backgroundImage={"https://github.com/user-attachments/assets/2aa0826f-faa4-4bb0-8b59-ca8859f5c7f1"}
backgroundColor="#ED87A9"
/> : <DonateCard image={donateImage} />
}
{
isPluginDev(user?.id)
&& <SpecialCard
title="Contributions"
subtitle="Thank you for contributing!"
description={"Since you've contributed to Vencord and added yourself to contributors list, you now have a cool new badge!\n\nTo avoid pesky help from people you don't know, theres gonna be a warning on your profile to not ask for support in your DMs."}
cardImage={COZY_CONTRIB_IMAGE}
backgroundImage={"https://github.com/user-attachments/assets/98b19955-1ed7-4c8a-bf4b-986b72217d69"}
backgroundColor="#EDCC87"
buttonTitle="See What You Contributed To"
buttonOnClick={() => openContributorModal(user)}
/>
}
<Forms.FormSection title="Quick Actions">
<QuickActionCard>
<QuickAction
@ -266,4 +297,9 @@ function DonateCard({ image }: DonateCardProps) {
);
}
function isDonor(userId: string): boolean {
const donorBadges = (Plugins.BadgeAPI as unknown as typeof import("../../plugins/_api/badges").default).getDonorBadges(userId);
return GuildMemberStore.getMember(VENCORD_GUILD_ID, userId)?.roles.includes(DONOR_ROLE_ID) || !!donorBadges;
}
export default wrapTab(VencordSettings, "Vencord Settings");

View file

@ -1,12 +1,17 @@
.vc-settings-quickActions-card {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, max-content));
grid-template-columns: repeat(3, 1fr);
gap: 0.5em;
justify-content: center;
padding: 0.5em 0;
padding: 0.5em;
margin-bottom: 1em;
}
@media (max-width: 1040px) {
.vc-settings-quickActions-card {
grid-template-columns: repeat(2, 1fr);
}
}
.vc-settings-quickActions-pill {
all: unset;
background: var(--background-secondary);
@ -14,12 +19,16 @@
display: flex;
align-items: center;
gap: 0.5em;
padding: 8px 12px;
border-radius: 9999px;
padding: 8px 9px;
border-radius: 6px;
transition: 0.1s ease-out;
box-sizing: border-box;
}
.vc-settings-quickActions-pill:hover {
background: var(--background-secondary-alt);
transform: translateY(-1px);
box-shadow: var(--elevation-high);
}
.vc-settings-quickActions-pill:focus-visible {

View file

@ -0,0 +1,69 @@
.vc-settings-card {
padding: 1em;
margin-bottom: 1em;
}
.vc-special-card-special {
padding: 1.9em;
margin-bottom: 1em;
background-size: cover;
background-position: center;
}
.vc-special-card-flex {
display: flex;
flex-direction: row;
}
.vc-special-card-flex-main {
width: 100%;
}
.vc-special-title {
color: black;
}
.vc-special-subtitle {
color: black;
font-size: 1.4em;
font-weight: bold;
margin-top: 0.9em;
}
.vc-special-text {
color: black;
font-size: 1em;
margin-top: 1em;
}
.vc-special-seperator {
margin-top: 1em;
border-top: '1px solid white';
opacity: 0.4;
}
.vc-special-hyperlink {
color: black;
font-size: 1em;
font-weight: bold;
margin-top: 1em;
text-align: center;
cursor: pointer;
}
.vc-special-image-container {
display: flex;
justify-content: center;
align-items: center;
margin-left: 1em;
flex-shrink: 0;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: white;
}
.vc-special-image {
width: 65px;
height: 65px;
}

View file

@ -23,7 +23,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex";
import { Link } from "@components/Link";
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
import { Devs, SUPPORT_CHANNEL_ID } from "@utils/constants";
import { CONTRIB_ROLE_ID, Devs, DONOR_ROLE_ID, SUPPORT_CHANNEL_ID, VENBOT_USER_ID,VENCORD_GUILD_ID } from "@utils/constants";
import { sendMessage } from "@utils/discord";
import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
@ -40,8 +40,6 @@ import plugins, { PluginMeta } from "~plugins";
import SettingsPlugin from "./settings";
const VENCORD_GUILD_ID = "1015060230222131221";
const VENBOT_USER_ID = "1017176847865352332";
const KNOWN_ISSUES_CHANNEL_ID = "1222936386626129920";
const CodeBlockRe = /```js\n(.+?)```/s;
@ -52,9 +50,9 @@ const AllowedChannelIds = [
];
const TrustedRolesIds = [
"1026534353167208489", // contributor
CONTRIB_ROLE_ID, // contributor
"1026504932959977532", // regular
"1042507929485586532", // donor
DONOR_ROLE_ID, // donor
];
const AsyncFunction = async function () { }.constructor;

View file

@ -18,7 +18,12 @@
export const WEBPACK_CHUNK = "webpackChunkdiscord_app";
export const REACT_GLOBAL = "Vencord.Webpack.Common.React";
export const VENBOT_USER_ID = "1017176847865352332";
export const VENCORD_GUILD_ID = "1015060230222131221";
export const DONOR_ROLE_ID = "1042507929485586532";
export const CONTRIB_ROLE_ID = "1026534353167208489";
export const SUPPORT_CHANNEL_ID = "1026515880080842772";
export const KNOWN_ISSUES_CHANNEL_ID = "1222936386626129920";
export interface Dev {
name: string;
@ -583,6 +588,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
name: "jamesbt365",
id: 158567567487795200n,
},
samsam: {
name: "samsam",
id: 836452332387565589n,
},
} satisfies Record<string, Dev>);
// iife so #__PURE__ works correctly