refactor: introduce colors preferences and some cleanups

This commit is contained in:
pylixonly 2024-10-21 22:46:26 +08:00
parent 0fd2107473
commit 1eeed0f8b9
7 changed files with 51 additions and 32 deletions

View file

@ -142,7 +142,8 @@ export function wrapSync<T extends Promise<any>>(store: T): Awaited<T> {
export function awaitStorage(...stores: any[]) {
return Promise.all(
stores.map(store => new Promise<void>(res => store[syncAwaitSymbol](res)))
stores.map(store =>
new Promise<void>(res => store[syncAwaitSymbol](res)))
);
}
@ -150,11 +151,14 @@ export interface StorageBackend {
get: () => unknown | Promise<unknown>;
set: (data: unknown) => void | Promise<void>;
}
const ILLEGAL_CHARS_REGEX = /[<>:"/\\|?*]/g;
const filePathFixer = (file: string): string => Platform.select({
default: file,
ios: FileManager.saveFileToGallery ? file : `Documents/${file}`,
});
const getMMKVPath = (name: string): string => {
if (ILLEGAL_CHARS_REGEX.test(name)) {
// Replace forbidden characters with hyphens

View file

@ -10,32 +10,16 @@ import { initThemes } from "@lib/addons/themes";
import { patchCommands } from "@lib/api/commands";
import { patchLogHook } from "@lib/api/debug";
import { injectFluxInterceptor } from "@lib/api/flux";
import { writeFile } from "@lib/api/native/fs";
import { isPyonLoader, isThemeSupported } from "@lib/api/native/loader";
import { patchJsx } from "@lib/api/react/jsx";
import { logger } from "@lib/utils/logger";
import { patchSettings } from "@ui/settings";
import * as lib from "./lib";
function maybeLoadThemes() {
if (!isThemeSupported()) return;
try {
if (isPyonLoader()) {
writeFile("../vendetta_theme.json", "null");
}
initThemes();
} catch (e) {
console.error("Failed to initialize themes", e);
}
}
export default async () => {
maybeLoadThemes();
// Load everything in parallel
await Promise.all([
initThemes(),
injectFluxInterceptor(),
patchSettings(),
patchLogHook(),

View file

@ -3,12 +3,13 @@ import chroma from "chroma-js";
import { omit } from "es-toolkit";
import { Platform, processColor } from "react-native";
import { colorsPref } from "./preferences";
import { ColorManifest, InternalColorDefinition } from "./types";
const tokenRef = findByProps("SemanticColor");
export function parseColorManifest(manifest: ColorManifest): InternalColorDefinition {
const resolveType = (type = "dark") => /* (ColorManager.preferences.type ?? type) */ type === "dark" ? "darker" : "light";
const resolveType = (type = "dark") => (colorsPref.type ?? type) === "dark" ? "darker" : "light";
if (manifest.spec === 3) {
const semanticColorDefinitions: InternalColorDefinition["semantic"] = {};

View file

@ -1,5 +1,7 @@
import { colorsPref } from "@lib/addons/themes/colors/preferences";
import { _colorRef } from "@lib/addons/themes/colors/updater";
import { after } from "@lib/api/patcher";
import { useObservable } from "@lib/api/storage";
import { findInReactTree } from "@lib/utils";
import { lazyDestructure } from "@lib/utils/lazy";
import { findByNameLazy, findByProps } from "@metro";
@ -12,11 +14,8 @@ const { MessagesWrapper } = lazyDestructure(() => findByProps("MessagesWrapper")
export default function patchChatBackground() {
const patches = [
after("default", MessagesWrapperConnected, (_, ret) => {
// TODO: support custom preferences
// useObservable([ColorManager.preferences]);
// if (!_colorRef.current || ColorManager.preferences.customBackground === "hidden") return ret;
if (!_colorRef.current || !_colorRef.current.background?.url) return ret;
useObservable([colorsPref]);
if (!_colorRef.current || !_colorRef.current.background?.url || colorsPref.customBackground === "hidden") return ret;
return <ImageBackground
style={{ flex: 1, height: "100%" }}
@ -25,8 +24,7 @@ export default function patchChatBackground() {
>
{ret}
</ImageBackground>;
}
),
}),
after("render", MessagesWrapper.prototype, (_, ret) => {
if (!_colorRef.current || !_colorRef.current.background?.url) return;
const messagesComponent = findInReactTree(

View file

@ -49,7 +49,7 @@ export default function patchDefinitionAndResolver() {
const [name, colorDef] = extractInfo(_colorRef.current!.reference, args[1]);
let semanticDef = _colorRef.current.semantic[name];
if (!semanticDef && _colorRef.current?.spec === 2 && name in SEMANTIC_FALLBACK_MAP) {
if (!semanticDef && _colorRef.current.spec === 2 && name in SEMANTIC_FALLBACK_MAP) {
semanticDef = _colorRef.current.semantic[SEMANTIC_FALLBACK_MAP[name]];
}

View file

@ -0,0 +1,18 @@
import { createStorage } from "@lib/api/storage";
interface BunnyColorPreferencesStorage {
selected: string | null;
type?: "dark" | "light" | null;
customBackground: "hidden" | null;
per?: Record<string, { autoUpdate?: string; } | undefined>;
}
export const colorsPref = createStorage<BunnyColorPreferencesStorage>(
"themes/colors/preferences.json",
{
dflt: {
selected: null,
customBackground: null
}
}
);

View file

@ -1,10 +1,12 @@
import { awaitStorage, createFileBackend, createMMKVBackend, createStorage, wrapSync } from "@core/vendetta/storage";
import { getStoredTheme, getThemeFilePath } from "@lib/api/native/loader";
import { writeFile } from "@lib/api/native/fs";
import { getStoredTheme, getThemeFilePath, isPyonLoader, isThemeSupported } from "@lib/api/native/loader";
import { safeFetch } from "@lib/utils";
import { Platform } from "react-native";
import initColors from "./colors";
import { applyAndroidAlphaKeys, normalizeToHex } from "./colors/parser";
import { colorsPref } from "./colors/preferences";
import { VendettaThemeManifest } from "./colors/types";
import { updateBunnyColor } from "./colors/updater";
@ -123,9 +125,21 @@ export function getThemeFromLoader(): VdThemeInfo | null {
/**
* @internal
*/
export function initThemes() {
const currentTheme = getThemeFromLoader();
initColors(currentTheme?.data ?? null);
export async function initThemes() {
if (!isThemeSupported()) return;
updateThemes().catch(e => console.error("Failed to update themes", e));
try {
if (isPyonLoader()) {
writeFile("../vendetta_theme.json", "null");
}
await awaitStorage(colorsPref);
const currentTheme = getThemeFromLoader();
initColors(currentTheme?.data ?? null);
updateThemes().catch(e => console.error("Failed to update themes", e));
} catch (e) {
console.error("Failed to initialize themes", e);
}
}