ServerDrawer: fully hide GuildsBar and reclaim its space, not just replace its content
This commit is contained in:
parent
8bbfd6d7a5
commit
47da6d615c
1 changed files with 66 additions and 82 deletions
|
|
@ -1,94 +1,78 @@
|
|||
import React from "react";
|
||||
import { Pressable, Image, View } from "react-native";
|
||||
import { find, findByName, findByProps } from "@vendetta/metro";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { registerIntercept } from "./createElementIntercept";
|
||||
import { View } from "react-native";
|
||||
import { registerPropsTransform, registerTypeDetector, registerIntercept } from "./createElementIntercept";
|
||||
|
||||
const TAG = "[ServerDrawer]";
|
||||
const SD_NOTHING_TEST_ID = "ServerDrawerNothing";
|
||||
|
||||
const ChatIcon = getAssetIDByName("ChatIcon");
|
||||
const Haptic = findByProps("triggerHapticFeedback", "HapticFeedbackTypes");
|
||||
const ChannelActions = findByProps("selectPrivateChannel");
|
||||
const SelectedChannelStore = findByName("SelectedChannelStore");
|
||||
const FluxStores = findByProps("useStateFromStores");
|
||||
const useStateFromStores = FluxStores?.useStateFromStores;
|
||||
const GuildStore = findByProps("getGuildId");
|
||||
const colors = findByProps("colors", "unsafe_rawColors")?.colors;
|
||||
const Routes = findByProps("ME");
|
||||
const ME = Routes?.ME ?? "/channels/@me";
|
||||
function Nothing() {
|
||||
return React.createElement(View, {
|
||||
style: {
|
||||
display: "none",
|
||||
width: 0,
|
||||
minWidth: 0,
|
||||
maxWidth: 0,
|
||||
flexGrow: 0,
|
||||
flexShrink: 0,
|
||||
flexBasis: 0,
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
borderWidth: 0,
|
||||
overflow: "hidden",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function openDms() {
|
||||
Haptic?.triggerHapticFeedback(Haptic.HapticFeedbackTypes.SOFT);
|
||||
if (ChannelActions?.selectPrivateChannel) {
|
||||
const lastChannelId = SelectedChannelStore?.getLastSelectedChannelId?.();
|
||||
ChannelActions.selectPrivateChannel(lastChannelId);
|
||||
// The parent creates GuildsBar via its outer React.memo wrapper object, which has no own
|
||||
// .name/.displayName at all - those only exist on the memo's inner function, at
|
||||
// type.type.name/type.type.displayName.
|
||||
function isGuildsBar(type: any): boolean {
|
||||
return type?.name === "GuildsBar" || type?.displayName === "GuildsBar" ||
|
||||
type?.type?.name === "GuildsBar" || type?.type?.displayName === "GuildsBar";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
function useIsInDms(): boolean {
|
||||
try {
|
||||
return GuildStore ? useStateFromStores([GuildStore], () => {
|
||||
const guildId = GuildStore?.getGuildId?.();
|
||||
return guildId == null || guildId === ME;
|
||||
}) : false;
|
||||
} catch { return false; }
|
||||
}
|
||||
|
||||
function DmsGuildIcon() {
|
||||
const selected = useIsInDms();
|
||||
|
||||
const iconColor = selected
|
||||
? (colors?.WHITE ?? "#fff")
|
||||
: (colors?.INTERACTIVE_NORMAL ?? "#80848e");
|
||||
|
||||
return (
|
||||
<Pressable onPress={openDms} style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
|
||||
{selected ? (
|
||||
<View style={{
|
||||
position: "absolute", left: 0, top: "25%",
|
||||
width: 4, height: "50%", borderRadius: 2,
|
||||
backgroundColor: colors?.WHITE ?? "#fff",
|
||||
}} />
|
||||
) : null}
|
||||
<Image
|
||||
source={ChatIcon}
|
||||
style={{ width: 28, height: 28, tintColor: iconColor }}
|
||||
/>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
function findGuildsBar(): any {
|
||||
const byName = findByName("GuildsBar");
|
||||
if (byName) return { default: byName };
|
||||
|
||||
let mod = find((m) => {
|
||||
try { return m?.default?.type?.name === "GuildsBar"; } catch { return false; }
|
||||
});
|
||||
if (mod?.default) return mod;
|
||||
|
||||
mod = find((m) => {
|
||||
try { return m?.default?.displayName === "GuildsBar"; } catch { return false; }
|
||||
});
|
||||
if (mod?.default) return mod;
|
||||
|
||||
return null;
|
||||
for (const child of rest) if (inspect(child)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
export function patchHideGuildsBar(cleanups: (() => void)[]): boolean {
|
||||
const mod = findGuildsBar();
|
||||
if (!mod?.default) {
|
||||
console.log(TAG, "WARN: GuildsBar not found");
|
||||
return false;
|
||||
}
|
||||
const orig = mod.default;
|
||||
// Rendering GuildsBar as nothing alone still leaves its space reserved - the immediate parent
|
||||
// carries an explicit width in its own style, so display: none on the child doesn't reclaim
|
||||
// it. This zeroes the parent wrapper too once it spots the hidden marker as a child.
|
||||
registerPropsTransform(
|
||||
(props: any, _type: any, rest: any[]) =>
|
||||
hasChildWithTestID(props?.children, rest, SD_NOTHING_TEST_ID),
|
||||
(props: any) => ({
|
||||
...props,
|
||||
style: [
|
||||
props?.style,
|
||||
{
|
||||
display: "none",
|
||||
width: 0,
|
||||
minWidth: 0,
|
||||
maxWidth: 0,
|
||||
flexGrow: 0,
|
||||
flexShrink: 0,
|
||||
flexBasis: 0,
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
borderWidth: 0,
|
||||
overflow: "hidden",
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
registerIntercept(orig, DmsGuildIcon);
|
||||
|
||||
mod.default = function DmsGuildsBar() {
|
||||
return React.createElement(DmsGuildIcon);
|
||||
};
|
||||
mod.default.displayName = "GuildsBar";
|
||||
cleanups.push(() => { mod.default = orig; });
|
||||
registerTypeDetector("ServerDrawer.HideGuildsBar", isGuildsBar, (realGuildsBar) => {
|
||||
registerIntercept(realGuildsBar, Nothing, { testID: SD_NOTHING_TEST_ID }, { collapseAncestors: 6 });
|
||||
console.log(TAG, "PATCH: found a real GuildsBar reference, now rendering nothing");
|
||||
}, { persistent: true });
|
||||
console.log(TAG, "PATCH: watching for the real GuildsBar to appear");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue