1
0
Fork 1
mirror of https://github.com/Vendicated/Vencord.git synced 2025-01-10 18:06:22 +00:00

use store instead of manual fetching

This commit is contained in:
Luna 2024-05-27 15:42:46 -04:00
parent f124164447
commit 77975c0664
3 changed files with 40 additions and 95 deletions

View file

@ -2,4 +2,4 @@
Displays nitro and USRBG banners as a background in the member list Displays nitro and USRBG banners as a background in the member list
![Adds banners to member list](https://github.com/Vendicated/Vencord/assets/44179559/d8a3a2f2-8491-4a4f-b43e-22fdf46622e5) ![](https://github.com/Vendicated/Vencord/assets/44179559/d8a3a2f2-8491-4a4f-b43e-22fdf46622e5)

View file

@ -2,7 +2,9 @@
.vc-banners-everywhere-memberlist { .vc-banners-everywhere-memberlist {
opacity: 0.8; opacity: 0.8;
-webkit-mask-image: linear-gradient(to right, transparent 20%, #fff); -webkit-mask-image: linear-gradient(to right, transparent 20%, #fff);
mask-image: linear-gradient(to right, transparent 20%, #fff);
height: 100%; height: 100%;
width: 100%;
background-size: cover; background-size: cover;
background-position: center; background-position: center;
position: absolute; position: absolute;

View file

@ -8,10 +8,13 @@ import { definePluginSettings } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles"; import { disableStyle, enableStyle } from "@api/Styles";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { RestAPI } from "@webpack/common"; import { RestAPI, UserProfileStore, useEffect, useStateFromStores } from "@webpack/common";
import { User } from "discord-types/general"; import { User } from "discord-types/general";
import style from "./index.css?managed"; import style from "./index.css";
import { fetchUserProfile, getCurrentGuild } from "@utils/discord";
import ErrorBoundary from "@components/ErrorBoundary";
import { Queue } from "@utils/Queue";
const settings = definePluginSettings({ const settings = definePluginSettings({
animate: { animate: {
@ -20,103 +23,51 @@ const settings = definePluginSettings({
default: false default: false
}, },
}); });
const data: { [key: string]: string | null; } = {};
let enabled = false; let queue = new Queue();
async function refreshVisibleMembers() {
// TODO - move away from dom query
for await (const elem of document.querySelectorAll(
'div[role="listitem"][class*="member"]'
)) {
const rect = elem.getBoundingClientRect();
if ( const useFetchMemberProfile = (userId: string): string => {
!( const profile = useStateFromStores([UserProfileStore], () => UserProfileStore.getUserProfile(userId));
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight || document.documentElement.clientHeight) &&
rect.right <=
(window.innerWidth || document.documentElement.clientWidth)
)
)
continue;
const avatar = ( useEffect(() => {
elem.querySelector('img[class*="avatar"]') as any let cancel = false;
).src.split("/");
let memberId = ""; queue.push(() => {
if (avatar[3] === "avatars") memberId = avatar[4]; if (cancel) return Promise.resolve(void 0);
else if (avatar[3] === "guilds") memberId = avatar[6]; return fetchUserProfile(userId).finally(async () => {
else continue; await new Promise<void>(resolve => setTimeout(resolve, 1000));
});
});
if (data[memberId]) continue; return () => { cancel = true; };
}, []);
let res: any;
try {
res = (await RestAPI.get({
url: `/users/${memberId}`,
})) as { body: { banner: string; }; };
} catch (e: any) {
if (e.status === 429) {
await new Promise(r => setTimeout(r, e.body.retry_after * 2000));
continue;
}
}
const { banner } = res.body;
if (!banner) {
data[memberId] = null;
continue;
}
data[
memberId
] = `https://cdn.discordapp.com/banners/${memberId}/${banner}.${banner.startsWith("a_") ? "gif" : "png"
}?size=4096`;
// Trigger a rerender via hovering
elem.dispatchEvent(
new MouseEvent("mouseover", {
bubbles: true,
cancelable: true,
view: window,
})
);
// Please dont ratelimit us :pleadey:
await new Promise(r => setTimeout(r, 1000));
}
if (enabled) {
setTimeout(refreshVisibleMembers, 1000);
}
}
if (!profile?.banner) return "";
return `https://cdn.discordapp.com/banners/${userId}/${profile.banner}`;
};
export default definePlugin({ export default definePlugin({
name: "BannersEverywhere", name: "BannersEverywhere",
description: "Displays nitro and USRBG banners in the member list", description: "Displays banners in the member list ",
authors: [Devs.ImLvna, Devs.AutumnVN], authors: [Devs.ImLvna, Devs.AutumnVN],
settings, settings,
patches: [ patches: [
{ {
find: "lostPermissionTooltipText", find: ".Messages.GUILD_OWNER,",
replacement: replacement:
{ {
// We add the banner as a property while we can still access the user id // We add the banner as a property while we can still access the user id
match: /((\i)=\i\.user.+)(,avatar:function)/, match: /verified:(\i).isVerifiedBot.*?name:null.*?(?=avatar:)/,
replace: "$1,banner:$self.memberListBannerHook($2)$3", replace: "$&banner:$self.memberListBanner({user: $1}),",
}, },
}, },
{ {
find: "apply(this,arguments)).handleKeyPress", find: "role:\"listitem\",innerRef",
replacement: replacement:
{ {
// We cant access the user id here, so we take the banner property we set earlier // We cant access the user id here, so we take the banner property we set earlier
match: /(renderInner=function.+\i=)(\i)\.children/, match: /let{avatar:\i.*?focusProps:\i.*?=(\i).*?children:\[/,
replace: "$1[$2.banner, $2.children]", replace: "$&$1.banner,"
} }
} }
@ -124,31 +75,23 @@ export default definePlugin({
start() { start() {
enableStyle(style); enableStyle(style);
enabled = true;
refreshVisibleMembers();
}, },
stop() { stop() {
enabled = false;
disableStyle(style); disableStyle(style);
}, },
memberListBannerHook(user: User) { memberListBanner: ErrorBoundary.wrap(({ user }: { user: User; }) => {
let url = this.getBanner(user.id);
if (url === "") return;
if (!settings.store.animate) url = url.replace(".gif", ".png");
let url = useFetchMemberProfile(user.id);
if (url === "") return null;
if (!settings.store.animate) url = url.replace(".gif", ".png");
return ( return (
<img src={url} className="vc-banners-everywhere-memberlist"></img> <img src={url} className="vc-banners-everywhere-memberlist"></img>
); );
}, }, { noop: true }),
getBanner(userId: string): string {
if (data[userId]) return data[userId] as string;
if (Vencord.Plugins.isPluginEnabled("USRBG") && (Vencord.Plugins.plugins.USRBG as any).data[userId]) {
data[userId] = (Vencord.Plugins.plugins.USRBG as any).data[userId];
return data[userId] as string;
}
return "";
},
}); });