diff --git a/src/equicordplugins/betterInvites/README.md b/src/equicordplugins/betterInvites/README.md new file mode 100644 index 00000000..88932178 --- /dev/null +++ b/src/equicordplugins/betterInvites/README.md @@ -0,0 +1,11 @@ +# BetterInvites + +![Inviter preview](https://github.com/user-attachments/assets/9f040e27-5540-433f-86e6-d4bd745e36a3) + +![Receiver preview](https://github.com/user-attachments/assets/00d87d09-e420-4830-a0b9-28bded1aaed7) + +# features + +- be able to see the inviter and inviter profile +- preview discoverable servers by clicking the server name +- be able to see the invite relative expiration date diff --git a/src/equicordplugins/betterInvites/index.tsx b/src/equicordplugins/betterInvites/index.tsx new file mode 100644 index 00000000..e157d077 --- /dev/null +++ b/src/equicordplugins/betterInvites/index.tsx @@ -0,0 +1,75 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import "./style.css"; + +import { EquicordDevs } from "@utils/constants"; +import { openUserProfile } from "@utils/discord"; +import { classes } from "@utils/misc"; +import definePlugin, { StartAt } from "@utils/types"; +import { findByPropsLazy } from "@webpack"; +import { Parser } from "@webpack/common"; + + +const AvatarStyles = findByPropsLazy("avatar", "zalgo"); +const GuildManager = findByPropsLazy("joinGuild"); + +interface User { + id: string; + avatar: string; + global_name: string; + username: string; +} + +function lurk(id: string) { + GuildManager.joinGuild(id, { lurker: true }) + .then(() => { GuildManager.transitionToGuildSync(id); }) + .catch(() => { throw new Error("Guild is not lurkable"); }); +} + + +export default definePlugin({ + name: "BetterInvites", + description: "See invites expiration date, view inviter profile and preview discoverable servers before joining by clicking their name", + authors: [EquicordDevs.iamme], + patches: [ + { + find: ".Messages.HUB_INVITE_ANOTHER_SCHOOL_LINK", + replacement: [ + { + match: /,(\i)&&(\(.{0,15}\i\.TooltipContainer.+)(\i\.\i\.Messages.GUEST_MEMBERSHIP_EXPLANATION)/, + replace: ",($1||((!$1)&&arguments[0].invite.expires_at)) && $2$self.RenderTip($1, $3, arguments[0].invite.expires_at)" + }, + { + match: /(\.jsx\)\(\i.\i.Info,{.+onClick):(\i\?\i:null),/, + replace: "$1:$2 || $self.Lurkable(arguments[0].invite.guild.id, arguments[0].invite.guild.features)," + }, + { + match: /(\.jsx\)\(\i\.\i\.Header,\{)text:(\i)/, + replace: "$1text: $self.Header(arguments[0].currentUserId, arguments[0].invite.inviter, $2)" + } + ] + } + ], + RenderTip(isGuest: boolean, message: string, expires_at: string) { + return <>This invite will expire {Parser.parse(``)}{isGuest ? ". " + message : ""}; + }, + Header(currentUserId: string, inviter: User | undefined, defaultMessage: string) { + return
+ {(inviter && (currentUserId !== inviter.id)) ? <> + openUserProfile(inviter.id)} + src={inviter.avatar ? `https://cdn.discordapp.com/avatars/${inviter.id}/${inviter.avatar}.webp?size=80` : "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"} + /> {inviter.global_name ? inviter.global_name.toUpperCase() : inviter.username.toUpperCase()} HAS INVITED YOU TO JOIN + : defaultMessage}
; + }, + Lurkable: (id: string, features: Iterable | undefined) => { + return new Set(features).has("DISCOVERABLE") ? () => lurk(id) : null; + }, + startAt: StartAt.WebpackReady +}); + diff --git a/src/equicordplugins/betterInvites/style.css b/src/equicordplugins/betterInvites/style.css new file mode 100644 index 00000000..0e9eaa4c --- /dev/null +++ b/src/equicordplugins/betterInvites/style.css @@ -0,0 +1,18 @@ +h3[class^="h5"]:has([class="vc-bi-header-inner"]) { + display: flex; + margin: 0 !important; +} + +.vc-bi-inviter-avatar { + margin: 0; + margin-right: 5px; + height: 16px; + width: 16px; + position: static; +} + +.vc-bi-header-inner { + display: flex; + margin: 0; + margin-bottom: 5px; +}