[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 { initThemes } from "@lib/themes";
|
||||||
|
import { instead } from "spitroast";
|
||||||
|
|
||||||
// Hoist required modules
|
// Hoist required modules
|
||||||
// This used to be in filters.ts, but things became convoluted
|
// This used to be in filters.ts, but things became convoluted
|
||||||
|
|
||||||
// Early find logic
|
const basicFind = (filter: (m: any) => any | string) => {
|
||||||
const basicFind = (prop: string) => Object.values(window.modules).find(m => m?.publicModule.exports?.[prop])?.publicModule?.exports;
|
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
|
// 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 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 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
|
// Themes
|
||||||
if (window.__vendetta_loader?.features.themes) {
|
if (window.__vendetta_loader?.features.themes) {
|
||||||
|
|
|
@ -111,6 +111,7 @@ export const getYouData = () => {
|
||||||
return {
|
return {
|
||||||
getLayout: () => ({
|
getLayout: () => ({
|
||||||
title: "Vendetta",
|
title: "Vendetta",
|
||||||
|
label: "Vendetta",
|
||||||
// We can't use our keyMap function here since `settings` is an array not an object
|
// We can't use our keyMap function here since `settings` is an array not an object
|
||||||
settings: getRenderableScreens(true).map(s => s.key)
|
settings: getRenderableScreens(true).map(s => s.key)
|
||||||
}),
|
}),
|
||||||
|
@ -124,6 +125,7 @@ export const getYouData = () => {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "route",
|
type: "route",
|
||||||
|
title: () => s.title,
|
||||||
icon: s.icon ? getAssetIDByName(s.icon) : null,
|
icon: s.icon ? getAssetIDByName(s.icon) : null,
|
||||||
screen: {
|
screen: {
|
||||||
// TODO: This is bad, we should not re-convert the key casing
|
// TODO: This is bad, we should not re-convert the key casing
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
import { i18n } from "@metro/common";
|
|
||||||
import { findByProps } from "@metro/filters";
|
import { findByProps } from "@metro/filters";
|
||||||
import { after } from "@lib/patcher";
|
import { after, before } from "@lib/patcher";
|
||||||
import { getRenderableScreens, getScreens, getYouData } from "@ui/settings/data";
|
import { getRenderableScreens, getScreens, getYouData } from "@ui/settings/data";
|
||||||
|
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 layoutModule = findByProps("useOverviewSettings");
|
||||||
const titleConfigModule = findByProps("getSettingTitleConfig");
|
const titleConfigModule = findByProps("getSettingTitleConfig");
|
||||||
const miscModule = findByProps("SETTING_RELATIONSHIPS", "SETTING_RENDERER_CONFIGS");
|
const miscModule = findByProps("SETTING_RELATIONSHIPS", "SETTING_RENDERER_CONFIGS");
|
||||||
|
@ -17,23 +25,13 @@ const usingNewGettersModule = !oldGettersModule;
|
||||||
const getterFunctionName = usingNewGettersModule ? NEW_GETTER_FUNCTION : OLD_GETTER_FUNCTION;
|
const getterFunctionName = usingNewGettersModule ? NEW_GETTER_FUNCTION : OLD_GETTER_FUNCTION;
|
||||||
const gettersModule = oldGettersModule ?? findByProps(NEW_GETTER_FUNCTION);
|
const gettersModule = oldGettersModule ?? findByProps(NEW_GETTER_FUNCTION);
|
||||||
|
|
||||||
export default function patchYou() {
|
|
||||||
if (!gettersModule || !layoutModule) return;
|
if (!gettersModule || !layoutModule) return;
|
||||||
|
|
||||||
const patches = new Array<Function>;
|
|
||||||
const screens = getScreens(true);
|
const screens = getScreens(true);
|
||||||
const renderableScreens = getRenderableScreens(true);
|
const renderableScreens = getRenderableScreens(true);
|
||||||
const data = getYouData();
|
const data = getYouData();
|
||||||
|
|
||||||
patches.push(after("useOverviewSettings", layoutModule, (_, ret) => {
|
patches.push(after("useOverviewSettings", layoutModule, (_, ret) => manipulateSections(ret, data.getLayout())));
|
||||||
// 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("getSettingTitleConfig", titleConfigModule, (_, ret) => ({
|
patches.push(after("getSettingTitleConfig", titleConfigModule, (_, ret) => ({
|
||||||
...ret,
|
...ret,
|
||||||
|
@ -53,16 +51,56 @@ export default function patchYou() {
|
||||||
...ret.filter((i: any) => (usingNewGettersModule || !screens.map(s => s.key).includes(i.setting)))
|
...ret.filter((i: any) => (usingNewGettersModule || !screens.map(s => s.key).includes(i.setting)))
|
||||||
].map((item, index, parent) => ({ ...item, index, total: parent.length }))));
|
].map((item, index, parent) => ({ ...item, index, total: parent.length }))));
|
||||||
|
|
||||||
// TODO: We could use a proxy for these
|
|
||||||
const oldRelationships = miscModule.SETTING_RELATIONSHIPS;
|
const oldRelationships = miscModule.SETTING_RELATIONSHIPS;
|
||||||
miscModule.SETTING_RELATIONSHIPS = { ...oldRelationships, ...data.relationships };
|
|
||||||
|
|
||||||
const oldRendererConfigs = miscModule.SETTING_RENDERER_CONFIGS;
|
const oldRendererConfigs = miscModule.SETTING_RENDERER_CONFIGS;
|
||||||
|
|
||||||
|
miscModule.SETTING_RELATIONSHIPS = { ...oldRelationships, ...data.relationships };
|
||||||
miscModule.SETTING_RENDERER_CONFIGS = { ...oldRendererConfigs, ...data.rendererConfigs };
|
miscModule.SETTING_RENDERER_CONFIGS = { ...oldRendererConfigs, ...data.rendererConfigs };
|
||||||
|
|
||||||
return () => {
|
patches.push(() => {
|
||||||
miscModule.SETTING_RELATIONSHIPS = oldRelationships;
|
miscModule.SETTING_RELATIONSHIPS = oldRelationships;
|
||||||
miscModule.SETTING_RENDERER_CONFIGS = oldRendererConfigs;
|
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