Get rid of preinit

This commit is contained in:
amsyarasyiq 2024-02-29 20:07:55 +08:00
parent 314fa28773
commit ba8ddf55c2
7 changed files with 33 additions and 49 deletions

View file

@ -1,3 +1,3 @@
{
"include": ["dist/*.ts"]
"include": ["dist"]
}

View file

@ -1,12 +1,19 @@
/**
* Why do we need this exactly? It's simple, to fight the side effects caused by when you
* initialize modules not in the right time or when you're not supposed to.
* Back then, we had major bugs like the mixing of light and dark themes and AMOLED option getting ignored.
* Nowadays, there are only three which I can spot: Hindi timestamps, crashing on some native components and slower startup time.
* - @pylixonly
*/
import { FluxDispatcher, moment } from "@metro/common";
import logger from "@lib/utils/logger";
function onDispatch({ locale }: { locale: string }) {
// Timestamps
try {
// TODO: Test if this works with all locales
moment.locale(locale.toLowerCase());
} catch(e) {
} catch (e) {
logger.error("Failed to fix timestamps...", e);
}
@ -14,4 +21,6 @@ function onDispatch({ locale }: { locale: string }) {
FluxDispatcher.unsubscribe("I18N_LOAD_SUCCESS", onDispatch);
}
export default () => FluxDispatcher.subscribe("I18N_LOAD_SUCCESS", onDispatch);
export default () => {
FluxDispatcher.subscribe("I18N_LOAD_SUCCESS", onDispatch)
};

View file

@ -1,29 +0,0 @@
// Hoist required modules
import { isThemeSupported } from "../lib/api/native/loader";
// This used to be in filters.ts, but things became convoluted
const basicFind = (filter: (m: any) => any | string) => {
for (const key in window.modules) {
const exp = window.modules[key as unknown as number]?.publicModule.exports;
if (exp && filter(exp)) return exp;
}
}
// Hoist React on window
window.React = basicFind(m => m.createElement) as typeof import("react");
// Export ReactNative
export const ReactNative = basicFind(m => m.AppRegistry) as typeof import("react-native");
// Export chroma.js
export const chroma = basicFind(m => m.brewer) as typeof import("chroma-js");
// Themes
if (isThemeSupported()) {
try {
require("@lib/managers/themes").initThemes();
} catch (e) {
console.error("[Vendetta] Failed to initialize themes...", e);
}
}

View file

@ -1,7 +1,7 @@
import { patchLogHook } from "@lib/debug";
import { patchCommands } from "@/lib/api/commands";
import { initPlugins } from "@lib/managers/plugins";
import { patchChatBackground } from "@lib/managers/themes";
import { initThemes, patchChatBackground } from "@lib/managers/themes";
import { patchAssets } from "@/lib/api/assets";
import initSafeMode from "@ui/safeMode";
import initSettings from "@/core/ui/settings";
@ -9,8 +9,18 @@ import initFixes from "@/core/fixes";
import logger from "@lib/utils/logger";
import initWindowObject from "@lib/windowObject";
import { initCorePlugins } from "./core/plugins";
import { isThemeSupported } from "./lib/api/native/loader";
export default async () => {
// Themes
if (isThemeSupported()) {
try {
initThemes();
} catch (e) {
console.error("[Vendetta] Failed to initialize themes...", e);
}
}
// Load everything in parallel
const unloads = await Promise.all([
patchLogHook(),

View file

@ -59,7 +59,7 @@ const semanticAlternativeMap: Record<string, string> = {
async function writeTheme(theme: Theme | {}) {
if (typeof theme !== "object") throw new Error("Theme must be an object");
// Save the current theme as vendetta_theme.json. When supported by loader,
// Save the current theme as current-theme.json. When supported by loader,
// this json will be written to appropriate path and be used to theme the native side.
await createFileBackend(getThemeFilePath() || "theme.json").set(theme);
}
@ -365,7 +365,7 @@ export async function initThemes() {
patchColor();
applyTheme(currentTheme, vdThemeFallback, false);
await updateThemes();
updateThemes().catch(e => console.error("Failed to update themes", e));
}
function extractInfo(themeName: string, colorObj: any): [name: string, colorDef: any] {

View file

@ -1,5 +1,4 @@
import { find, findByProps, findByStoreName } from "@metro/filters";
import { ReactNative as RN } from "@/core/preinit";
import type { StyleSheet } from "react-native";
export interface DiscordStyleSheet {
@ -10,7 +9,7 @@ export interface DiscordStyleSheet {
const ThemeStore = findByStoreName("ThemeStore");
const colorModule = findByProps("colors", "unsafe_rawColors");
const colorResolver = colorModule.internal ?? colorModule.meta;
const colorResolver = colorModule.internal ??= colorModule.meta;
// Reimplementation of Discord's createThemedStyleSheet, which was removed since 204201
// Not exactly a 1:1 reimplementation, but sufficient to keep compatibility with existing plugins
@ -18,7 +17,7 @@ function createThemedStyleSheet<T extends StyleSheet.NamedStyles<T>>(sheet: T) {
if (!colorModule) return;
for (const key in sheet) {
// @ts-ignore
sheet[key] = new Proxy(RN.StyleSheet.flatten(sheet[key]), {
sheet[key] = new Proxy(ReactNative.StyleSheet.flatten(sheet[key]), {
get(target, prop, receiver) {
const res = Reflect.get(target, prop, receiver);
return colorResolver.isSemanticColor(res)
@ -59,14 +58,14 @@ export const Flux = findByProps("connectStores");
export const FluxDispatcher = findByProps("_currentDispatchActionType");
// React
export const React = window.React as typeof import("react");
export { ReactNative } from "@/core/preinit";
export const React = window.React = findByProps("createElement") as typeof import("react");
export const ReactNative = findByProps("AppRegistry") as typeof import("react-native");
// Moment
export const moment = findByProps("isMoment") as typeof import("moment");
// chroma.js
export { chroma } from "@/core/preinit";
export const chroma = findByProps("brewer") as typeof import("chroma-js");
// Lodash
export const lodash = findByProps("forEachRight") as typeof import("lodash");

View file

@ -1,9 +1,9 @@
import { findByProps } from "@lib/metro/filters";
import { ReactNative } from "@/core/preinit";
import { instead } from "@lib/api/patcher";
import { ReactNative } from "@/lib/metro/common";
const { ContextMenu: _ContextMenu } = findByProps("ContextMenu");
const { AccessibilityInfo } = ReactNative
const { AccessibilityInfo } = ReactNative;
type ContextMenuItem = {
label: string,
@ -47,11 +47,6 @@ export default function ContextMenu(props: ContextMenuProps) {
return <ReactNative.View ref={ref}>
<_ContextMenu
{...props}
title={props.title}
children={props.children}
triggerOnLongPress={props.triggerOnLongPress}
items={props.items}
align={props.align}
/>
</ReactNative.View>
}