feat(serverProfilesToolbox): add support for profile effects, avatar decorations and clipboard

This commit is contained in:
D3SOX 2024-05-15 18:33:18 +02:00
parent 92b303b9cc
commit 554c3e2f3c
No known key found for this signature in database
GPG key ID: 39EC1673FC37B048

View file

@ -7,24 +7,59 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { Button, GuildMemberStore, UserProfileStore, UserStore } from "@webpack/common";
import {
Button,
Clipboard,
GuildMemberStore,
Text,
Toasts,
UserProfileStore,
UserStore
} from "@webpack/common";
import { GuildMember } from "discord-types/general";
const SummaryItem = findComponentByCodeLazy("borderType", "showBorder", "hideDivider");
let savedNick: string | null = null;
let savedPronouns: string | null = null;
let savedBio: string | undefined = undefined;
let savedThemeColors: number[] | undefined = undefined;
let savedBanner: string | undefined = undefined;
let savedAvatar: string | undefined = undefined;
interface SavedProfile {
nick: string | null;
pronouns: string | null;
bio: string | null;
themeColors: number[] | undefined;
banner: string | undefined;
avatar: string | undefined;
profileEffectId: string | undefined;
avatarDecoration: string | undefined;
}
const { setPendingAvatar, setPendingBanner, setPendingBio, setPendingNickname, setPendingPronouns, setPendingThemeColors }: {
const savedProfile: SavedProfile = {
nick: null,
pronouns: null,
bio: null,
themeColors: undefined,
banner: undefined,
avatar: undefined,
profileEffectId: undefined,
avatarDecoration: undefined,
};
const {
setPendingAvatar,
setPendingBanner,
setPendingBio,
setPendingNickname,
setPendingPronouns,
setPendingThemeColors,
setPendingProfileEffectId,
setPendingAvatarDecoration,
}: {
setPendingAvatar: (a: string | undefined) => void;
setPendingBanner: (a: string | undefined) => void;
setPendingBio: (a: string | undefined) => void;
setPendingBio: (a: string | null) => void;
setPendingNickname: (a: string | null) => void;
setPendingPronouns: (a: string | null) => void;
setPendingThemeColors: (a: number[] | undefined) => void;
setPendingProfileEffectId: (a: string | undefined) => void;
setPendingAvatarDecoration: (a: string | undefined) => void;
} = findByPropsLazy("setPendingNickname", "setPendingPronouns");
export default definePlugin({
@ -36,48 +71,109 @@ export default definePlugin({
const currentUser = UserStore.getCurrentUser();
const premiumType = currentUser.premiumType ?? 0;
return <SummaryItem title="Server Profiles Toolbox" hideDivider={false} forcedDivider>
<div style={{ display: "flex", gap: "5px" }}>
<Button onClick={() => {
const copy = () => {
const profile = UserProfileStore.getGuildMemberProfile(currentUser.id, guildId);
const nick = GuildMemberStore.getNick(guildId, currentUser.id);
const selfMember = GuildMemberStore.getMember(guildId, currentUser.id);
savedNick = nick ?? "";
savedPronouns = profile.pronouns;
savedBio = profile.bio;
savedThemeColors = profile.themeColors;
savedBanner = profile.banner;
savedAvatar = selfMember.avatar;
}}>
Copy profile
</Button>
<Button onClick={() => {
// set pending
setPendingNickname(savedNick);
setPendingPronouns(savedPronouns);
const selfMember = GuildMemberStore.getMember(guildId, currentUser.id) as GuildMember & { avatarDecoration: string | undefined };
savedProfile.nick = nick ?? "";
savedProfile.pronouns = profile.pronouns;
savedProfile.bio = profile.bio;
savedProfile.themeColors = profile.themeColors;
savedProfile.banner = profile.banner;
savedProfile.avatar = selfMember.avatar;
savedProfile.profileEffectId = profile.profileEffectId;
savedProfile.avatarDecoration = selfMember.avatarDecoration;
};
const paste = () => {
setPendingNickname(savedProfile.nick);
setPendingPronouns(savedProfile.pronouns);
if (premiumType === 2) {
setPendingBio(savedBio);
setPendingThemeColors(savedThemeColors);
setPendingBanner(savedBanner);
setPendingAvatar(savedAvatar);
setPendingBio(savedProfile.bio);
setPendingThemeColors(savedProfile.themeColors);
setPendingBanner(savedProfile.banner);
setPendingAvatar(savedProfile.avatar);
setPendingProfileEffectId(savedProfile.profileEffectId);
setPendingAvatarDecoration(savedProfile.avatarDecoration);
}
}}>
Paste profile
</Button>
<Button onClick={() => {
// reset
setPendingNickname("");
};
const reset = () => {
setPendingNickname(null);
setPendingPronouns("");
if (premiumType === 2) {
setPendingBio("");
setPendingBio(null);
setPendingThemeColors([]);
setPendingBanner("");
setPendingAvatar("");
setPendingBanner(undefined);
setPendingAvatar(undefined);
setPendingProfileEffectId(undefined);
setPendingAvatarDecoration(undefined);
}
}}>
};
const copyToClipboard = () => {
copy();
Clipboard.copy(JSON.stringify(savedProfile));
};
const pasteFromClipboard = async () => {
try {
const clip = await navigator.clipboard.readText();
if (!clip) {
Toasts.show({
message: "Clipboard is empty",
type: Toasts.Type.FAILURE,
id: Toasts.genId(),
});
return;
}
const clipboardProfile: SavedProfile = JSON.parse(clip);
if (!("nick" in clipboardProfile)) {
Toasts.show({
message: "Data is not in correct format",
type: Toasts.Type.FAILURE,
id: Toasts.genId(),
});
return;
}
Object.assign(savedProfile, JSON.parse(clip));
paste();
} catch (e) {
Toasts.show({
message: `Failed to read clipboard data: ${e}`,
type: Toasts.Type.FAILURE,
id: Toasts.genId(),
});
}
};
return <SummaryItem title="Server Profiles Toolbox" hideDivider={false} forcedDivider>
<div style={{ display: "flex", alignItems: "center", flexDirection: "column", gap: "5px" }}>
<Text variant="text-md/normal">
Use the following buttons to mange the currently selected server
</Text>
<div style={{ display: "flex", gap: "5px" }}>
<Button onClick={copy}>
Copy profile
</Button>
<Button onClick={paste}>
Paste profile
</Button>
<Button onClick={reset}>
Reset profile
</Button>
</div>
<div style={{ display: "flex", gap: "5px" }}>
<Button onClick={copyToClipboard}>
Copy to clipboard
</Button>
<Button onClick={pasteFromClipboard}>
Paste from clipboard
</Button>
</div>
</div>
</SummaryItem>;
},