refactor: introduce colors preferences and some cleanups
This commit is contained in:
parent
0fd2107473
commit
1eeed0f8b9
7 changed files with 51 additions and 32 deletions
|
|
@ -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
|
||||
|
|
|
|||
18
src/index.ts
18
src/index.ts
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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"] = {};
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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]];
|
||||
}
|
||||
|
||||
|
|
|
|||
18
src/lib/addons/themes/colors/preferences.ts
Normal file
18
src/lib/addons/themes/colors/preferences.ts
Normal 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
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue