From 2529ce2827b262586c82c781a3b7421e2f72a28b Mon Sep 17 00:00:00 2001 From: Ally Founder Date: Mon, 10 Aug 2026 22:05:31 -0400 Subject: [PATCH] FakeProfileThemesAndEffects: get real effects data (ProfileEffectStore doesn't exist anymore) --- .../src/lib/stores/ProfileEffectStore.ts | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/plugins/fake-profile-themes-and-effects/src/lib/stores/ProfileEffectStore.ts b/plugins/fake-profile-themes-and-effects/src/lib/stores/ProfileEffectStore.ts index e29bb4b..4a079e6 100644 --- a/plugins/fake-profile-themes-and-effects/src/lib/stores/ProfileEffectStore.ts +++ b/plugins/fake-profile-themes-and-effects/src/lib/stores/ProfileEffectStore.ts @@ -1,14 +1,33 @@ import type { ExtractAction, FluxAction, FluxStore } from "@vencord/discord-types"; -import { findByStoreName } from "@vendetta/metro"; +import { findByProps, findByStoreName } from "@vendetta/metro"; import { lazy } from "@shared/lib/lazy"; import type { CollectiblesItemType } from "@fpte/lib/records"; -// findByStoreName caches a negative result forever - a real live crash confirmed this store -// wasn't registered yet at plugin-load time, and the eager version of this permanently poisoned -// itself with undefined for the rest of the session. Every call site now has to call this as a -// function and handle it possibly still being undefined, instead of importing a plain constant. -export const getProfileEffectStore = lazy((): $ProfileEffectStore | undefined => findByStoreName("ProfileEffectStore")); +// There is no dedicated "ProfileEffectStore" anymore - confirmed live via devtools that it's +// absent from Metro's module registry even after actually using Discord's real, native Nitro +// effect picker on a Nitro account (so this isn't a lazy-loading timing issue, the store itself +// doesn't exist in the current build). Profile effects are now served from the same shop/ +// collectibles catalog used for avatar decorations and nameplates: getProfileEffectsFromCategories +// (confirmed live to return real data - 340 real effects) reads CollectiblesCategoryStore's +// categories and returns ProfileEffectConfig objects directly, not wrapped in the old +// {id, skuId, config} shape this file's ProfileEffect type expects - the adapter below rebuilds +// that shape so every other file in this plugin didn't need to change. +const getShopEffectsUtil = lazy(() => findByProps("getProfileEffectsFromCategories") as + { getProfileEffectsFromCategories(categories: unknown): ProfileEffectConfig[] } | undefined); +const getCategoryStore = lazy(() => findByStoreName("CollectiblesCategoryStore") as + { categories: unknown } | undefined); + +export const getProfileEffectStore = lazy((): { profileEffects: ProfileEffect[] } | undefined => { + const util = getShopEffectsUtil(); + const categoryStore = getCategoryStore(); + if (!util || !categoryStore) return undefined; + + const configs = util.getProfileEffectsFromCategories(categoryStore.categories) ?? []; + return { + profileEffects: configs.map((config): ProfileEffect => ({ id: config.skuId, skuId: config.skuId, config })), + }; +}); export type ProfileEffectStoreAction = ExtractAction;