diff --git a/src/components/PluginSettings/PluginModal.tsx b/src/components/PluginSettings/PluginModal.tsx index 1818a8bcf..7079ebfc6 100644 --- a/src/components/PluginSettings/PluginModal.tsx +++ b/src/components/PluginSettings/PluginModal.tsx @@ -18,6 +18,7 @@ import { generateId } from "@api/Commands"; import { useSettings } from "@api/Settings"; +import { disableStyle, enableStyle } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Flex } from "@components/Flex"; import { proxyLazy } from "@utils/lazy"; @@ -40,6 +41,7 @@ import { SettingSliderComponent, SettingTextComponent } from "./components"; +import hideBotTagStyle from "./userPopoutHideBotTag.css?managed"; const UserSummaryItem = LazyComponent(() => findByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers")); const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar"); @@ -50,11 +52,12 @@ interface PluginModalProps extends ModalProps { onRestartNeeded(): void; } -/** To stop discord making unwanted requests... */ -function makeDummyUser(user: { name: string, id: BigInt; }) { +function makeDummyUser(user: { username: string; id?: string; avatar?: string; }) { const newUser = new UserRecord({ - username: user.name, - id: generateId(), + username: user.username, + id: user.id ?? generateId(), + avatar: user.avatar, + /** To stop discord making unwanted requests... */ bot: true, }); FluxDispatcher.dispatch({ @@ -89,14 +92,27 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti const hasSettings = Boolean(pluginSettings && plugin.options); React.useEffect(() => { + enableStyle(hideBotTagStyle); + + let originalUser: User; (async () => { for (const user of plugin.authors.slice(0, 6)) { const author = user.id - ? await UserUtils.fetchUser(`${user.id}`).catch(() => makeDummyUser(user)) - : makeDummyUser(user); + ? await UserUtils.fetchUser(`${user.id}`) + // only show name & pfp and no actions so users cannot harass plugin devs for support (send dms, add as friend, etc) + .then(u => (originalUser = u, makeDummyUser(u))) + .catch(() => makeDummyUser({ username: user.name })) + : makeDummyUser({ username: user.name }); + setAuthors(a => [...a, author]); } })(); + + return () => { + disableStyle(hideBotTagStyle); + if (originalUser) + FluxDispatcher.dispatch({ type: "USER_UPDATE", user: originalUser }); + }; }, []); async function saveAndClose() { diff --git a/src/components/PluginSettings/userPopoutHideBotTag.css b/src/components/PluginSettings/userPopoutHideBotTag.css new file mode 100644 index 000000000..5e33e4b32 --- /dev/null +++ b/src/components/PluginSettings/userPopoutHideBotTag.css @@ -0,0 +1,3 @@ +[class|="userPopoutOuter"] [class*="botTag"] { + display: none; +} diff --git a/src/plugins/apiBadges.tsx b/src/plugins/apiBadges.tsx index 23ed6de2b..5f44d9826 100644 --- a/src/plugins/apiBadges.tsx +++ b/src/plugins/apiBadges.tsx @@ -24,15 +24,13 @@ import { Heart } from "@components/Heart"; import { Devs } from "@utils/constants"; import { Logger } from "@utils/Logger"; import { Margins } from "@utils/margins"; +import { isPluginDev } from "@utils/misc"; import { closeModal, Modals, openModal } from "@utils/modal"; import definePlugin from "@utils/types"; import { Forms, Toasts } from "@webpack/common"; const CONTRIBUTOR_BADGE = "https://cdn.discordapp.com/attachments/1033680203433660458/1092089947126780035/favicon.png"; -/** List of vencord contributor IDs */ -const contributorIds: string[] = Object.values(Devs).map(d => d.id.toString()); - const ContributorBadge: ProfileBadge = { description: "Vencord Contributor", image: CONTRIBUTOR_BADGE, @@ -43,7 +41,7 @@ const ContributorBadge: ProfileBadge = { transform: "scale(0.9)" // The image is a bit too big compared to default badges } }, - shouldShow: ({ user }) => contributorIds.includes(user.id), + shouldShow: ({ user }) => isPluginDev(user.id), link: "https://github.com/Vendicated/Vencord" }; diff --git a/src/plugins/supportHelper.tsx b/src/plugins/supportHelper.tsx index db38b375e..8b0880d19 100644 --- a/src/plugins/supportHelper.tsx +++ b/src/plugins/supportHelper.tsx @@ -18,6 +18,7 @@ import { DataStore } from "@api/index"; import { Devs, SUPPORT_CHANNEL_ID } from "@utils/constants"; +import { isPluginDev } from "@utils/misc"; import { makeCodeblock } from "@utils/text"; import definePlugin from "@utils/types"; import { isOutdated } from "@utils/updater"; @@ -74,8 +75,7 @@ ${makeCodeblock(Object.keys(plugins).filter(Vencord.Plugins.isPluginEnabled).joi async CHANNEL_SELECT({ channelId }) { if (channelId !== SUPPORT_CHANNEL_ID) return; - const myId = BigInt(UserStore.getCurrentUser().id); - if (Object.values(Devs).some(d => d.id === myId)) return; + if (isPluginDev(UserStore.getCurrentUser().id)) return; if (isOutdated && gitHash !== await DataStore.get(REMEMBER_DISMISS_KEY)) { const rememberDismiss = () => DataStore.set(REMEMBER_DISMISS_KEY, gitHash); diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 1c7047090..9671ac398 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -29,7 +29,18 @@ export const REACT_GLOBAL = "Vencord.Webpack.Common.React"; export const VENCORD_USER_AGENT = `Vencord/${gitHash}${gitRemote ? ` (https://github.com/${gitRemote})` : ""}`; export const SUPPORT_CHANNEL_ID = "1026515880080842772"; -// Add yourself here if you made a plugin +export interface Dev { + name: string; + id: bigint; + badge?: boolean; +} + +/** + * If you made a plugin or substantial contribution, add yourself here. + * This object is used for the plugin author list, as well as to add a contributor badge to your profile. + * If you wish to stay fully anonymous, feel free to set ID to 0n. + * If you are fine with attribution but don't want the badge, add badge: false + */ export const Devs = /* #__PURE__*/ Object.freeze({ Ven: { name: "Vendicated", @@ -201,7 +212,8 @@ export const Devs = /* #__PURE__*/ Object.freeze({ }, nick: { name: "nick", - id: 347884694408265729n + id: 347884694408265729n, + badge: false }, whqwert: { name: "whqwert", @@ -295,4 +307,13 @@ export const Devs = /* #__PURE__*/ Object.freeze({ name: "outfoxxed", id: 837425748435796060n }, -}); +} satisfies Record); + +// iife so #__PURE__ works correctly +export const DevsById = /* #__PURE__*/ (() => + Object.freeze(Object.fromEntries( + Object.entries(Devs) + .filter(d => d[1].id !== 0n) + .map(([_, v]) => [v.id, v] as const) + )) +)() as Record; diff --git a/src/utils/misc.tsx b/src/utils/misc.tsx index 59475cbd7..ec612a91d 100644 --- a/src/utils/misc.tsx +++ b/src/utils/misc.tsx @@ -18,6 +18,8 @@ import { Clipboard, Toasts } from "@webpack/common"; +import { DevsById } from "./constants"; + /** * Recursively merges defaults into an object and returns the same object * @param obj Object @@ -100,3 +102,5 @@ export function identity(value: T): T { // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#mobile_tablet_or_desktop // "In summary, we recommend looking for the string Mobi anywhere in the User Agent to detect a mobile device." export const isMobile = navigator.userAgent.includes("Mobi"); + +export const isPluginDev = (id: string) => Object.hasOwn(DevsById, id);