[UI] Fix You tab on recent versions (#142)
* Fix You tab crash * Fix You tab patch on recent versions Compatibility with older version is implemented, however, untested
This commit is contained in:
parent
3b035d537a
commit
b90cddd3d8
3 changed files with 97 additions and 37 deletions
|
@ -1,19 +1,39 @@
|
|||
import { initThemes } from "@lib/themes";
|
||||
import { instead } from "spitroast";
|
||||
|
||||
// Hoist required modules
|
||||
// This used to be in filters.ts, but things became convoluted
|
||||
|
||||
// Early find logic
|
||||
const basicFind = (prop: string) => Object.values(window.modules).find(m => m?.publicModule.exports?.[prop])?.publicModule?.exports;
|
||||
const basicFind = (filter: (m: any) => any | string) => {
|
||||
for (const key in window.modules) {
|
||||
const exp = window.modules[key]?.publicModule.exports;
|
||||
if (exp && filter(exp)) return exp;
|
||||
}
|
||||
}
|
||||
|
||||
const requireNativeComponent = basicFind(m => m?.default?.name === "requireNativeComponent");
|
||||
|
||||
if (requireNativeComponent) {
|
||||
// > "Tried to register two views with the same name DCDVisualEffectView"
|
||||
// This serves as a workaround for the crashing You tab on Android starting from version 192.x
|
||||
// How? We simply ignore it.
|
||||
instead("default", requireNativeComponent, (args, orig) => {
|
||||
try {
|
||||
return orig(...args);
|
||||
} catch {
|
||||
return () => null;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Hoist React on window
|
||||
window.React = basicFind("createElement") as typeof import("react");
|
||||
window.React = basicFind(m => m.createElement) as typeof import("react");
|
||||
|
||||
// Export ReactNative
|
||||
export const ReactNative = basicFind("AppRegistry") as typeof import("react-native");
|
||||
export const ReactNative = basicFind(m => m.AppRegistry) as typeof import("react-native");
|
||||
|
||||
// Export chroma.js
|
||||
export const chroma = basicFind("brewer") as typeof import("chroma-js");
|
||||
export const chroma = basicFind(m => m.brewer) as typeof import("chroma-js");
|
||||
|
||||
// Themes
|
||||
if (window.__vendetta_loader?.features.themes) {
|
||||
|
|
|
@ -111,6 +111,7 @@ export const getYouData = () => {
|
|||
return {
|
||||
getLayout: () => ({
|
||||
title: "Vendetta",
|
||||
label: "Vendetta",
|
||||
// We can't use our keyMap function here since `settings` is an array not an object
|
||||
settings: getRenderableScreens(true).map(s => s.key)
|
||||
}),
|
||||
|
@ -124,6 +125,7 @@ export const getYouData = () => {
|
|||
|
||||
return {
|
||||
type: "route",
|
||||
title: () => s.title,
|
||||
icon: s.icon ? getAssetIDByName(s.icon) : null,
|
||||
screen: {
|
||||
// TODO: This is bad, we should not re-convert the key casing
|
||||
|
|
|
@ -1,39 +1,37 @@
|
|||
import { i18n } from "@metro/common";
|
||||
import { findByProps } from "@metro/filters";
|
||||
import { after } from "@lib/patcher";
|
||||
import { after, before } from "@lib/patcher";
|
||||
import { getRenderableScreens, getScreens, getYouData } from "@ui/settings/data";
|
||||
|
||||
const layoutModule = findByProps("useOverviewSettings");
|
||||
const titleConfigModule = findByProps("getSettingTitleConfig");
|
||||
const miscModule = findByProps("SETTING_RELATIONSHIPS", "SETTING_RENDERER_CONFIGS");
|
||||
|
||||
// Checks for 189.4 and above
|
||||
// When dropping support for 189.3 and below, following can be done: (unless Discord changes things again)
|
||||
// const gettersModule = findByProps("getSettingListItems");
|
||||
const OLD_GETTER_FUNCTION = "getSettingSearchListItems";
|
||||
const NEW_GETTER_FUNCTION = "getSettingListItems";
|
||||
const oldGettersModule = findByProps(OLD_GETTER_FUNCTION);
|
||||
const usingNewGettersModule = !oldGettersModule;
|
||||
const getterFunctionName = usingNewGettersModule ? NEW_GETTER_FUNCTION : OLD_GETTER_FUNCTION;
|
||||
const gettersModule = oldGettersModule ?? findByProps(NEW_GETTER_FUNCTION);
|
||||
import { i18n } from "@lib/metro/common";
|
||||
|
||||
export default function patchYou() {
|
||||
const patches = new Array<Function>;
|
||||
|
||||
newYouPatch(patches) || oldYouPatch(patches);
|
||||
return () => patches.forEach(p => p?.());
|
||||
}
|
||||
|
||||
function oldYouPatch(patches: Function[]) {
|
||||
const layoutModule = findByProps("useOverviewSettings");
|
||||
const titleConfigModule = findByProps("getSettingTitleConfig");
|
||||
const miscModule = findByProps("SETTING_RELATIONSHIPS", "SETTING_RENDERER_CONFIGS");
|
||||
|
||||
// Checks for 189.4 and above
|
||||
// When dropping support for 189.3 and below, following can be done: (unless Discord changes things again)
|
||||
// const gettersModule = findByProps("getSettingListItems");
|
||||
const OLD_GETTER_FUNCTION = "getSettingSearchListItems";
|
||||
const NEW_GETTER_FUNCTION = "getSettingListItems";
|
||||
const oldGettersModule = findByProps(OLD_GETTER_FUNCTION);
|
||||
const usingNewGettersModule = !oldGettersModule;
|
||||
const getterFunctionName = usingNewGettersModule ? NEW_GETTER_FUNCTION : OLD_GETTER_FUNCTION;
|
||||
const gettersModule = oldGettersModule ?? findByProps(NEW_GETTER_FUNCTION);
|
||||
|
||||
if (!gettersModule || !layoutModule) return;
|
||||
|
||||
const patches = new Array<Function>;
|
||||
const screens = getScreens(true);
|
||||
const renderableScreens = getRenderableScreens(true);
|
||||
const data = getYouData();
|
||||
|
||||
patches.push(after("useOverviewSettings", layoutModule, (_, ret) => {
|
||||
// Add our settings
|
||||
const accountSettingsIndex = ret.findIndex((i: any) => i.title === i18n.Messages.ACCOUNT_SETTINGS);
|
||||
ret.splice(accountSettingsIndex + 1, 0, data.getLayout());
|
||||
|
||||
// Upload Logs button be gone
|
||||
const supportCategory = ret.find((i: any) => i.title === i18n.Messages.SUPPORT);
|
||||
supportCategory.settings = supportCategory.settings.filter((s: string) => s !== "UPLOAD_DEBUG_LOGS");
|
||||
}));
|
||||
patches.push(after("useOverviewSettings", layoutModule, (_, ret) => manipulateSections(ret, data.getLayout())));
|
||||
|
||||
patches.push(after("getSettingTitleConfig", titleConfigModule, (_, ret) => ({
|
||||
...ret,
|
||||
|
@ -53,16 +51,56 @@ export default function patchYou() {
|
|||
...ret.filter((i: any) => (usingNewGettersModule || !screens.map(s => s.key).includes(i.setting)))
|
||||
].map((item, index, parent) => ({ ...item, index, total: parent.length }))));
|
||||
|
||||
// TODO: We could use a proxy for these
|
||||
const oldRelationships = miscModule.SETTING_RELATIONSHIPS;
|
||||
miscModule.SETTING_RELATIONSHIPS = { ...oldRelationships, ...data.relationships };
|
||||
|
||||
const oldRendererConfigs = miscModule.SETTING_RENDERER_CONFIGS;
|
||||
|
||||
miscModule.SETTING_RELATIONSHIPS = { ...oldRelationships, ...data.relationships };
|
||||
miscModule.SETTING_RENDERER_CONFIGS = { ...oldRendererConfigs, ...data.rendererConfigs };
|
||||
|
||||
return () => {
|
||||
patches.push(() => {
|
||||
miscModule.SETTING_RELATIONSHIPS = oldRelationships;
|
||||
miscModule.SETTING_RENDERER_CONFIGS = oldRendererConfigs;
|
||||
patches.forEach(p => p());
|
||||
};
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function newYouPatch(patches: Function[]) {
|
||||
const settingsListComponents = findByProps("SearchableSettingsList");
|
||||
const settingConstantsModule = findByProps("SETTING_RENDERER_CONFIG");
|
||||
const gettersModule = findByProps("getSettingListItems");
|
||||
|
||||
if (!gettersModule || !settingsListComponents || !settingConstantsModule) return false;
|
||||
|
||||
const screens = getScreens(true);
|
||||
const data = getYouData();
|
||||
|
||||
patches.push(before("type", settingsListComponents.SearchableSettingsList, ([{ sections }]) => manipulateSections(sections, data.getLayout())));
|
||||
|
||||
patches.push(after("getSettingListSearchResultItems", gettersModule, (_, ret) => {
|
||||
ret.forEach((s: any) => screens.some(b => b.key === s.setting) && (s.breadcrumbs = ["Vendetta"]))
|
||||
}));
|
||||
|
||||
const oldRendererConfig = settingConstantsModule.SETTING_RENDERER_CONFIG;
|
||||
settingConstantsModule.SETTING_RENDERER_CONFIG = { ...oldRendererConfig, ...data.rendererConfigs };
|
||||
|
||||
patches.push(() => {
|
||||
settingConstantsModule.SETTING_RENDERER_CONFIG = oldRendererConfig;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const isLabel = (i: any, name: string) => i?.label === name || i?.title === name;
|
||||
|
||||
function manipulateSections(sections: any[], layout: any) {
|
||||
if (!Array.isArray(sections) || sections.find((i: any) => isLabel(i, "Vendetta"))) return;
|
||||
|
||||
// Add our settings
|
||||
const accountSettingsIndex = sections.findIndex((i: any) => isLabel(i, i18n.Messages.ACCOUNT_SETTINGS));
|
||||
sections.splice(accountSettingsIndex + 1, 0, layout);
|
||||
|
||||
// Upload Logs button be gone
|
||||
const supportCategory = sections.find((i: any) => isLabel(i, i18n.Messages.SUPPORT));
|
||||
if (supportCategory) supportCategory.settings = supportCategory.settings.filter((s: string) => s !== "UPLOAD_DEBUG_LOGS")
|
||||
}
|
Loading…
Reference in a new issue