diff --git a/src/plugins/fakeProfileThemes/index.css b/src/plugins/fakeProfileThemes/index.css new file mode 100644 index 000000000..1c9bebf2d --- /dev/null +++ b/src/plugins/fakeProfileThemes/index.css @@ -0,0 +1,3 @@ +.vc-fpt-preview * { + pointer-events: none; +} diff --git a/src/plugins/fakeProfileThemes/index.tsx b/src/plugins/fakeProfileThemes/index.tsx index a1b629d10..7a6bda9a5 100644 --- a/src/plugins/fakeProfileThemes/index.tsx +++ b/src/plugins/fakeProfileThemes/index.tsx @@ -17,13 +17,17 @@ */ // This plugin is a port from Alyxia's Vendetta plugin +import "./index.css"; + import { definePluginSettings } from "@api/Settings"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import { Margins } from "@utils/margins"; -import { copyWithToast } from "@utils/misc"; +import { classes, copyWithToast } from "@utils/misc"; +import { useAwaiter } from "@utils/react"; import definePlugin, { OptionType } from "@utils/types"; -import { Button, Forms } from "@webpack/common"; +import { extractAndLoadChunksLazy, findComponentByCodeLazy } from "@webpack"; +import { Button, Flex, Forms, React, Text, UserProfileStore, UserStore, useState } from "@webpack/common"; import { User } from "discord-types/general"; import virtualMerge from "virtual-merge"; @@ -81,6 +85,34 @@ const settings = definePluginSettings({ } }); +interface ColorPickerProps { + color: number | null; + label: React.ReactElement; + showEyeDropper?: boolean; + suggestedColors?: string[]; + onChange(value: number | null): void; +} + +// I can't be bothered to figure out the semantics of this component. The +// functions surely get some event argument sent to them and they likely aren't +// all required. If anyone who wants to use this component stumbles across this +// code, you'll have to do the research yourself. +interface ProfileModalProps { + user: User; + pendingThemeColors: [number, number]; + onAvatarChange: () => void; + onBannerChange: () => void; + canUsePremiumCustomization: boolean; + hideExampleButton: boolean; + hideFakeActivity: boolean; + isTryItOutFlow: boolean; +} + +const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); +const ProfileModal = findComponentByCodeLazy('"ProfileCustomizationPreview"'); + +const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i\("(.+?)"\).then\(\i\.bind\(\i,"(.+?)"\)\)/); + export default definePlugin({ name: "FakeProfileThemes", description: "Allows profile theming by hiding the colors in your bio thanks to invisible 3y3 encoding", @@ -101,21 +133,98 @@ export default definePlugin({ } } ], - settingsAboutComponent: () => ( - - Usage - - After enabling this plugin, you will see custom colors in the profiles of other people using compatible plugins.
- To set your own colors: -
    -
  • • go to your profile settings
  • -
  • • choose your own colors in the Nitro preview
  • -
  • • click the "Copy 3y3" button
  • -
  • • paste the invisible text anywhere in your bio
  • -

- Please note: if you are using a theme which hides nitro ads, you should disable it temporarily to set colors. -
-
), + settingsAboutComponent: () => { + const existingColors = decode( + UserProfileStore.getUserProfile(UserStore.getCurrentUser().id).bio + ) ?? [0, 0]; + const [color1, setColor1] = useState(existingColors[0]); + const [color2, setColor2] = useState(existingColors[1]); + + const [, , loadingColorPickerChunk] = useAwaiter(requireColorPicker); + + return ( + + Usage + + After enabling this plugin, you will see custom colors in + the profiles of other people using compatible plugins.{" "} +
+ To set your own colors: +
    +
  • + • use the color pickers below to choose your colors +
  • +
  • • click the "Copy 3y3" button
  • +
  • • paste the invisible text anywhere in your bio
  • +

+ + Color pickers + {!loadingColorPickerChunk && ( + + + Primary + + } + onChange={(color: number) => { + setColor1(color); + }} + /> + + Accent + + } + onChange={(color: number) => { + setColor2(color); + }} + /> + + + )} + + Preview +
+ { }} + onBannerChange={() => { }} + canUsePremiumCustomization={true} + hideExampleButton={true} + hideFakeActivity={true} + isTryItOutFlow={true} + /> +
+
+
); + }, settings, colorDecodeHook(user: UserProfile) { if (user) {