Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
thororen1234 2025-02-07 02:43:07 -05:00
commit 77fc5bfd84
12 changed files with 564 additions and 351 deletions

View file

@ -17,16 +17,22 @@
*/ */
import { Button } from "@webpack/common"; import { Button } from "@webpack/common";
import { ButtonProps } from "@webpack/types";
import { Heart } from "./Heart"; import { Heart } from "./Heart";
export default function DonateButton(props: any) { export default function DonateButton({
look = Button.Looks.LINK,
color = Button.Colors.TRANSPARENT,
...props
}: Partial<ButtonProps>) {
return ( return (
<Button <Button
{...props} {...props}
look={Button.Looks.LINK} look={look}
color={Button.Colors.TRANSPARENT} color={color}
onClick={() => VencordNative.native.openExternal("https://github.com/sponsors/verticalsync")} onClick={() => VencordNative.native.openExternal("https://github.com/sponsors/verticalsync")}
innerClassName="vc-donate-button"
> >
<Heart /> <Heart />
Donate Donate

View file

@ -16,14 +16,18 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
export function Heart() { import { classes } from "@utils/misc";
import { SVGProps } from "react";
export function Heart(props: SVGProps<SVGSVGElement>) {
return ( return (
<svg <svg
aria-hidden="true" aria-hidden="true"
height="16"
viewBox="0 0 16 16" viewBox="0 0 16 16"
height="16"
width="16" width="16"
style={{ marginRight: "0.5em", transform: "translateY(2px)" }} {...props}
className={classes("vc-heart-icon", props.className)}
> >
<path <path
fill="#db61a2" fill="#db61a2"

View file

@ -0,0 +1,77 @@
/*
* 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, Clickable, Forms, React } from "@webpack/common";
import type { PropsWithChildren } from "react";
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, children }: PropsWithChildren<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}</Forms.FormText>
{children}
</div>
{cardImage && (
<div className={cl("image-container")}>
<img
role="presentation"
src={cardImage}
alt=""
className={cl("image")}
/>
</div>
)}
</div>
{buttonTitle && (
<>
<Forms.FormDivider className={cl("seperator")} />
<Clickable onClick={onClick} className={cl("hyperlink")}>
<Forms.FormText className={cl("hyperlink-text")}>
{buttonTitle}
</Forms.FormText>
</Clickable>
</>
)}
</Card>
);
}

View file

@ -9,354 +9,347 @@ import "./VencordTab.css";
import { openNotificationLogModal } from "@api/Notifications/notificationLog"; import { openNotificationLogModal } from "@api/Notifications/notificationLog";
import { useSettings } from "@api/Settings"; import { useSettings } from "@api/Settings";
import { classNameFactory } from "@api/Styles"; import { classNameFactory } from "@api/Styles";
import DonateButton from "@components/DonateButton";
import { openContributorModal } from "@components/PluginSettings/ContributorModal";
import { openPluginModal } from "@components/PluginSettings/PluginModal"; import { openPluginModal } from "@components/PluginSettings/PluginModal";
import { gitRemote } from "@shared/vencordUserAgent"; import { gitRemote } from "@shared/vencordUserAgent";
import { openInviteModal } from "@utils/discord"; import { DONOR_ROLE_ID, GUILD_ID, VC_DONOR_ROLE_ID, VC_GUILD_ID } from "@utils/constants";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { identity } from "@utils/misc"; import { identity, isEquicordPluginDev, isPluginDev } from "@utils/misc";
import { relaunch, showItemInFolder } from "@utils/native"; import { relaunch, showItemInFolder } from "@utils/native";
import { useAwaiter } from "@utils/react"; import { useAwaiter } from "@utils/react";
import { import { Button, Forms, GuildMemberStore, React, Select, Switch, UserStore } from "@webpack/common";
Button,
Card,
Forms,
React,
Select,
showToast,
Switch,
} from "@webpack/common";
import { import BadgeAPI from "../../plugins/_api/badges";
Flex, import { Flex, FolderIcon, GithubIcon, LogIcon, PaintbrushIcon, RestartIcon } from "..";
FolderIcon,
GithubIcon,
Heart,
LogIcon,
PaintbrushIcon,
RestartIcon,
} from "..";
import { openNotificationSettingsModal } from "./NotificationSettings"; import { openNotificationSettingsModal } from "./NotificationSettings";
import { QuickAction, QuickActionCard } from "./quickActions"; import { QuickAction, QuickActionCard } from "./quickActions";
import { SettingsTab, wrapTab } from "./shared"; import { SettingsTab, wrapTab } from "./shared";
import { SpecialCard } from "./SpecialCard";
const cl = classNameFactory("vc-settings-"); const cl = classNameFactory("vc-settings-");
const DEFAULT_DONATE_IMAGE = const DEFAULT_DONATE_IMAGE = "https://cdn.discordapp.com/emojis/1026533090627174460.png";
"https://cdn.discordapp.com/emojis/1026533090627174460.png";
const SHIGGY_DONATE_IMAGE = "https://i.imgur.com/57ATLZu.png"; const SHIGGY_DONATE_IMAGE = "https://i.imgur.com/57ATLZu.png";
const VENNIE_DONATOR_IMAGE = "https://cdn.discordapp.com/emojis/1238120638020063377.png";
const COZY_CONTRIB_IMAGE = "https://cdn.discordapp.com/emojis/1026533070955872337.png";
const DONOR_BACKGROUND_IMAGE = "https://media.discordapp.net/stickers/1311070116305436712.png?size=2048";
const CONTRIB_BACKGROUND_IMAGE = "https://media.discordapp.net/stickers/1311070166481895484.png?size=2048";
type KeysOfType<Object, Type> = { type KeysOfType<Object, Type> = {
[K in keyof Object]: Object[K] extends Type ? K : never; [K in keyof Object]: Object[K] extends Type ? K : never;
}[keyof Object]; }[keyof Object];
function EquicordSettings() { function EquicordSettings() {
const [settingsDir, , settingsDirPending] = useAwaiter( const [settingsDir, , settingsDirPending] = useAwaiter(VencordNative.settings.getSettingsDir, {
VencordNative.settings.getSettingsDir, fallbackValue: "Loading..."
{ });
fallbackValue: "Loading...", const settings = useSettings();
},
);
const settings = useSettings();
const discordInvite = "bFp57wxCkv"; const discordInvite = "bFp57wxCkv";
const donateImage = React.useMemo( const vcDiscordInvite = "https://discord.gg/KGgvd6jPFu";
() => (Math.random() > 0.5 ? DEFAULT_DONATE_IMAGE : SHIGGY_DONATE_IMAGE), const donateImage = React.useMemo(
[], () => (Math.random() > 0.5 ? DEFAULT_DONATE_IMAGE : SHIGGY_DONATE_IMAGE),
); [],
);
const isWindows = navigator.platform.toLowerCase().startsWith("win"); const isWindows = navigator.platform.toLowerCase().startsWith("win");
const isMac = navigator.platform.toLowerCase().startsWith("mac"); const isMac = navigator.platform.toLowerCase().startsWith("mac");
const needsVibrancySettings = IS_DISCORD_DESKTOP && isMac; const needsVibrancySettings = IS_DISCORD_DESKTOP && isMac;
const Switches: Array< const user = UserStore.getCurrentUser();
| false
| { const Switches: Array<false | {
key: KeysOfType<typeof settings, boolean>; key: KeysOfType<typeof settings, boolean>;
title: string; title: string;
note: string; note: string;
warning: { enabled: boolean; message?: string }; warning: { enabled: boolean; message?: string; };
} }
> = [ > = [
{ {
key: "useQuickCss", key: "useQuickCss",
title: "Enable Custom CSS", title: "Enable Custom CSS",
note: "Loads your Custom CSS", note: "Loads your Custom CSS",
warning: { enabled: false }, warning: { enabled: false },
}, },
!IS_WEB && { !IS_WEB && {
key: "enableReactDevtools", key: "enableReactDevtools",
title: "Enable React Developer Tools", title: "Enable React Developer Tools",
note: "Requires a full restart", note: "Requires a full restart",
warning: { enabled: false }, warning: { enabled: false },
}, },
!IS_WEB && !IS_WEB &&
(!IS_DISCORD_DESKTOP || !isWindows (!IS_DISCORD_DESKTOP || !isWindows
? { ? {
key: "frameless", key: "frameless",
title: "Disable the window frame", title: "Disable the window frame",
note: "Requires a full restart", note: "Requires a full restart",
warning: { enabled: false }, warning: { enabled: false },
}
: {
key: "winNativeTitleBar",
title:
"Use Windows' native title bar instead of Discord's custom one",
note: "Requires a full restart",
warning: { enabled: false },
}),
!IS_WEB && {
key: "transparent",
title: "Enable window transparency.",
note: "You need a theme that supports transparency or this will do nothing. Requires a full restart!",
warning: {
enabled: isWindows,
message: "Enabling this will prevent you from snapping this window.",
},
},
!IS_WEB &&
isWindows && {
key: "winCtrlQ",
title:
"Register Ctrl+Q as shortcut to close Discord (Alternative to Alt+F4)",
note: "Requires a full restart",
warning: { enabled: false },
},
IS_DISCORD_DESKTOP && {
key: "disableMinSize",
title: "Disable minimum window size",
note: "Requires a full restart",
warning: { enabled: false },
},
];
return (
<SettingsTab title="Equicord Settings">
<DiscordInviteCard invite={discordInvite} image={donateImage} />
<Forms.FormSection title="Quick Actions">
<QuickActionCard>
<QuickAction
Icon={LogIcon}
text="Notification Log"
action={openNotificationLogModal}
/>
<QuickAction
Icon={PaintbrushIcon}
text="Edit QuickCSS"
action={() => VencordNative.quickCss.openEditor()}
/>
{!IS_WEB && (
<QuickAction
Icon={RestartIcon}
text="Relaunch Discord"
action={relaunch}
/>
)}
{!IS_WEB && (
<QuickAction
Icon={FolderIcon}
text="Open Settings Folder"
action={() => showItemInFolder(settingsDir)}
/>
)}
<QuickAction
Icon={GithubIcon}
text="View Source Code"
action={() =>
VencordNative.native.openExternal(
"https://github.com/" + gitRemote,
)
}
/>
</QuickActionCard>
</Forms.FormSection>
<Forms.FormDivider />
<Forms.FormSection className={Margins.top16} title="Settings" tag="h5">
<Forms.FormText
className={Margins.bottom20}
style={{ color: "var(--text-muted)" }}
>
Hint: You can change the position of this settings section in the{" "}
<Button
look={Button.Looks.BLANK}
style={{ color: "var(--text-link)", display: "inline-block" }}
onClick={() => openPluginModal(Vencord.Plugins.plugins.Settings)}
>
settings of the Settings plugin
</Button>
!
</Forms.FormText>
{Switches.map(
s =>
s && (
<Switch
key={s.key}
value={settings[s.key]}
onChange={v => (settings[s.key] = v)}
note={
s.warning.enabled ? (
<>
{s.note}
<div className="form-switch-warning">
{s.warning.message}
</div>
</>
) : (
s.note
)
} }
> : {
{s.title} key: "winNativeTitleBar",
</Switch> title:
), "Use Windows' native title bar instead of Discord's custom one",
)} note: "Requires a full restart",
</Forms.FormSection> warning: { enabled: false },
}),
!IS_WEB && {
key: "transparent",
title: "Enable window transparency.",
note: "You need a theme that supports transparency or this will do nothing. Requires a full restart!",
warning: {
enabled: isWindows,
message: "Enabling this will prevent you from snapping this window.",
},
},
!IS_WEB &&
isWindows && {
key: "winCtrlQ",
title:
"Register Ctrl+Q as shortcut to close Discord (Alternative to Alt+F4)",
note: "Requires a full restart",
warning: { enabled: false },
},
IS_DISCORD_DESKTOP && {
key: "disableMinSize",
title: "Disable minimum window size",
note: "Requires a full restart",
warning: { enabled: false },
},
];
{needsVibrancySettings && ( return (
<> <SettingsTab title="Equicord Settings">
<Forms.FormTitle tag="h5"> {(isDonor(user?.id) || isVCDonor(user?.id)) ? (
Window vibrancy style (requires restart) <SpecialCard
</Forms.FormTitle> title="Donations"
<Select subtitle="Thank you for donating!"
className={Margins.bottom20} description={
placeholder="Window vibrancy style" isDonor(user?.id) && isVCDonor(user?.id)
options={[ ? "All Vencord users can see your Vencord donor badge, and Equicord users can see your Equicord donor badge. To change your Vencord donor badge, contact @vending.machine. For your Equicord donor badge, make a ticket in Equicord's server."
// Sorted from most opaque to most transparent : isVCDonor(user?.id)
{ ? "All Vencord users can see your badge! You can change it at any time by messaging @vending.machine."
label: "No vibrancy", : "All Equicord users can see your badge! You can change it at any time by making a ticket in Equicord's server."
value: undefined, }
}, cardImage={VENNIE_DONATOR_IMAGE}
{ backgroundImage={DONOR_BACKGROUND_IMAGE}
label: "Under Page (window tinting)", backgroundColor="#ED87A9"
value: "under-page", >
}, <DonateButtonComponent />
{ </SpecialCard>
label: "Content", ) : (
value: "content", <SpecialCard
}, title="Support the Project"
{ description="Please consider supporting the development of Equicord by donating!"
label: "Window", cardImage={donateImage}
value: "window", backgroundImage={DONOR_BACKGROUND_IMAGE}
}, backgroundColor="#c3a3ce"
{ >
label: "Selection", <DonateButtonComponent />
value: "selection", </SpecialCard>
}, )}
{ {isPluginDev(user?.id) || isEquicordPluginDev(user?.id) && (
label: "Titlebar", <SpecialCard
value: "titlebar", title="Contributions"
}, subtitle="Thank you for contributing!"
{ description="Since you've contributed to Equicord you now have a cool new badge!"
label: "Header", cardImage={COZY_CONTRIB_IMAGE}
value: "header", backgroundImage={CONTRIB_BACKGROUND_IMAGE}
}, backgroundColor="#EDCC87"
{ buttonTitle="See what you've contributed to"
label: "Sidebar", buttonOnClick={() => openContributorModal(user)}
value: "sidebar", />
}, )}
{ <Forms.FormSection title="Quick Actions">
label: "Tooltip", <QuickActionCard>
value: "tooltip", <QuickAction
}, Icon={LogIcon}
{ text="Notification Log"
label: "Menu", action={openNotificationLogModal}
value: "menu", />
}, <QuickAction
{ Icon={PaintbrushIcon}
label: "Popover", text="Edit QuickCSS"
value: "popover", action={() => VencordNative.quickCss.openEditor()}
}, />
{ {!IS_WEB && (
label: "Fullscreen UI (transparent but slightly muted)", <QuickAction
value: "fullscreen-ui", Icon={RestartIcon}
}, text="Relaunch Discord"
{ action={relaunch}
label: "HUD (Most transparent)", />
value: "hud", )}
}, {!IS_WEB && (
]} <QuickAction
select={v => (settings.macosVibrancyStyle = v)} Icon={FolderIcon}
isSelected={v => settings.macosVibrancyStyle === v} text="Open Settings Folder"
serialize={identity} action={() => showItemInFolder(settingsDir)}
/> />
</> )}
)} <QuickAction
Icon={GithubIcon}
text="View Source Code"
action={() =>
VencordNative.native.openExternal(
"https://github.com/" + gitRemote,
)
}
/>
</QuickActionCard>
</Forms.FormSection>
<Forms.FormSection <Forms.FormDivider />
className={Margins.top16}
title="Equicord Notifications" <Forms.FormSection className={Margins.top16} title="Settings" tag="h5">
tag="h5" <Forms.FormText
> className={Margins.bottom20}
<Flex> style={{ color: "var(--text-muted)" }}
<Button onClick={openNotificationSettingsModal}> >
Notification Settings Hint: You can change the position of this settings section in the{" "}
</Button> <Button
<Button onClick={openNotificationLogModal}> look={Button.Looks.BLANK}
View Notification Log style={{ color: "var(--text-link)", display: "inline-block" }}
</Button> onClick={() => openPluginModal(Vencord.Plugins.plugins.Settings)}
</Flex> >
</Forms.FormSection> settings of the Settings plugin
</SettingsTab> </Button>
); !
</Forms.FormText>
{Switches.map(
s =>
s && (
<Switch
key={s.key}
value={settings[s.key]}
onChange={v => (settings[s.key] = v)}
note={
s.warning.enabled ? (
<>
{s.note}
<div className="form-switch-warning">
{s.warning.message}
</div>
</>
) : (
s.note
)
}
>
{s.title}
</Switch>
),
)}
</Forms.FormSection>
{needsVibrancySettings && (
<>
<Forms.FormTitle tag="h5">
Window vibrancy style (requires restart)
</Forms.FormTitle>
<Select
className={Margins.bottom20}
placeholder="Window vibrancy style"
options={[
// Sorted from most opaque to most transparent
{
label: "No vibrancy",
value: undefined,
},
{
label: "Under Page (window tinting)",
value: "under-page",
},
{
label: "Content",
value: "content",
},
{
label: "Window",
value: "window",
},
{
label: "Selection",
value: "selection",
},
{
label: "Titlebar",
value: "titlebar",
},
{
label: "Header",
value: "header",
},
{
label: "Sidebar",
value: "sidebar",
},
{
label: "Tooltip",
value: "tooltip",
},
{
label: "Menu",
value: "menu",
},
{
label: "Popover",
value: "popover",
},
{
label: "Fullscreen UI (transparent but slightly muted)",
value: "fullscreen-ui",
},
{
label: "HUD (Most transparent)",
value: "hud",
},
]}
select={v => (settings.macosVibrancyStyle = v)}
isSelected={v => settings.macosVibrancyStyle === v}
serialize={identity}
/>
</>
)}
<Forms.FormSection
className={Margins.top16}
title="Equicord Notifications"
tag="h5"
>
<Flex>
<Button onClick={openNotificationSettingsModal}>
Notification Settings
</Button>
<Button onClick={openNotificationLogModal}>
View Notification Log
</Button>
</Flex>
</Forms.FormSection>
</SettingsTab>
);
} }
interface DiscordInviteProps { function DonateButtonComponent() {
invite: string; return (
image: string; <DonateButton
look={Button.Looks.FILLED}
color={Button.Colors.TRANSPARENT}
style={{ marginTop: "1em" }}
/>
);
} }
function DiscordInviteCard({ invite, image }: DiscordInviteProps) { function isVCDonor(userId: string): boolean {
return ( const donorBadges = BadgeAPI.getDonorBadges(userId);
<Card className={cl("card", "discordinvite")}> return GuildMemberStore.getMember(VC_GUILD_ID, userId)?.roles.includes(VC_DONOR_ROLE_ID) || !!donorBadges;
<div> }
<Forms.FormTitle tag="h5">Join the discord!</Forms.FormTitle>
<Forms.FormText>
Please consider joining the discord for any news on breaking changes,
or new bigger updates!
</Forms.FormText>
<Forms.FormText>
<Heart />
You can also donate to me if you'd like to support this project.
</Forms.FormText>
<div className={cl("card-buttons")}> function isDonor(userId: string): boolean {
<Button const donorBadges = BadgeAPI.getDonorBadges(userId);
className="vc-joindiscordbutton vc-settingbuttons" return GuildMemberStore.getMember(GUILD_ID, userId)?.roles.includes(DONOR_ROLE_ID) || !!donorBadges;
onClick={async e => {
e.preventDefault();
openInviteModal(invite).catch(() =>
showToast("Invalid or expired invite"),
);
}}
>
Join
</Button>
<Button
className="vc-donatebutton vc-settingbuttons"
onClick={() => {
VencordNative.native.openExternal(
"https://github.com/sponsors/verticalsync",
);
}}
>
Donate
</Button>
</div>
</div>
<img
role="presentation"
src={image}
alt=""
height={128}
style={{
marginLeft: "auto",
}}
/>
</Card>
);
} }
export default wrapTab(EquicordSettings, "Equicord Settings"); export default wrapTab(EquicordSettings, "Equicord Settings");

View file

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

View file

@ -0,0 +1,92 @@
.vc-donate-button {
overflow: visible !important;
}
.vc-donate-button .vc-heart-icon {
transition: transform 0.3s;
}
.vc-donate-button:hover .vc-heart-icon {
transform: scale(1.1);
z-index: 10;
position: relative;
}
.vc-settings-card {
padding: 1em;
margin-bottom: 1em;
}
.vc-special-card-special {
padding: 1em 1.5em;
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.2em;
font-weight: bold;
margin-top: 0.5em;
}
.vc-special-text {
color: black;
font-size: 1em;
margin-top: .75em;
white-space: pre-line;
}
.vc-special-seperator {
margin-top: .75em;
border-top: 1px solid white;
opacity: 0.4;
}
.vc-special-hyperlink {
margin-top: 1em;
cursor: pointer;
.vc-special-hyperlink-text {
color: black;
font-size: 1em;
font-weight: bold;
text-align: center;
transition: text-decoration 0.5s;
cursor: pointer;
}
&:hover .vc-special-hyperlink-text {
text-decoration: underline;
}
}
.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: 65%;
}

View file

@ -5,3 +5,8 @@
.vc-owner-crown-icon { .vc-owner-crown-icon {
color: var(--text-warning); color: var(--text-warning);
} }
.vc-heart-icon {
margin-right: 0.5em;
translate: 0 2px;
}

View file

@ -22,7 +22,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex"; import { Flex } from "@components/Flex";
import { Link } from "@components/Link"; import { Link } from "@components/Link";
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab"; import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
import { Devs, GUILD_ID, SUPPORT_CHANNEL_ID, SUPPORT_CHANNEL_IDS, VC_GUILD_ID, VC_SUPPORT_CHANNEL_ID } from "@utils/constants"; import { CONTRIB_ROLE_ID, Devs, DONOR_ROLE_ID, EQUIBOP_CONTRIB_ROLE_ID, EQUICORD_TEAM, GUILD_ID, SUPPORT_CHANNEL_ID, SUPPORT_CHANNEL_IDS, VC_CONTRIB_ROLE_ID, VC_DONOR_ROLE_ID, VC_KNOWN_ISSUES_CHANNEL_ID, VC_REGULAR_ROLE_ID, VC_SUPPORT_CHANNEL_ID, VENBOT_USER_ID, VENCORD_CONTRIB_ROLE_ID } from "@utils/constants";
import { sendMessage } from "@utils/discord"; import { sendMessage } from "@utils/discord";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
@ -40,18 +40,17 @@ import plugins, { PluginMeta } from "~plugins";
import SettingsPlugin from "./settings"; import SettingsPlugin from "./settings";
const VENBOT_USER_ID = "1017176847865352332";
const KNOWN_ISSUES_CHANNEL_ID = "1222936386626129920";
const CodeBlockRe = /```js\n(.+?)```/s; const CodeBlockRe = /```js\n(.+?)```/s;
const TrustedRolesIds = [ const TrustedRolesIds = [
"1026534353167208489", // contributor VC_CONTRIB_ROLE_ID, // Vencord Contributor
"1026504932959977532", // regular VC_REGULAR_ROLE_ID, // Vencord Regular
"1042507929485586532", // donor VC_DONOR_ROLE_ID, // Vencord Donor
"1173520023239786538", // Equicord Team EQUICORD_TEAM, // Equicord Team
"1222677964760682556", // Equicord Contributor DONOR_ROLE_ID, // Equicord Donor
"1287079931645263968", // Equibop Contributor CONTRIB_ROLE_ID, // Equicord Contributor
"1173343399470964856", // Vencord Contributor EQUIBOP_CONTRIB_ROLE_ID, // Equibop Contributor
VENCORD_CONTRIB_ROLE_ID, // Vencord Contributor
]; ];
const AsyncFunction = async function () { }.constructor; const AsyncFunction = async function () { }.constructor;
@ -261,8 +260,8 @@ export default definePlugin({
const shouldAddUpdateButton = const shouldAddUpdateButton =
!IS_UPDATER_DISABLED !IS_UPDATER_DISABLED
&& ( && (
(props.channel.id === KNOWN_ISSUES_CHANNEL_ID) || (props.channel.id === VC_KNOWN_ISSUES_CHANNEL_ID) ||
(props.channel.id === SUPPORT_CHANNEL_ID && props.message.author.id === VENBOT_USER_ID) (props.channel.id === VC_SUPPORT_CHANNEL_ID && props.message.author.id === VENBOT_USER_ID)
) )
&& props.message.content?.includes("update"); && props.message.content?.includes("update");

View file

@ -18,12 +18,29 @@
export const WEBPACK_CHUNK = "webpackChunkdiscord_app"; export const WEBPACK_CHUNK = "webpackChunkdiscord_app";
export const REACT_GLOBAL = "Vencord.Webpack.Common.React"; export const REACT_GLOBAL = "Vencord.Webpack.Common.React";
// Equicord
export const SUPPORT_CHANNEL_ID = "1297590739911573585"; export const SUPPORT_CHANNEL_ID = "1297590739911573585";
export const VC_SUPPORT_CHANNEL_ID = "1026515880080842772";
export const SUPPORT_CHANNEL_IDS = [SUPPORT_CHANNEL_ID, VC_SUPPORT_CHANNEL_ID];
export const GUILD_ID = "1173279886065029291"; export const GUILD_ID = "1173279886065029291";
export const DONOR_ROLE_ID = "1173316879083896912";
export const CONTRIB_ROLE_ID = "1222677964760682556";
export const EQUICORD_TEAM = "1173520023239786538";
export const EQUIBOP_CONTRIB_ROLE_ID = "1287079931645263968";
export const VENCORD_CONTRIB_ROLE_ID = "1173343399470964856";
// Vencord
export const VC_SUPPORT_CHANNEL_ID = "1026515880080842772";
export const VC_GUILD_ID = "1015060230222131221"; export const VC_GUILD_ID = "1015060230222131221";
export const VENBOT_USER_ID = "1017176847865352332";
export const VC_DONOR_ROLE_ID = "1042507929485586532";
export const VC_CONTRIB_ROLE_ID = "1026534353167208489";
export const VC_REGULAR_ROLE_ID = "1026504932959977532";
export const VC_KNOWN_ISSUES_CHANNEL_ID = "1222936386626129920";
export const GUILD_IDS = [GUILD_ID, VC_GUILD_ID]; export const GUILD_IDS = [GUILD_ID, VC_GUILD_ID];
export const SUPPORT_CHANNEL_IDS = [SUPPORT_CHANNEL_ID, VC_SUPPORT_CHANNEL_ID];
export const DONOR_ROLE_IDS = [DONOR_ROLE_ID, VC_DONOR_ROLE_ID];
export const CONTRIB_ROLE_IDS = [CONTRIB_ROLE_ID, EQUIBOP_CONTRIB_ROLE_ID, VENCORD_CONTRIB_ROLE_ID, VC_CONTRIB_ROLE_ID];
export interface Dev { export interface Dev {
name: string; name: string;
@ -584,6 +601,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
name: "jamesbt365", name: "jamesbt365",
id: 158567567487795200n, id: 158567567487795200n,
}, },
samsam: {
name: "samsam",
id: 836452332387565589n,
},
} satisfies Record<string, Dev>); } satisfies Record<string, Dev>);
export const EquicordDevs = Object.freeze({ export const EquicordDevs = Object.freeze({

View file

@ -60,7 +60,7 @@ export async function downloadSettingsBackup() {
} }
} }
const toast = (type: number, message: string) => const toast = (type: string, message: string) =>
Toasts.show({ Toasts.show({
type, type,
message, message,

View file

@ -152,7 +152,7 @@ export type ComboboxPopout = ComponentType<PropsWithChildren<{
}>>; }>>;
export type Button = ComponentType<PropsWithChildren<Omit<HTMLProps<HTMLButtonElement>, "size"> & { export interface ButtonProps extends PropsWithChildren<Omit<HTMLProps<HTMLButtonElement>, "size">> {
/** Button.Looks.FILLED */ /** Button.Looks.FILLED */
look?: string; look?: string;
/** Button.Colors.BRAND */ /** Button.Colors.BRAND */
@ -172,7 +172,9 @@ export type Button = ComponentType<PropsWithChildren<Omit<HTMLProps<HTMLButtonEl
submittingStartedLabel?: string; submittingStartedLabel?: string;
submittingFinishedLabel?: string; submittingFinishedLabel?: string;
}>> & { }
export type Button = ComponentType<ButtonProps> & {
BorderColors: Record<"BLACK" | "BRAND" | "BRAND_NEW" | "GREEN" | "LINK" | "PRIMARY" | "RED" | "TRANSPARENT" | "WHITE" | "YELLOW", string>; BorderColors: Record<"BLACK" | "BRAND" | "BRAND_NEW" | "GREEN" | "LINK" | "PRIMARY" | "RED" | "TRANSPARENT" | "WHITE" | "YELLOW", string>;
Colors: Record<"BRAND" | "RED" | "GREEN" | "YELLOW" | "PRIMARY" | "LINK" | "WHITE" | "BLACK" | "TRANSPARENT" | "BRAND_NEW" | "CUSTOM", string>; Colors: Record<"BRAND" | "RED" | "GREEN" | "YELLOW" | "PRIMARY" | "LINK" | "WHITE" | "BLACK" | "TRANSPARENT" | "BRAND_NEW" | "CUSTOM", string>;
Hovers: Record<"DEFAULT" | "BRAND" | "RED" | "GREEN" | "YELLOW" | "PRIMARY" | "LINK" | "WHITE" | "BLACK" | "TRANSPARENT", string>; Hovers: Record<"DEFAULT" | "BRAND" | "RED" | "GREEN" | "YELLOW" | "PRIMARY" | "LINK" | "WHITE" | "BLACK" | "TRANSPARENT", string>;

View file

@ -74,10 +74,15 @@ export let Alerts: t.Alerts;
waitFor(["show", "close"], m => Alerts = m); waitFor(["show", "close"], m => Alerts = m);
const ToastType = { const ToastType = {
MESSAGE: 0, MESSAGE: "message",
SUCCESS: 1, SUCCESS: "success",
FAILURE: 2, FAILURE: "failure",
CUSTOM: 3 CUSTOM: "custom",
CLIP: "clip",
LINK: "link",
FORWARD: "forward",
BOOKMARK: "bookmark",
CLOCK: "clock"
}; };
const ToastPosition = { const ToastPosition = {
TOP: 0, TOP: 0,
@ -90,7 +95,7 @@ export interface ToastData {
/** /**
* Toasts.Type * Toasts.Type
*/ */
type: number, type: string,
options?: ToastOptions; options?: ToastOptions;
} }
@ -113,7 +118,7 @@ export const Toasts = {
...{} as { ...{} as {
show(data: ToastData): void; show(data: ToastData): void;
pop(): void; pop(): void;
create(message: string, type: number, options?: ToastOptions): ToastData; create(message: string, type: string, options?: ToastOptions): ToastData;
} }
}; };