mirror of
https://github.com/Equicord/Equicord.git
synced 2025-01-18 13:23:28 -05:00
Remove FakeProfile
This commit is contained in:
parent
ee6a447c6f
commit
de726bb51b
6 changed files with 3 additions and 722 deletions
|
@ -48,7 +48,6 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend
|
|||
- Encryptcord by Inbestigator
|
||||
- EquicordCSS by FoxStorm1 and thororen (and all respective css developers)
|
||||
- ExportContacts by dat_insanity
|
||||
- FakeProfile by Sampath
|
||||
- FindReply by newwares
|
||||
- FriendshipRanks by Samwich
|
||||
- GensokyoRadioRPC by RyanCaoDev and Prince527
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
export const BASE_URL = "https://i.sampath.tech";
|
||||
export const API_URL = BASE_URL + "/v3/users";
|
||||
export const SKU_ID_DISCORD = "100101099222222";
|
||||
export const SKU_ID = "100101099222224";
|
||||
export const GUILD_ID = "1117373291095662623";
|
||||
export const INVITE_KEY = "ffmkewQ4R7";
|
||||
export const VERSION = "v2.17";
|
|
@ -1,644 +0,0 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { addBadge, BadgePosition, ProfileBadge, removeBadge } from "@api/Badges";
|
||||
import { addDecoration, removeDecoration } from "@api/MessageDecorations";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { classNameFactory, enableStyle } from "@api/Styles";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Flex } from "@components/Flex";
|
||||
import { Link } from "@components/Link";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { copyWithToast } from "@utils/misc";
|
||||
import { closeModal, Modals, openModal } from "@utils/modal";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { Button, Forms, Toasts, Tooltip, useEffect, useState } from "@webpack/common";
|
||||
import { User } from "discord-types/general";
|
||||
import virtualMerge from "virtual-merge";
|
||||
|
||||
import { API_URL, BASE_URL, SKU_ID, SKU_ID_DISCORD, VERSION } from "./constants";
|
||||
const CustomizationSection = findByCodeLazy(".customizationSectionBackground");
|
||||
const cl = classNameFactory("vc-decoration-");
|
||||
|
||||
import style from "./style.css?managed";
|
||||
import { AvatarDecoration, Colors, fakeProfileSectionProps, UserProfile, UserProfileData } from "./types";
|
||||
|
||||
|
||||
|
||||
|
||||
let UsersData = {} as Record<string, UserProfileData>;
|
||||
const UserBadges: Record<string, ProfileBadge[]> = {};
|
||||
const updateBadgesForAllUsers = () => {
|
||||
Object.keys(UsersData).forEach(userId => {
|
||||
const newBadges = UsersData[userId].badges;
|
||||
const existingBadges = UserBadges[userId] || [];
|
||||
if (newBadges) {
|
||||
newBadges.forEach((badge, index) => {
|
||||
const existingBadge = existingBadges[index];
|
||||
|
||||
if (!existingBadge) {
|
||||
const newBadge = {
|
||||
image: badge.icon,
|
||||
position: BadgePosition.START,
|
||||
description: badge.description,
|
||||
props: {
|
||||
style: {
|
||||
borderRadius: "15%",
|
||||
transform: "scale(0.9)"
|
||||
}
|
||||
},
|
||||
shouldShow: userInfo => userInfo.userId === userId,
|
||||
onClick() {
|
||||
const modalKey = openModal(props => (
|
||||
<ErrorBoundary noop onError={() => {
|
||||
closeModal(modalKey);
|
||||
VencordNative.native.openExternal("https://github.com/sampathgujarathi/fakeProfile");
|
||||
}}>
|
||||
<Modals.ModalRoot {...props}>
|
||||
<Modals.ModalHeader>
|
||||
<Flex style={{ width: "100%", justifyContent: "center" }}>
|
||||
<Forms.FormTitle
|
||||
tag="h2"
|
||||
style={{
|
||||
width: "100%",
|
||||
textAlign: "center",
|
||||
margin: 0
|
||||
}}
|
||||
>
|
||||
fakeProfile
|
||||
</Forms.FormTitle>
|
||||
</Flex>
|
||||
</Modals.ModalHeader>
|
||||
<Modals.ModalContent>
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<img
|
||||
role="presentation"
|
||||
src="https://cdn.discordapp.com/emojis/1217777696650563614.webp"
|
||||
alt=""
|
||||
style={{ margin: "auto", display: "block" }}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ padding: "0.5em", textAlign: "center" }}>
|
||||
<Forms.FormText>
|
||||
Disclaimer: This badge is generated by the fakeProfile plugin. Please be aware that it may not represent genuine credentials or affiliations. Thank you for your understanding.
|
||||
</Forms.FormText>
|
||||
</div>
|
||||
</Modals.ModalContent>
|
||||
|
||||
</Modals.ModalRoot>
|
||||
|
||||
</ErrorBoundary>
|
||||
));
|
||||
},
|
||||
};
|
||||
|
||||
addBadge(newBadge);
|
||||
|
||||
if (!UserBadges[userId]) {
|
||||
UserBadges[userId] = [];
|
||||
}
|
||||
|
||||
UserBadges[userId].splice(index, 0, newBadge);
|
||||
}
|
||||
});
|
||||
}
|
||||
existingBadges.forEach((existingBadge, index) => {
|
||||
const badgeStillExists = newBadges && newBadges[index];
|
||||
|
||||
if (!badgeStillExists) {
|
||||
removeBadge(existingBadge);
|
||||
UserBadges[userId].splice(index, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
async function loadfakeProfile(noCache = false) {
|
||||
try {
|
||||
const init = {} as RequestInit;
|
||||
if (noCache)
|
||||
init.cache = "no-cache";
|
||||
|
||||
const response = await fetch(API_URL + "/fakeProfile", init);
|
||||
const data = await response.json();
|
||||
UsersData = data;
|
||||
} catch (error) {
|
||||
console.error("Error loading fake profile:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function getUserEffect(profileId: string) {
|
||||
return UsersData[profileId] ? UsersData[profileId].profile_effect : null;
|
||||
}
|
||||
|
||||
|
||||
function encode(primary: number, accent: number): string {
|
||||
const message = `[#${primary.toString(16).padStart(6, "0")},#${accent.toString(16).padStart(6, "0")}]`;
|
||||
const padding = "";
|
||||
const encoded = Array.from(message)
|
||||
.map(x => x.codePointAt(0))
|
||||
.filter(x => x! >= 0x20 && x! <= 0x7f)
|
||||
.map(x => String.fromCodePoint(x! + 0xe0000))
|
||||
.join("");
|
||||
|
||||
return (padding || "") + " " + encoded;
|
||||
}
|
||||
|
||||
function decode(bio: string): Array<number> | null {
|
||||
if (bio == null) return null;
|
||||
const colorString = bio.match(
|
||||
/\u{e005b}\u{e0023}([\u{e0061}-\u{e0066}\u{e0041}-\u{e0046}\u{e0030}-\u{e0039}]+?)\u{e002c}\u{e0023}([\u{e0061}-\u{e0066}\u{e0041}-\u{e0046}\u{e0030}-\u{e0039}]+?)\u{e005d}/u,
|
||||
);
|
||||
if (colorString != null) {
|
||||
const parsed = [...colorString[0]]
|
||||
.map(x => String.fromCodePoint(x.codePointAt(0)! - 0xe0000))
|
||||
.join("");
|
||||
const colors = parsed
|
||||
.substring(1, parsed.length - 1)
|
||||
.split(",")
|
||||
.map(x => parseInt(x.replace("#", "0x"), 16));
|
||||
|
||||
return colors;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const settings = definePluginSettings({
|
||||
enableProfileEffects: {
|
||||
description: "Allows you to use profile effects",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: false
|
||||
},
|
||||
enableProfileThemes: {
|
||||
description: "Allows you to use profile themes",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: false
|
||||
},
|
||||
enableCustomBadges: {
|
||||
description: "Allows you to use custom badges",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: false,
|
||||
restartNeeded: true
|
||||
},
|
||||
enableAvatarDecorations: {
|
||||
description: "Allows you to use discord avatar decorations",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: false
|
||||
},
|
||||
showCustomBadgesinmessage: {
|
||||
description: "Show custom badges in message",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: false,
|
||||
restartNeeded: true
|
||||
},
|
||||
nitroFirst: {
|
||||
description: "Banner/Avatar to use if both Nitro and fakeProfile Banner/Avatar are present",
|
||||
type: OptionType.SELECT,
|
||||
options: [
|
||||
{ label: "Nitro", value: true, default: true },
|
||||
{ label: "fakeProfile", value: false },
|
||||
]
|
||||
},
|
||||
voiceBackground: {
|
||||
description: "Use fakeProfile banners as voice chat backgrounds",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true,
|
||||
restartNeeded: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function fakeProfileSection({ hideTitle = false, hideDivider = false, noMargin = false }: fakeProfileSectionProps) {
|
||||
return <CustomizationSection
|
||||
title={!hideTitle && "fakeProfile"}
|
||||
hasBackground={true}
|
||||
hideDivider={hideDivider}
|
||||
className={noMargin && cl("section-remove-margin")}
|
||||
>
|
||||
<Flex>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
await loadfakeProfile(true);
|
||||
updateBadgesForAllUsers();
|
||||
Toasts.show({
|
||||
message: "Successfully refetched fakeProfile!",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.SUCCESS
|
||||
});
|
||||
}}
|
||||
size={Button.Sizes.SMALL}
|
||||
>
|
||||
Refetch fakeProfile
|
||||
</Button>
|
||||
</Flex>
|
||||
</CustomizationSection>;
|
||||
}
|
||||
|
||||
const openModalOnClick = () => {
|
||||
const modalKey = openModal(props => (
|
||||
<ErrorBoundary noop onError={() => {
|
||||
closeModal(modalKey);
|
||||
VencordNative.native.openExternal("https://github.com/sampathgujarathi/fakeProfile");
|
||||
}}>
|
||||
<Modals.ModalRoot {...props}>
|
||||
<Modals.ModalHeader>
|
||||
<Flex style={{ width: "100%", justifyContent: "center" }}>
|
||||
<Forms.FormTitle
|
||||
tag="h2"
|
||||
style={{
|
||||
width: "100%",
|
||||
textAlign: "center",
|
||||
margin: 0
|
||||
}}
|
||||
>
|
||||
fakeProfile
|
||||
</Forms.FormTitle>
|
||||
</Flex>
|
||||
</Modals.ModalHeader>
|
||||
<Modals.ModalContent>
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<img
|
||||
role="presentation"
|
||||
src="https://cdn.discordapp.com/emojis/1217777696650563614.webp"
|
||||
alt=""
|
||||
style={{ margin: "auto", display: "block" }}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ padding: "0.5em", textAlign: "center" }}>
|
||||
<Forms.FormText>
|
||||
Disclaimer: This badge is generated by the fakeProfile plugin. Please be aware that it may not represent genuine credentials or affiliations. Thank you for your understanding.
|
||||
</Forms.FormText>
|
||||
</div>
|
||||
</Modals.ModalContent>
|
||||
</Modals.ModalRoot>
|
||||
</ErrorBoundary>
|
||||
));
|
||||
};
|
||||
|
||||
function ImageIcon(path: string) {
|
||||
return ({ tooltip }: { tooltip: string; }) => (
|
||||
<Tooltip text={tooltip} >
|
||||
{(tooltipProps: any) => (
|
||||
<img {...tooltipProps} src={path} height={20} width={20} />
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
const BadgeIcon = ({ user, badgeImg, badgeText }: { user: User, badgeImg: string, badgeText: string; }) => {
|
||||
if (UsersData[user.id]?.badges) {
|
||||
const Icon = ImageIcon(badgeImg);
|
||||
const tooltip = badgeText;
|
||||
return <Icon tooltip={tooltip} />;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const BadgeMain = ({ user, wantMargin = true, wantTopMargin = false }: { user: User; wantMargin?: boolean; wantTopMargin?: boolean; }) => {
|
||||
|
||||
const validBadges = UsersData[user.id]?.badges;
|
||||
if (!validBadges || validBadges.length === 0) return null;
|
||||
|
||||
const icons = validBadges.map((badge, index) => (
|
||||
<div onClick={openModalOnClick} >
|
||||
<BadgeIcon
|
||||
key={index}
|
||||
user={user}
|
||||
badgeImg={badge.icon}
|
||||
badgeText={badge.description}
|
||||
/>
|
||||
</div>
|
||||
));
|
||||
|
||||
return (
|
||||
<span
|
||||
className="custom-badge"
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginLeft: wantMargin ? 4 : 0,
|
||||
verticalAlign: "top",
|
||||
position: "relative",
|
||||
top: wantTopMargin ? 2 : 0,
|
||||
padding: !wantMargin ? 1 : 0,
|
||||
gap: 2
|
||||
}}
|
||||
>
|
||||
{icons}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default definePlugin({
|
||||
name: "fakeProfile",
|
||||
description: "Unlock Discord profile effects, themes, avatar decorations, and custom badges without the need for Nitro.",
|
||||
authors: [EquicordDevs.Sampath, Devs.Alyxia, Devs.Remty, Devs.AutumnVN, Devs.pylix, Devs.TheKodeToad],
|
||||
dependencies: ["MessageDecorationsAPI"],
|
||||
start: async () => {
|
||||
enableStyle(style);
|
||||
await loadfakeProfile();
|
||||
if (settings.store.enableCustomBadges) {
|
||||
updateBadgesForAllUsers();
|
||||
}
|
||||
if (settings.store.showCustomBadgesinmessage) {
|
||||
addDecoration("custom-badge", props =>
|
||||
<ErrorBoundary noop>
|
||||
<BadgeMain user={props.message?.author} wantTopMargin={true} />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
const response = await fetch(BASE_URL + "/fakeProfile");
|
||||
const data = await response.json();
|
||||
if (data.version !== VERSION) {
|
||||
Toasts.show({
|
||||
message: "There is an update available for the fakeProfile plugin.",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.MESSAGE,
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
setInterval(async () => {
|
||||
await loadfakeProfile(true);
|
||||
if (settings.store.enableCustomBadges) {
|
||||
updateBadgesForAllUsers();
|
||||
}
|
||||
}, data.reloadInterval);
|
||||
},
|
||||
stop: () => {
|
||||
if (settings.store.showCustomBadgesinmessage) {
|
||||
removeDecoration("custom-badge");
|
||||
}
|
||||
},
|
||||
patches: [
|
||||
{
|
||||
find: "UserProfileStore",
|
||||
replacement: {
|
||||
match: /(?<=getUserProfile\(\i\){return )(\i\[\i\])/,
|
||||
replace: "$self.profileDecodeHook($1)"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "getAvatarDecorationURL:",
|
||||
replacement: {
|
||||
match: /(?<=function \i\(\i\){)(?=let{avatarDecoration)/,
|
||||
replace: "const vcDecoration = (() => { return $self.getAvatarDecorationURL(arguments[0]); })(); if (vcDecoration) return vcDecoration;"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: ".USER_SETTINGS_RESET_PROFILE_THEME",
|
||||
replacement: {
|
||||
match: /RESET_PROFILE_THEME}\)(?<=color:(\i),.{0,500}?color:(\i),.{0,500}?)/,
|
||||
replace: "$&,$self.addCopy3y3Button({primary:$1,accent:$2})"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "DefaultCustomizationSections",
|
||||
replacement: {
|
||||
match: /(?<=USER_SETTINGS_AVATAR_DECORATION},"decoration"\),)/,
|
||||
replace: "$self.fakeProfileSection(),"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: ".NITRO_BANNER,",
|
||||
replacement: {
|
||||
match: /\?\(0,\i\.jsx\)\(\i,{type:\i,shown/,
|
||||
replace: "&&$self.shouldShowBadge(arguments[0])$&"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "=!1,canUsePremiumCustomization:",
|
||||
replacement: {
|
||||
match: /(\i)\.premiumType/,
|
||||
replace: "$self.premiumHook($1)||$&"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: ".banner)==null",
|
||||
replacement: {
|
||||
match: /(?<=void 0:)\i.getPreviewBanner\(\i,\i,\i\)/,
|
||||
replace: "$self.useBannerHook(arguments[0])||$&"
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "\"data-selenium-video-tile\":",
|
||||
predicate: () => settings.store.voiceBackground,
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=function\((\i),\i\)\{)(?=let.{20,40},style:)/,
|
||||
replace: "$1.style=$self.voiceBackgroundHook($1);"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
find: "getUserAvatarURL:",
|
||||
replacement: [
|
||||
{
|
||||
match: /(getUserAvatarURL:)(\i),/,
|
||||
replace: "$1$self.getAvatarHook($2),"
|
||||
},
|
||||
{
|
||||
match: /(getUserAvatarURL:\i\(\){return )(\i)}/,
|
||||
replace: "$1$self.getAvatarHook($2)}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
find: "isAvatarDecorationAnimating:",
|
||||
group: true,
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=TryItOut:\i,guildId:\i}\),)(?<=user:(\i).+?)/,
|
||||
replace: "vcAvatarDecoration=$self.useUserAvatarDecoration($1),"
|
||||
},
|
||||
{
|
||||
match: /(?<={avatarDecoration:).{1,20}?(?=,)(?<=avatarDecorationOverride:(\i).+?)/,
|
||||
replace: "$1??vcAvatarDecoration??($&)"
|
||||
},
|
||||
{
|
||||
match: /(?<=size:\i}\),\[)/,
|
||||
replace: "vcAvatarDecoration,"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
find: "renderAvatarWithPopout(){",
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=\)\({(?:(?:.(?!\)}))*,)?avatarDecoration:)(\i)\.avatarDecoration(?=,|}\))/,
|
||||
replace: "$self.useUserAvatarDecoration($1)??$&"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
settingsAboutComponent: () => (
|
||||
|
||||
<Forms.FormSection>
|
||||
<Forms.FormTitle tag="h3">Usage</Forms.FormTitle>
|
||||
<Link href="https://github.com/sampathgujarathi/fakeProfile">CLICK HERE TO GET PROFILE EFFECTS, CUSTOM BADGES, BANNER OR ANIMATED PFP</Link>
|
||||
<Forms.FormText>
|
||||
Enable Profile Themes to use fake profile themes. <br />
|
||||
To set your own colors:
|
||||
<ul>
|
||||
<li>• go to your profile settings</li>
|
||||
<li>• choose your own colors in the Nitro preview</li>
|
||||
<li>• click the "Copy 3y3" button</li>
|
||||
<li>• paste the invisible text anywhere in your bio</li>
|
||||
</ul><br />
|
||||
</Forms.FormText>
|
||||
</Forms.FormSection>
|
||||
),
|
||||
settings,
|
||||
profileDecodeHook(user: UserProfile) {
|
||||
if (user) {
|
||||
if (settings.store.enableProfileEffects || settings.store.enableProfileThemes) {
|
||||
let mergeData: Partial<UserProfile> = {};
|
||||
const profileEffect = getUserEffect(user.userId);
|
||||
const colors = decode(user.bio);
|
||||
if (settings.store.enableProfileEffects && profileEffect) {
|
||||
mergeData = {
|
||||
...mergeData,
|
||||
profileEffectId: profileEffect
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
if (settings.store.enableProfileThemes && colors) {
|
||||
mergeData = {
|
||||
...mergeData,
|
||||
premiumType: 2,
|
||||
themeColors: colors
|
||||
};
|
||||
}
|
||||
return virtualMerge(user, mergeData as UserProfile);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
return user;
|
||||
},
|
||||
SKU_ID_DISCORD,
|
||||
SKU_ID,
|
||||
useUserAvatarDecoration(user?: User): { asset: string; skuId: string; animated: boolean; } | null {
|
||||
const [avatarDecoration, setAvatarDecoration] = useState<{ asset: string; skuId: string; animated: boolean; } | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchUserAssets = async () => {
|
||||
try {
|
||||
if (user?.id) {
|
||||
const userAssetsData = UsersData[user.id];
|
||||
if (userAssetsData?.decoration) {
|
||||
setAvatarDecoration({
|
||||
asset: userAssetsData.decoration?.asset,
|
||||
skuId: userAssetsData.decoration?.skuId,
|
||||
animated: userAssetsData.decoration?.animated
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching user assets:", error);
|
||||
}
|
||||
};
|
||||
fetchUserAssets();
|
||||
}, [user, UsersData]);
|
||||
|
||||
if (!user || !settings.store.enableAvatarDecorations) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return avatarDecoration ? {
|
||||
asset: avatarDecoration.asset,
|
||||
skuId: avatarDecoration.skuId,
|
||||
animated: avatarDecoration.animated
|
||||
} : null;
|
||||
},
|
||||
voiceBackgroundHook({ className, participantUserId }: any) {
|
||||
if (className.includes("tile_")) {
|
||||
if (UsersData[participantUserId]) {
|
||||
return {
|
||||
backgroundImage: `url(${UsersData[participantUserId].banner})`,
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
backgroundRepeat: "no-repeat"
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
useBannerHook({ displayProfile }: any) {
|
||||
if (displayProfile?.banner && settings.store.nitroFirst) return;
|
||||
if (UsersData[displayProfile?.userId] && UsersData[displayProfile?.userId].banner) return UsersData[displayProfile?.userId].banner;
|
||||
},
|
||||
|
||||
premiumHook({ userId }: any) {
|
||||
if (UsersData[userId]) return 2;
|
||||
},
|
||||
|
||||
shouldShowBadge({ displayProfile, user }: any) {
|
||||
return displayProfile?.banner && (UsersData[user.id] || settings.store.nitroFirst);
|
||||
},
|
||||
getAvatarHook: (original: any) => (user: User, animated: boolean, size: number) => {
|
||||
if (!settings.store.nitroFirst && user.avatar?.startsWith("a_")) return original(user, animated, size);
|
||||
|
||||
return UsersData[user.id]?.avatar ?? original(user, animated, size);
|
||||
},
|
||||
getAvatarDecorationURL({ avatarDecoration, canAnimate }: { avatarDecoration: AvatarDecoration | null; canAnimate?: boolean; }) {
|
||||
if (!avatarDecoration || !settings.store.enableAvatarDecorations) return;
|
||||
if (canAnimate && avatarDecoration?.animated !== false) {
|
||||
if (avatarDecoration?.skuId === SKU_ID) {
|
||||
const url = new URL(`https://i.sampath.tech/avatar-decoration-presets/a_${avatarDecoration?.asset}.png`);
|
||||
return url.toString();
|
||||
} else {
|
||||
const url = new URL(`https://cdn.discordapp.com/avatar-decoration-presets/${avatarDecoration?.asset}.png`);
|
||||
return url.toString();
|
||||
}
|
||||
} else {
|
||||
if (avatarDecoration?.skuId === SKU_ID) {
|
||||
const url = new URL(`https://i.sampath.tech/avatar-decoration-presets/${avatarDecoration?.asset}.png`);
|
||||
return url.toString();
|
||||
} else {
|
||||
const url = new URL(`https://cdn.discordapp.com/avatar-decoration-presets/${avatarDecoration?.asset}.png?passthrough=false`);
|
||||
return url.toString();
|
||||
}
|
||||
}
|
||||
},
|
||||
fakeProfileSection: ErrorBoundary.wrap(fakeProfileSection),
|
||||
toolboxActions: {
|
||||
async "Refetch fakeProfile"() {
|
||||
await loadfakeProfile(true);
|
||||
updateBadgesForAllUsers();
|
||||
Toasts.show({
|
||||
message: "Successfully refetched fakeProfile!",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.SUCCESS
|
||||
});
|
||||
}
|
||||
},
|
||||
addCopy3y3Button: ErrorBoundary.wrap(function ({ primary, accent }: Colors) {
|
||||
return <Button
|
||||
onClick={() => {
|
||||
const colorString = encode(primary, accent);
|
||||
copyWithToast(colorString);
|
||||
}}
|
||||
color={Button.Colors.PRIMARY}
|
||||
size={Button.Sizes.XLARGE}
|
||||
className={Margins.left16}
|
||||
>Copy 3y3
|
||||
</Button >;
|
||||
}, { noop: true }),
|
||||
});
|
|
@ -1,12 +0,0 @@
|
|||
:is([class*="userProfile"], [class*="userPopout"]) [class*="bannerPremium"] {
|
||||
background: center / cover no-repeat;
|
||||
}
|
||||
|
||||
[class*="NonPremium"]:has([class*="bannerPremium"]) [class*="avatarPositionNormal"],
|
||||
[class*="PremiumWithoutBanner"]:has([class*="bannerPremium"]) [class*="avatarPositionPremiumNoBanner"] {
|
||||
top: 76px;
|
||||
}
|
||||
|
||||
[style*="background-image"] [class*="background_"] {
|
||||
background-color: transparent !important;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { User } from "discord-types/general";
|
||||
|
||||
export interface Badge {
|
||||
asset: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
link?: string;
|
||||
}
|
||||
|
||||
export interface DecorationData {
|
||||
asset: string;
|
||||
skuId: string;
|
||||
animated: boolean;
|
||||
}
|
||||
export interface AvatarDecoration {
|
||||
asset: string;
|
||||
skuId: string;
|
||||
animated: boolean;
|
||||
}
|
||||
export interface UserProfile extends User {
|
||||
profileEffectId: string;
|
||||
userId: string;
|
||||
themeColors?: Array<number>;
|
||||
|
||||
}
|
||||
export interface UserProfileData {
|
||||
profile_effect: string;
|
||||
banner: string;
|
||||
avatar: string;
|
||||
badges: Badge[];
|
||||
decoration: DecorationData;
|
||||
}
|
||||
|
||||
export interface Colors {
|
||||
primary: number;
|
||||
accent: number;
|
||||
}
|
||||
|
||||
export interface fakeProfileSectionProps {
|
||||
hideTitle?: boolean;
|
||||
hideDivider?: boolean;
|
||||
noMargin?: boolean;
|
||||
}
|
|
@ -7,21 +7,21 @@
|
|||
import { CheckedTextInput } from "@components/CheckedTextInput";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { identity } from "@utils/misc";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { Card, Forms, React, Select, SnowflakeUtils, Switch } from "@webpack/common";
|
||||
|
||||
import { makeEmptyAppId } from ".";
|
||||
import { ActivityType, RpcApp, SettingsProps } from "./types";
|
||||
|
||||
|
||||
const RPCUtils = findByPropsLazy("fetchApplicationsRPC", "getRemoteIconURL");
|
||||
const fetchApplicationsRPC = findByCodeLazy("APPLICATION_RPC(", "Client ID");
|
||||
|
||||
const cachedApps: any = {};
|
||||
async function lookupApp(appId: string): Promise<RpcApp | null> {
|
||||
if (cachedApps[appId]) return cachedApps[appId];
|
||||
const socket: any = {};
|
||||
try {
|
||||
await RPCUtils.fetchApplicationsRPC(socket, appId);
|
||||
await fetchApplicationsRPC(socket, appId);
|
||||
console.log(`Lookup finished for ${socket.application.name}`);
|
||||
cachedApps[appId] = socket.application;
|
||||
return socket.application;
|
||||
|
|
Loading…
Reference in a new issue