ServerDrawer: revert contentPatch.tsx drawer-swap to the confirmed-working version
This commit is contained in:
parent
58ddfc1f2d
commit
4568828688
1 changed files with 41 additions and 40 deletions
|
|
@ -1,10 +1,14 @@
|
|||
import { React } from "@vendetta/metro/common";
|
||||
import { rawFind } from "../lib/rawFind";
|
||||
import ServerDrawerSheet from "../components/ServerDrawerSheet";
|
||||
import { registerIntercept, registerTypeDetector } from "../lib/createElementIntercept";
|
||||
import { registerIntercept } from "../lib/createElementIntercept";
|
||||
|
||||
const TAG = "[ServerDrawer]";
|
||||
|
||||
// rawFind, not @vendetta/metro's find - both patchExpanded and patchEmpty are retried by index.ts's
|
||||
// fast-retry loop, and Revenge's own find() permanently caches a "not found" result per call site
|
||||
// and never rescans (see rawFind.ts), which would make the retry pointless after the first
|
||||
// failed attempt.
|
||||
let cachedGestureContext: any = null;
|
||||
function getGestureContext(): any {
|
||||
if (!cachedGestureContext) {
|
||||
|
|
@ -13,50 +17,47 @@ function getGestureContext(): any {
|
|||
return cachedGestureContext;
|
||||
}
|
||||
|
||||
// Same fix as hideGuildsBar.tsx: memo-wrapped components are passed to createElement/jsx as the
|
||||
// outer wrapper object, which has no own .name/.displayName - only its nested .type does. Missing
|
||||
// that nested check meant this never matched anything, which is why Discord's real
|
||||
// QuestDockEnrolledHeader (and friends) kept running unpatched against the fake quest data.
|
||||
function isNamed(name: string) {
|
||||
return (type: any) => type?.name === name || type?.displayName === name ||
|
||||
type?.type?.name === name || type?.type?.displayName === name;
|
||||
}
|
||||
export function patchExpanded(
|
||||
cleanups: (() => void)[]
|
||||
): boolean {
|
||||
const mod = rawFind((m) => m?.type?.displayName === "QuestDockContentExpanded" || m?.type?.name === "QuestDockContentExpanded");
|
||||
if (!mod?.type) {
|
||||
console.log(TAG, "WARN: QuestDockContentExpanded not found (will retry)");
|
||||
return false;
|
||||
}
|
||||
const orig = mod.type;
|
||||
|
||||
function Nothing() {
|
||||
return null;
|
||||
}
|
||||
registerIntercept(orig, ServerDrawerSheet, { gestureContext: getGestureContext() });
|
||||
|
||||
/**
|
||||
* Reset after live verification (Key Inspector's fiber capture + Eval, same methodology that found
|
||||
* GuildsBar's bug) showed this file's original approach shares the exact same flaw: rawFind matching
|
||||
* a component by `.type.displayName`/`.type.name` across window.modules can - and here, does - match
|
||||
* a different, unrelated module than the one actually mounted. The visible symptom: Discord's real
|
||||
* QuestDockEnrolledHeader (and friends) kept running unpatched, then crashed reading properties off
|
||||
* the fake quest data useMobileQuestDock.ts hands out, because our replacement was silently mutating
|
||||
* the wrong object the whole time.
|
||||
*
|
||||
* registerTypeDetector sidesteps this the same way it does for GuildsBar: it inspects the `type`
|
||||
* argument passed directly to createElement/jsx at the moment something actually creates an element
|
||||
* with it, which is necessarily the real, live reference - there's no module-registry ambiguity
|
||||
* possible. registerIntercept then swaps that exact reference (matched by identity) for the
|
||||
* replacement on every future creation.
|
||||
*/
|
||||
export function patchExpanded(cleanups: (() => void)[]): boolean {
|
||||
registerTypeDetector(isNamed("QuestDockContentExpanded"), (real) => {
|
||||
registerIntercept(real, ServerDrawerSheetWrapper);
|
||||
console.log(TAG, "PATCH: found the real QuestDockContentExpanded, now rendering the drawer");
|
||||
});
|
||||
mod.type = function ServerDrawerPatch() {
|
||||
return <ServerDrawerSheet gestureContext={getGestureContext()} />;
|
||||
};
|
||||
cleanups.push(() => { mod.type = orig; });
|
||||
console.log(TAG, "PATCH: QuestDockContentExpanded replaced");
|
||||
return true;
|
||||
}
|
||||
|
||||
function ServerDrawerSheetWrapper() {
|
||||
return <ServerDrawerSheet gestureContext={getGestureContext()} />;
|
||||
}
|
||||
export function patchEmpty(
|
||||
name: string,
|
||||
cleanups: (() => void)[]
|
||||
): boolean {
|
||||
const mod = rawFind((m) => m?.type?.displayName === name || m?.type?.name === name);
|
||||
if (!mod?.type) {
|
||||
console.log(TAG, `WARN: ${name} not found`);
|
||||
return false;
|
||||
}
|
||||
const orig = mod.type;
|
||||
const originalComponent = orig;
|
||||
|
||||
export function patchEmpty(name: string, cleanups: (() => void)[]): boolean {
|
||||
registerTypeDetector(isNamed(name), (real) => {
|
||||
registerIntercept(real, Nothing);
|
||||
console.log(TAG, `PATCH: found the real ${name}, now rendering nothing`);
|
||||
});
|
||||
mod.type = function EmptyPatch() {
|
||||
return null;
|
||||
};
|
||||
|
||||
if (originalComponent) {
|
||||
Object.defineProperties(mod.type, Object.getOwnPropertyDescriptors(originalComponent));
|
||||
mod.type.displayName = name;
|
||||
}
|
||||
|
||||
cleanups.push(() => { mod.type = orig; });
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue