From 26a06ca81f20bd017e59e920433f3faf9cfd2999 Mon Sep 17 00:00:00 2001 From: Der_Googler <54764558+DerGoogler@users.noreply.github.com> Date: Sat, 11 Nov 2023 13:01:26 +0100 Subject: [PATCH] Some changes to the Properties system --- README.md | 8 ++ Website/src/hooks/useLocalForage.ts | 65 ------------- Website/src/hooks/useModConf.tsx | 4 - Website/src/hooks/useNativeProperties.tsx | 110 +++++----------------- Website/src/hooks/useNativeStorage.tsx | 2 +- Website/src/hooks/useRepos.tsx | 1 - Website/src/index.tsx | 4 - Website/src/native/Native.ts | 1 - Website/src/native/Properties.ts | 4 +- Website/src/typings/global.d.ts | 10 +- 10 files changed, 44 insertions(+), 165 deletions(-) delete mode 100644 Website/src/hooks/useLocalForage.ts diff --git a/README.md b/README.md index 83376c87..6543a27c 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,14 @@ Introducing Magisk Module Repo Loader (MMRL) - the ultimate module manager for M - [x] Magisk Delta - [x] KernelSU +## Retive configs + +```shell +function getconf { + /system/bin/getprop "$1" "$2" | sed 's/"//g' +} +``` + ## Screenshots diff --git a/Website/src/hooks/useLocalForage.ts b/Website/src/hooks/useLocalForage.ts deleted file mode 100644 index c33b7ac9..00000000 --- a/Website/src/hooks/useLocalForage.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { useState, useEffect, useCallback, useRef } from "react"; -import localForage from "localforage"; -import pkg from "./../../package.json"; -import { useStateCallback } from "./useStateCallback"; -import { SetValue } from "./useNativeStorage"; - -type ErrorHandler = (e?: Error) => void; - -const defaultErrorHandler: ErrorHandler = (e?: Error) => { - console.error(e); -}; - -localForage.config({ - driver: localForage.INDEXEDDB, // Force WebSQL; same as using setDriver() - name: pkg.config.storage.name, - version: pkg.config.storage.version, - description: pkg.description, -}); - -export function useLocalForage(key: string, initialValue: D, errorHandler?: ErrorHandler) { - const [storedValue, setStoredValue] = useStateCallback(initialValue); - const _errorHandler = useRef(typeof errorHandler == undefined || errorHandler == null ? defaultErrorHandler : errorHandler); - - const error = (e?: Error) => { - _errorHandler.current(e); - }; - - useEffect(() => { - localForage.getItem(key).then((value) => { - if (value !== null) { - setStoredValue(value); - } else { - setStoredValue(initialValue); - } - }); - }, []); - - const setValue: SetValue = (value, callback) => { - setStoredValue(value, callback); - const newValue = value instanceof Function ? value(storedValue) : value; - localForage.setItem(key, newValue).then((_value) => { - const _newValue = _value instanceof Function ? _value(storedValue) : _value; - if (_newValue !== null) { - setStoredValue(_newValue, callback); - } else { - setStoredValue(initialValue, callback); - } - }); - }; - - const removeValue = useCallback(() => { - async function remove() { - try { - setStoredValue(initialValue); - await localForage.removeItem(key); - } catch (e) { - error(e as any); - } - } - - remove(); - }, [key]); - - return [storedValue, setValue, removeValue] as const; -} diff --git a/Website/src/hooks/useModConf.tsx b/Website/src/hooks/useModConf.tsx index 6cf24380..4bd44fff 100644 --- a/Website/src/hooks/useModConf.tsx +++ b/Website/src/hooks/useModConf.tsx @@ -1,11 +1,7 @@ import React, { createContext, useContext } from "react"; -import { colors as kolors } from "@mui/material"; import { defaultComposer } from "default-composer"; import { useNativeStorage } from "./useNativeStorage"; -import { os } from "@Native/Os"; import { SetStateAction } from "./useStateCallback"; -import { useLanguageMap } from "./../locales/declaration"; -import { useLocalForage } from "./useLocalForage"; export interface ModConf { //cli diff --git a/Website/src/hooks/useNativeProperties.tsx b/Website/src/hooks/useNativeProperties.tsx index bc95e7a7..072bbae1 100644 --- a/Website/src/hooks/useNativeProperties.tsx +++ b/Website/src/hooks/useNativeProperties.tsx @@ -8,7 +8,8 @@ import { os } from "@Native/Os"; import { Dispatch, SetStateAction, useStateCallback } from "./useStateCallback"; import { useLog } from "./native/useLog"; import { Shell } from "@Native/Shell"; -import { useNativeStorage } from "./useNativeStorage"; +import { parseJSON, useNativeStorage } from "./useNativeStorage"; +import { Properties } from "@Native/Properties"; declare global { interface WindowEventMap { @@ -18,80 +19,51 @@ declare global { export type SetValue = Dispatch, T>; -export const nativeProperties = { - setItem(key: str, val: str): void { - Shell.cmd(`setprop "${key}" "${val}"`).exec(); - }, - getItem(key: str, initialValue: str): string | "" { - return window.__properties__.get(key, initialValue); - }, -}; - -if (window.__nativeStorage__) { - window.__nativeStorage__.defineName("localstorage"); -} - -/** - * Fallback for playground - * @returns - */ -export function useNativeProperties(key: string, initialValue: str): [str, SetValue] { - if (os.isAndroid) { - return __useProperties(key, initialValue); +function convertToProperType(value: string) { + if (/^(true|1|y|yes|on)$/i.test(value)) { + return /^(true|1|y|yes|on)$/i.test(value); // Convert to boolean true + } else if (!isNaN(value as unknown as number)) { + return parseFloat(value); // Convert to number if it's a valid number } else { - return useNativeStorage(key, initialValue); + return value; // Return the original string if no conversion is possible } } -function __useProperties(key: string, initialValue: str): [str, SetValue] { +export function useNativeProperties( + key: string, + initialValue: string | boolean | number +): [string | boolean | number, SetValue] { const log = useLog("useNativeProperties"); - // Get from local storage then - - // parse stored json or return initialValue - const readValue = useCallback((): str => { + const readValue = useCallback((): string | boolean | number => { // Prevent build error "window is undefined" but keeps working if (typeof window === "undefined") { return initialValue; } - return nativeProperties.getItem(key, initialValue); - }, [initialValue, key]); - - // State to store our value - - // Pass initial state function to useState so logic is only executed once - - const [storedValue, setStoredValue] = useStateCallback(readValue); + try { + const item = Properties.get(key, String(initialValue)); - // Return a wrapped version of useState's setter function that ... + return item ? (parseJSON(item) as string | boolean | number) : initialValue; + } catch (error) { + log.w(`Error reading nativeStorage key “${key}”: ${error}`); - // ... persists the new value to localStorage. + return initialValue; + } + }, [initialValue, key]); - const setValue: SetValue = (value, callback) => { - // Prevent build error "window is undefined" but keeps working + const [storedValue, setStoredValue] = useStateCallback(readValue); + const setValue: SetValue = (value, callback) => { if (typeof window === "undefined") { log.w(`Tried setting nativeProperties key “${key}” even though environment is not a client`); } try { - // Allow value to be a function so we have the same API as useState - const newValue = value instanceof Function ? value(storedValue) : value; - - // Save to local storage - - nativeProperties.setItem(key, JSON.stringify(newValue)); - - // Save state - + Properties.set(key, JSON.stringify(newValue)); setStoredValue(newValue, callback); - - // We dispatch a custom event so every useLocalStorage hook are notified - - // window.dispatchEvent(new Event("local-storage")); } catch (error) { log.w(`Error setting localStorage key “${key}”: ${error}`); } @@ -101,39 +73,5 @@ function __useProperties(key: string, initialValue: str): [str, SetValue] { setStoredValue(readValue()); }, []); - // const handleStorageChange = useCallback( - // (event: StorageEvent | CustomEvent) => { - // if ((event as StorageEvent)?.key && (event as StorageEvent).key !== key) { - // return; - // } - - // setStoredValue(readValue()); - // }, - - // [key, readValue] - // ); - - // // this only works for other documents, not the current one - - // useEventListener("storage", handleStorageChange); - - // // this is a custom event, triggered in writeValueToLocalStorage - - // // See: useLocalStorage() - - // useEventListener("native-storage", handleStorageChange); - return [storedValue, setValue]; } - -// A wrapper for "JSON.parse()"" to support "undefined" value - -function parseJSON(value: string | null): T | Error { - try { - return value === "undefined" ? undefined : JSON.parse(value ?? ""); - } catch (e) { - console.log("parsing error on", { value }); - - return e as Error; - } -} diff --git a/Website/src/hooks/useNativeStorage.tsx b/Website/src/hooks/useNativeStorage.tsx index 462720e4..a5eeca0a 100644 --- a/Website/src/hooks/useNativeStorage.tsx +++ b/Website/src/hooks/useNativeStorage.tsx @@ -111,7 +111,7 @@ export function useNativeStorage(key: string, initialValue: T): [T, SetValue< // A wrapper for "JSON.parse()"" to support "undefined" value -function parseJSON(value: string | null): T | Error { +export function parseJSON(value: string | null): T | Error { try { return value === "undefined" ? undefined : JSON.parse(value ?? ""); } catch (e) { diff --git a/Website/src/hooks/useRepos.tsx b/Website/src/hooks/useRepos.tsx index a537b779..049c9b39 100644 --- a/Website/src/hooks/useRepos.tsx +++ b/Website/src/hooks/useRepos.tsx @@ -7,7 +7,6 @@ import _ from "underscore"; import { useSettings } from "./useSettings"; import { os } from "@Native/Os"; import { useLog } from "./native/useLog"; -import { useLocalForage } from "./useLocalForage"; export interface RepoContextActions { addRepo: (data: AddRepoData) => void; diff --git a/Website/src/index.tsx b/Website/src/index.tsx index cd7eb920..be8c86d4 100644 --- a/Website/src/index.tsx +++ b/Website/src/index.tsx @@ -22,10 +22,6 @@ import { strs } from "./locales/declaration"; ons.platform.select("android"); ons.ready(() => { - if (window.__nativeStorage__) { - window.__nativeStorage__.defineName("localstorage"); - } - customElements.define("mmrl-app", MMRLApp); customElements.define("mmrl-anchor", MMRLAnchor); diff --git a/Website/src/native/Native.ts b/Website/src/native/Native.ts index 8bf13d78..5bcdd146 100644 --- a/Website/src/native/Native.ts +++ b/Website/src/native/Native.ts @@ -16,7 +16,6 @@ export class Native implements INative { * @required true */ public constructor(i: I) { - if (typeof i === "undefined") throw new Error("No interface defined"); this._internal_interface = i; } diff --git a/Website/src/native/Properties.ts b/Website/src/native/Properties.ts index 44abc217..82f3bcfc 100644 --- a/Website/src/native/Properties.ts +++ b/Website/src/native/Properties.ts @@ -15,13 +15,15 @@ class PropertiesClass extends Native { if (this.isAndroid) { return this.interface.get(key, def); } else { - return ""; + return window.localStorage.getItem(key) || def; } } public set(key: string, value: string): void { if (this.isAndroid) { Shell.cmd(`setprop "${key}" "${value}"`).exec(); + } else { + return window.localStorage.setItem(key, value); } } } diff --git a/Website/src/typings/global.d.ts b/Website/src/typings/global.d.ts index 61c559d8..e171df06 100644 --- a/Website/src/typings/global.d.ts +++ b/Website/src/typings/global.d.ts @@ -42,6 +42,10 @@ declare global { } } + interface NativeStorage extends Storage { + getItem(key: string, def?: string): string; + } + /** * Native window properties for Android */ @@ -74,7 +78,7 @@ declare global { * * - This interface is not configurable */ - readonly __nativeStorage__: Pick & { defineName: (name: string) => void }; + readonly __nativeStorage__: NativeStorage; } namespace Terminal { @@ -101,7 +105,9 @@ declare global { export function getFile(type: string, successCallback: SuccessCallback, ErrorCallback: ErrorCallback): any; } - interface Window extends AndroidWindow {} + interface Window extends AndroidWindow { + localStorage: NativeStorage; + } const Toast: { LENGTH_LONG: "long";