diff --git a/src/def.d.ts b/src/def.d.ts index 035febee..927551f4 100644 --- a/src/def.d.ts +++ b/src/def.d.ts @@ -356,6 +356,7 @@ interface LoaderIdentity { interface DiscordStyleSheet { [index: string]: any, + createStyles: >(sheet: T | (() => T)) => () => T; createThemedStyleSheet: typeof import("react-native").StyleSheet.create; } diff --git a/src/lib/fixes.ts b/src/lib/fixes.ts index 6c4397f7..135e1f0e 100644 --- a/src/lib/fixes.ts +++ b/src/lib/fixes.ts @@ -11,8 +11,10 @@ function onDispatch({ locale }: { locale: string }) { // Theming // Based on https://github.com/Aliucord/AliucordRN/blob/main/src/ui/patchTheme.ts try { - ThemeManager.overrideTheme(ThemeStore?.theme ?? "dark"); - if (AMOLEDThemeManager && UnsyncedUserSettingsStore.useAMOLEDTheme === 2) AMOLEDThemeManager.setAMOLEDThemeEnabled(true); + if (ThemeManager) { + ThemeManager.overrideTheme(ThemeStore?.theme ?? "dark"); + if (AMOLEDThemeManager && UnsyncedUserSettingsStore.useAMOLEDTheme === 2) AMOLEDThemeManager.setAMOLEDThemeEnabled(true); + } } catch(e) { logger.error("Failed to fix theme...", e); } diff --git a/src/lib/metro/common.ts b/src/lib/metro/common.ts index 80bad8a0..482993bb 100644 --- a/src/lib/metro/common.ts +++ b/src/lib/metro/common.ts @@ -1,5 +1,28 @@ +import { find, findByProps, findByStoreName } from "@metro/filters"; import { DiscordStyleSheet } from "@types"; -import { find, findByProps } from "@metro/filters"; +import { ReactNative as RN } from "@lib/preinit"; +import type { StyleSheet } from "react-native"; + +const ThemeStore = findByStoreName("ThemeStore"); +const colorResolver = findByProps("colors", "meta").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 +function createThemedStyleSheet>(sheet: T) { + for (const key in sheet) { + // @ts-ignore + sheet[key] = new Proxy(RN.StyleSheet.flatten(sheet[key]), { + get(target, prop, receiver) { + const res = Reflect.get(target, prop, receiver); + return colorResolver.isSemanticColor(res) + ? colorResolver.resolveSemanticColor(ThemeStore.theme, res) + : res + } + }); + } + + return sheet; +} // Discord export const constants = findByProps("Fonts", "Permissions"); @@ -7,7 +30,14 @@ export const channels = findByProps("getVoiceChannelId"); export const i18n = findByProps("Messages"); export const url = findByProps("openURL", "openDeeplink"); export const toasts = find(m => m.open && m.close && !m.startDrag && !m.init && !m.openReplay && !m.setAlwaysOnTop); -export const stylesheet = findByProps("createThemedStyleSheet") as DiscordStyleSheet; + +// Compatible with pre-204201 versions since createThemedStyleSheet is undefined. +export const stylesheet = { + ...find(m => m.createStyles && !m.ActionSheet), + createThemedStyleSheet, + ...findByProps("createThemedStyleSheet") as {}, +} as DiscordStyleSheet; + export const clipboard = findByProps("setString", "getString", "hasString") as typeof import("@react-native-clipboard/clipboard").default; export const assets = findByProps("registerAsset"); export const invites = findByProps("acceptInviteAndTransitionToInviteChannel"); @@ -31,4 +61,4 @@ export const moment = findByProps("isMoment") as typeof import("moment"); export { chroma } from "@lib/preinit"; // Lodash -export const lodash = findByProps("forEachRight") as typeof import("lodash"); \ No newline at end of file +export const lodash = findByProps("forEachRight") as typeof import("lodash");