ServerDrawer: hard-enforce rail hide and quest dock transparency
This commit is contained in:
parent
69053d8b33
commit
b5224eb0a1
3 changed files with 42 additions and 9 deletions
|
|
@ -216,7 +216,7 @@ function resolveReplacement(type: any, props: any, rest: any[]): { type: any; pr
|
|||
if (effectiveProps) {
|
||||
for (const { predicate, transform } of propsTransforms) {
|
||||
try {
|
||||
if (predicate(effectiveProps, type)) {
|
||||
if (predicate(effectiveProps, type, rest)) {
|
||||
effectiveProps = transform(effectiveProps);
|
||||
}
|
||||
} catch {
|
||||
|
|
@ -228,7 +228,7 @@ function resolveReplacement(type: any, props: any, rest: any[]): { type: any; pr
|
|||
if (effectiveProps) {
|
||||
for (const { predicate, replacement } of propsIntercepts) {
|
||||
try {
|
||||
if (predicate(effectiveProps, type)) {
|
||||
if (predicate(effectiveProps, type, rest)) {
|
||||
return replacement ? { type: replacement, props: effectiveProps } : null;
|
||||
}
|
||||
} catch {
|
||||
|
|
@ -333,7 +333,7 @@ export function patchCreateElement(cleanups: (() => void)[]) {
|
|||
// This is synchronous because the race we're fixing is specifically the first QuestDock render:
|
||||
// an async scan completes too late and the element is created through an unpatched runtime.
|
||||
const initialRuntimes = rawFindAll<any>(
|
||||
(m: any) => typeof m?.jsx === "function" && typeof m?.jsxs === "function",
|
||||
(m: any) => typeof m?.jsx === "function" || typeof m?.jsxs === "function" || typeof m?.jsxDEV === "function",
|
||||
);
|
||||
for (const runtime of initialRuntimes) {
|
||||
patchRuntime(runtime);
|
||||
|
|
@ -344,7 +344,7 @@ export function patchCreateElement(cleanups: (() => void)[]) {
|
|||
scanning = true;
|
||||
|
||||
rawFindAllAsync<any>(
|
||||
(m: any) => typeof m?.jsx === "function" && typeof m?.jsxs === "function",
|
||||
(m: any) => typeof m?.jsx === "function" || typeof m?.jsxs === "function" || typeof m?.jsxDEV === "function",
|
||||
).then((runtimes) => {
|
||||
for (const runtime of runtimes) {
|
||||
patchRuntime(runtime);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,18 @@ function isQuestDock(type: any): boolean {
|
|||
return QUEST_DOCK_NAMES.some((name) => isNamed(name)(type));
|
||||
}
|
||||
|
||||
const SD_DRAWER_TEST_ID = "ServerDrawer";
|
||||
|
||||
function hasChildWithTestID(children: any, rest: any[], testID: string): boolean {
|
||||
const inspect = (child: any) => child != null && typeof child === "object" && child.props?.testID === testID;
|
||||
if (children != null) {
|
||||
if (Array.isArray(children)) { if (children.some(inspect)) return true; }
|
||||
else if (inspect(children)) return true;
|
||||
}
|
||||
for (const child of rest) if (inspect(child)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function ServerDrawerSheetWrapper() {
|
||||
return <ServerDrawerSheet gestureContext={getGestureContext()} />;
|
||||
}
|
||||
|
|
@ -63,7 +75,9 @@ export function patchExpanded(cleanups: (() => void)[]): boolean {
|
|||
// Make the quest dock's wrapper(s) transparent - the ServerDrawerSheet content still renders on
|
||||
// top, but the panel/drawer background that used to be behind the quest menu is removed.
|
||||
registerPropsTransform(
|
||||
(_props: any, type: any) => questDockTypes.has(type),
|
||||
(props: any, type: any, rest: any[]) =>
|
||||
questDockTypes.has(type) ||
|
||||
hasChildWithTestID(props?.children, rest, SD_DRAWER_TEST_ID),
|
||||
(props: any) => ({ ...props, style: [props?.style, { backgroundColor: "transparent" }] }),
|
||||
);
|
||||
|
||||
|
|
@ -73,7 +87,7 @@ export function patchExpanded(cleanups: (() => void)[]): boolean {
|
|||
}, { persistent: true });
|
||||
|
||||
registerTypeDetector("ServerDrawer.Expanded", isNamed("QuestDockContentExpanded"), (real) => {
|
||||
registerIntercept(real, ServerDrawerSheetWrapper);
|
||||
registerIntercept(real, ServerDrawerSheetWrapper, { testID: SD_DRAWER_TEST_ID });
|
||||
console.log(TAG, "PATCH: QuestDockContentExpanded replaced (type detector)");
|
||||
}, { persistent: true });
|
||||
|
||||
|
|
@ -84,7 +98,7 @@ export function patchExpanded(cleanups: (() => void)[]): boolean {
|
|||
}
|
||||
|
||||
const orig = mod.type;
|
||||
registerIntercept(orig, ServerDrawerSheetWrapper);
|
||||
registerIntercept(orig, ServerDrawerSheetWrapper, { testID: SD_DRAWER_TEST_ID });
|
||||
mod.type = ServerDrawerSheetWrapper;
|
||||
cleanups.push(() => { mod.type = orig; });
|
||||
console.log(TAG, "PATCH: QuestDockContentExpanded replaced (module mutation)");
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import { registerTypeDetector, registerIntercept } from "../lib/createElementIntercept";
|
||||
import { registerPropsTransform, registerTypeDetector, registerIntercept } from "../lib/createElementIntercept";
|
||||
import { captureFiberRef } from "../lib/fiberCapture";
|
||||
|
||||
const TAG = "[ServerDrawer]";
|
||||
const SD_NOTHING_TEST_ID = "ServerDrawerNothing";
|
||||
|
||||
// Whether this capture point actually mounts depends entirely on whether the intercept below
|
||||
// fires (unverified independently of it - see lib/fiberCapture.ts for the primary, confirmed
|
||||
|
|
@ -64,12 +65,30 @@ function isGuildsBar(type: any): boolean {
|
|||
* so every future creation of it - which happens on every re-render of GuildsBar's parent, i.e.
|
||||
* whenever the rail would normally repaint - renders nothing instead.
|
||||
*/
|
||||
function hasChildWithTestID(children: any, rest: any[], testID: string): boolean {
|
||||
const inspect = (child: any) => child != null && typeof child === "object" && child.props?.testID === testID;
|
||||
if (children != null) {
|
||||
if (Array.isArray(children)) { if (children.some(inspect)) return true; }
|
||||
else if (inspect(children)) return true;
|
||||
}
|
||||
for (const child of rest) if (inspect(child)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
export function patchHideGuildsBar(cleanups: (() => void)[]): boolean {
|
||||
// Hard-enforce the GuildsBar parent's visibility by detecting the hidden Nothing child and
|
||||
// applying display: none to the rail wrapper itself.
|
||||
registerPropsTransform(
|
||||
(props: any, _type: any, rest: any[]) =>
|
||||
hasChildWithTestID(props?.children, rest, SD_NOTHING_TEST_ID),
|
||||
(props: any) => ({ ...props, style: [props?.style, { display: "none" }] }),
|
||||
);
|
||||
|
||||
// Use a stable string key so duplicate registrations from retry loops are deduped correctly.
|
||||
registerTypeDetector("ServerDrawer.HideGuildsBar", isGuildsBar, (realGuildsBar) => {
|
||||
// Ask createElementIntercept to collapse a few ancestor levels as well so wrapper
|
||||
// containers around the rail don't leave a leftover gap.
|
||||
registerIntercept(realGuildsBar, Nothing, undefined, { collapseAncestors: 6 });
|
||||
registerIntercept(realGuildsBar, Nothing, { testID: SD_NOTHING_TEST_ID }, { collapseAncestors: 6 });
|
||||
console.log(TAG, "PATCH: found a real GuildsBar reference, now rendering nothing");
|
||||
}, { persistent: true });
|
||||
cleanups.push(() => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue