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";