From 00b1b7a52e27f4dc1937e703d782a5a12ea5c858 Mon Sep 17 00:00:00 2001 From: Der_Googler <54764558+DerGoogler@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:11:16 +0200 Subject: [PATCH] Inprove ModConf --- Android/app/release/output-metadata.json | 56 ++- Website/src/activitys/ConfigureActivity.tsx | 4 +- Website/src/activitys/ModuleTreeConf.tsx | 328 +++++------------- Website/src/activitys/SettingsActivity.tsx | 2 +- Website/src/activitys/TerminalActivity.tsx | 6 +- .../fragments/DeviceModuleFragment.tsx | 4 +- Website/src/components/DeviceModule.tsx | 28 +- Website/src/hooks/useSettings.tsx | 119 +++++-- 8 files changed, 260 insertions(+), 287 deletions(-) diff --git a/Android/app/release/output-metadata.json b/Android/app/release/output-metadata.json index 20fcbce2..78561d9a 100644 --- a/Android/app/release/output-metadata.json +++ b/Android/app/release/output-metadata.json @@ -8,12 +8,64 @@ "variantName": "release", "elements": [ { - "type": "SINGLE", + "type": "UNIVERSAL", "filters": [], "attributes": [], "versionCode": 165, "versionName": "1.6.5", - "outputFile": "app-release.apk" + "outputFile": "app-universal-release.apk" + }, + { + "type": "ONE_OF_MANY", + "filters": [ + { + "filterType": "ABI", + "value": "x86_64" + } + ], + "attributes": [], + "versionCode": 165, + "versionName": "1.6.5", + "outputFile": "app-x86_64-release.apk" + }, + { + "type": "ONE_OF_MANY", + "filters": [ + { + "filterType": "ABI", + "value": "arm64-v8a" + } + ], + "attributes": [], + "versionCode": 165, + "versionName": "1.6.5", + "outputFile": "app-arm64-v8a-release.apk" + }, + { + "type": "ONE_OF_MANY", + "filters": [ + { + "filterType": "ABI", + "value": "armeabi-v7a" + } + ], + "attributes": [], + "versionCode": 165, + "versionName": "1.6.5", + "outputFile": "app-armeabi-v7a-release.apk" + }, + { + "type": "ONE_OF_MANY", + "filters": [ + { + "filterType": "ABI", + "value": "x86" + } + ], + "attributes": [], + "versionCode": 165, + "versionName": "1.6.5", + "outputFile": "app-x86-release.apk" } ], "elementType": "File" diff --git a/Website/src/activitys/ConfigureActivity.tsx b/Website/src/activitys/ConfigureActivity.tsx index 1c760ca4..fe949ed7 100644 --- a/Website/src/activitys/ConfigureActivity.tsx +++ b/Website/src/activitys/ConfigureActivity.tsx @@ -83,12 +83,12 @@ const DialogEditListItem = ({ const ConfigureActivity = () => { const log = useLog("ConfigureActivity"); const { strings } = useStrings(); - const { settings } = useSettings(); + const { settings, modConf } = useSettings(); const { theme } = useTheme(); const { context, extra } = useActivity(); const config: string = React.useMemo(() => { - const file = new SuFile(`${settings.mod_tree}/${extra.moduleid}/system/usr/share/mmrl/config/${extra.moduleid}.mdx`); + const file = new SuFile(modConf("CONFIG", { MODID: extra.moduleid })); if (file.exist()) { return file.read(); diff --git a/Website/src/activitys/ModuleTreeConf.tsx b/Website/src/activitys/ModuleTreeConf.tsx index f1bc6fad..c29726b7 100644 --- a/Website/src/activitys/ModuleTreeConf.tsx +++ b/Website/src/activitys/ModuleTreeConf.tsx @@ -6,7 +6,7 @@ import { Page } from "@Components/onsenui/Page"; import { Magisk } from "@Native/Magisk"; import { useStrings } from "@Hooks/useStrings"; import { useActivity } from "@Hooks/useActivity"; -import { accent_colors, colors, useSettings } from "@Hooks/useSettings"; +import { ModConf, accent_colors, colors, useSettings } from "@Hooks/useSettings"; import { StyledListItemText } from "@Components/StyledListItemText"; import { ListPickerItem } from "@Components/ListPickerItem"; import { languages_map } from "../locales/languages"; @@ -17,17 +17,17 @@ import { useRepos } from "@Hooks/useRepos"; import { Shell } from "@Native/Shell"; import { DialogEditTextListItem } from "@Components/DialogEditTextListItem"; import { KernelSULogo } from "@Components/icon/KernelSULogo"; +import React from "react"; function ModuleTreeConf() { const { context } = useActivity(); const { strings } = useStrings(); const { setRepos } = useRepos(); - const { patchSettings } = useSettings(); const { theme, scheme } = useTheme(); // Prefs - const { settings, setSettings } = useSettings(); + const { _modConf, setModConf } = useSettings(); const renderToolbar = () => { return ( @@ -53,26 +53,26 @@ function ModuleTreeConf() { { if (value) { - setSettings("mod_msu_cli", value); + setModConf("MSUCLI", value); } }} > - + { if (value) { - setSettings("mod_ksu_cli", value); + setModConf("KSUCLI", value); } }} > @@ -83,216 +83,129 @@ function ModuleTreeConf() { KernelSU install cli } - secondary={settings.mod_ksu_cli} + secondary={_modConf.KSUCLI} /> ({ bgcolor: theme.palette.background.default })}>Default paths}> + { + if (value) { + setModConf("ADB", value); + } + }} + > + + { if (value) { - setSettings("mod_tree", value); + setModConf("MODULES", value); } }} > - + - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Module properties location" - initialValue={settings.mod_prop} + initialValue={_modConf.PROPS} onSuccess={(value) => { if (value) { - setSettings("mod_prop", value); + setModConf("PROPS", value); } }} > - + - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Module system properties location" - disabled - initialValue={settings.mod_system} + initialValue={_modConf.SYSTEM} onSuccess={(value) => { if (value) { - setSettings("mod_system", value); + setModConf("SYSTEM", value); } }} > - + - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Module sepolicy rules location" - disabled - initialValue={settings.mod_sepolicy} + initialValue={_modConf.SEPOLICY} onSuccess={(value) => { if (value) { - setSettings("mod_sepolicy", value); + setModConf("SEPOLICY", value); } }} > - + + + {}} + > + ({ bgcolor: theme.palette.background.default })}>Service path}> - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Late service location" - initialValue={settings.mod_late_service} + initialValue={_modConf.LATESERVICE} onSuccess={(value) => { if (value) { - setSettings("mod_late_service", value); + setModConf("LATESERVICE", value); } }} > - + - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Post service location" - initialValue={settings.mod_post_service} + initialValue={_modConf.POSTSERVICE} onSuccess={(value) => { if (value) { - setSettings("mod_post_service", value); + setModConf("POSTSERVICE", value); } }} > - + - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Mounted service location" disabled={!Shell.isKernelSU()} - initialValue={settings.mod_mounted} + initialValue={_modConf.POSTMOUNT} onSuccess={(value) => { if (value) { - setSettings("mod_mounted", value); + setModConf("POSTMOUNT", value); } }} > @@ -303,37 +216,19 @@ function ModuleTreeConf() { Mounted service location } - secondary={settings.mod_mounted} + secondary={_modConf.POSTMOUNT} /> - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Boot complete service location" disabled={!Shell.isKernelSU()} - initialValue={settings.mod_boot} + initialValue={_modConf.BOOTCOMP} onSuccess={(value) => { if (value) { - setSettings("mod_boot", value); + setModConf("BOOTCOMP", value); } }} > @@ -344,7 +239,7 @@ function ModuleTreeConf() { Boot complete service location } - secondary={settings.mod_boot} + secondary={_modConf.BOOTCOMP} /> @@ -353,100 +248,59 @@ function ModuleTreeConf() { ({ bgcolor: theme.palette.background.default })}>Status path}> - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Module skip mount location" - initialValue={settings.mod_s_mount} - disabled + initialValue={_modConf.SKIPMOUNT} onSuccess={(value) => { if (value) { - setSettings("mod_s_mount", value); + setModConf("SKIPMOUNT", value); } }} > - + - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" type="text" title="Module disable location" - initialValue={settings.mod_disable} + initialValue={_modConf.DISABLE} onSuccess={(value) => { if (value) { - setSettings("mod_disable", value); + setModConf("DISABLE", value); } }} > - + - {settings.mod_tree}/ - (theme.palette.mode === "dark" ? scheme[900] : scheme[50]), - color: (theme) => (theme.palette.mode === "dark" ? "#fff" : scheme[700]), - }} - > - MODID - - / - - } + inputLabel="Path" + type="text" + title="Module remove location" + initialValue={_modConf.REMOVE} + onSuccess={(value) => { + if (value) { + setModConf("REMOVE", value); + } + }} + > + + + + { if (value) { - setSettings("mod_remove", value); + setModConf("UPDATE", value); } }} > - + diff --git a/Website/src/activitys/SettingsActivity.tsx b/Website/src/activitys/SettingsActivity.tsx index 42632312..4409b179 100644 --- a/Website/src/activitys/SettingsActivity.tsx +++ b/Website/src/activitys/SettingsActivity.tsx @@ -114,7 +114,7 @@ function SettingsActivity() { }); }} > - + )} diff --git a/Website/src/activitys/TerminalActivity.tsx b/Website/src/activitys/TerminalActivity.tsx index 605741ee..d43a03a6 100644 --- a/Website/src/activitys/TerminalActivity.tsx +++ b/Website/src/activitys/TerminalActivity.tsx @@ -22,7 +22,7 @@ function useOnceCall(effect: React.EffectCallback, deps?: React.DependencyList | const TerminalActivity = () => { const { context, extra } = useActivity(); - const { settings } = useSettings(); + const { settings, modConf } = useSettings(); const [active, setActive] = React.useState(true); const [lines, setLines] = React.useState([]); @@ -51,9 +51,9 @@ const TerminalActivity = () => { const installCli = (path: string) => { if (Shell.isMagiskSU()) { - return settings.mod_msu_cli.replace(/{path}/i, path); + return modConf("MSUCLI", { ZIPFILE: path }); } else if (Shell.isKernelSU()) { - return settings.mod_ksu_cli.replace(/{path}/i, path); + return modConf("KSUCLI", { ZIPFILE: path }); } else { throw new Error("Unable to determine installation string"); } diff --git a/Website/src/activitys/fragments/DeviceModuleFragment.tsx b/Website/src/activitys/fragments/DeviceModuleFragment.tsx index 9df53d3c..b599c416 100644 --- a/Website/src/activitys/fragments/DeviceModuleFragment.tsx +++ b/Website/src/activitys/fragments/DeviceModuleFragment.tsx @@ -11,11 +11,11 @@ import TerminalActivity from "@Activitys/TerminalActivity"; const DeviceModuleFragment = () => { const { context } = useActivity(); - const { settings } = useSettings(); + const { settings, modConf } = useSettings(); const [modules, setModules] = React.useState([]); React.useEffect(() => { - setModules(SuFile.list(settings.mod_tree).split(",")); + setModules(SuFile.list(modConf("MODULES")).split(",")); }, [settings]); return ( diff --git a/Website/src/components/DeviceModule.tsx b/Website/src/components/DeviceModule.tsx index 1ecbe325..92fa16ad 100644 --- a/Website/src/components/DeviceModule.tsx +++ b/Website/src/components/DeviceModule.tsx @@ -10,7 +10,7 @@ import { ConfigureActivity } from "@Activitys/ConfigureActivity"; import { StyledIconButton } from "./StyledIconButton"; import { useLog } from "@Hooks/native/useLog"; import { Properties } from "properties-file"; -import { colors, useSettings } from "@Hooks/useSettings"; +import { ModConf, colors, useSettings } from "@Hooks/useSettings"; export const badgeStyle: (color: (typeof colors)["blue" | "teal" | "red" | "orange"]) => SxProps = (color) => { return { @@ -30,7 +30,7 @@ interface Props { const DeviceModule = (props: Props) => { const { strings } = useStrings(); - const { settings } = useSettings(); + const { settings, modConf } = useSettings(); const { context, extra } = useActivity(); const [moduleProps, setModuleProps] = React.useState>({}); const [isEnabled, setIsEnabled] = React.useState(true); @@ -40,31 +40,33 @@ const DeviceModule = (props: Props) => { const module = props.module; - const readProps = new SuFile(`${settings.mod_tree}/${module}/${settings.mod_prop}`); + const format = React.useCallback<(key: K) => ModConf[K]>((key) => modConf(key, { MODID: props.module }), []); + + const readProps = new SuFile(format("PROPS")); React.useEffect(() => { if (readProps.exist()) { setModuleProps(new Properties(readProps.read()).toObject()); } }, []); - const remove = new SuFile(`${settings.mod_tree}/${module}/${settings.mod_remove}`); + const remove = new SuFile(format("REMOVE")); React.useEffect(() => { setIsSwitchDisabled(remove.exist()); }, [isSwitchDisabled]); - const disable = new SuFile(`${settings.mod_tree}/${module}/${settings.mod_disable}`); + const disable = new SuFile(format("DISABLE")); React.useEffect(() => { setIsEnabled(!disable.exist()); }, [isEnabled]); const { id, name, version, versionCode, author, description, mmrlConfig } = moduleProps; - const post_service = SuFile.exist(`${settings.mod_tree}/${module}/${settings.mod_post_service}`); - const late_service = SuFile.exist(`${settings.mod_tree}/${module}/${settings.mod_late_service}`); - const post_mount = SuFile.exist(`${settings.mod_tree}/${module}/${settings.mod_mounted}`); - const boot_complete = SuFile.exist(`${settings.mod_tree}/${module}/${settings.mod_boot}`); + const post_service = SuFile.exist(format("POSTSERVICE")); + const late_service = SuFile.exist(format("LATESERVICE")); + const post_mount = SuFile.exist(format("POSTMOUNT")); + const boot_complete = SuFile.exist(format("BOOTCOMP")); - const module_config_file = SuFile.exist(`${settings.mod_tree}/${module}/system/usr/share/mmrl/config/${module}.mdx`); + const module_config_file = SuFile.exist(format("CONFIG")); if (!readProps.exist()) { return null; @@ -107,7 +109,7 @@ const DeviceModule = (props: Props) => { disabled={isSwitchDisabled} onChange={(e) => { const checked = e.target.checked; - const disable = new SuFile(`${settings.mod_tree}/${module}/${settings.mod_disable}`); + const disable = new SuFile(format("DISABLE")); if (checked) { if (disable.exist()) { @@ -158,7 +160,7 @@ const DeviceModule = (props: Props) => { { - const remove = new SuFile(`${settings.mod_tree}/${module}/${settings.mod_remove}`); + const remove = new SuFile(format("REMOVE")); if (remove.exist()) { if (remove.delete()) { setIsSwitchDisabled(false); @@ -177,7 +179,7 @@ const DeviceModule = (props: Props) => { { - const file = new SuFile(`${settings.mod_tree}/${module}/${settings.mod_remove}`); + const file = new SuFile(format("REMOVE")); if (file.create()) { setIsSwitchDisabled(true); } else { diff --git a/Website/src/hooks/useSettings.tsx b/Website/src/hooks/useSettings.tsx index cdd395f9..2f5dc8b5 100644 --- a/Website/src/hooks/useSettings.tsx +++ b/Website/src/hooks/useSettings.tsx @@ -162,27 +162,32 @@ export interface StorageDeclaration { __experimental_local_install: boolean; repos: StoredRepo[]; shade_value: number; +} - // cli - mod_msu_cli: string; - mod_ksu_cli: string; +export interface ModConf { + //cli + MSUCLI: string; + KSUCLI: string; // default paths - mod_tree: string; - mod_prop: string; - mod_system: string; - mod_sepolicy: string; + ADB: string; + MODULES: string; + PROPS: string; + SYSTEM: string; + SEPOLICY: string; + CONFIG: string; // service paths - mod_late_service: string; - mod_post_service: string; - mod_mounted: string; - mod_boot: string; + LATESERVICE: string; + POSTSERVICE: string; + POSTMOUNT: string; + BOOTCOMP: string; // status paths - mod_s_mount: string; - mod_disable: string; - mod_remove: string; + SKIPMOUNT: string; + DISABLE: string; + REMOVE: string; + UPDATE: string; } export const INITIAL_SETTINGS: StorageDeclaration = { @@ -196,55 +201,99 @@ export const INITIAL_SETTINGS: StorageDeclaration = { __experimental_local_install: false, repos: [], shade_value: -80, +}; +export const INITIAL_MOD_CONF: ModConf = { //cli - mod_msu_cli: '/system/bin/magisk --install-module "{path}"', - mod_ksu_cli: '/data/adb/ksu/bin/ksud module install "{path}"', + MSUCLI: '/system/bin/magisk --install-module ""', + KSUCLI: '/ksu/bin/ksud module install ""', // default paths - mod_tree: "/data/adb/modules", - mod_prop: "module.prop", - mod_system: "system.prop", - mod_sepolicy: "sepolicy.rule", + ADB: "/data/adb", + MODULES: "/modules", + PROPS: "//module.prop", + SYSTEM: "//system.prop", + SEPOLICY: "//sepolicy.rule", + CONFIG: `//system/usr/share/mmrl/config/.mdx`, // service paths - mod_late_service: "service.sh", - mod_post_service: "post-fs-data.sh", - mod_mounted: "post-mount.sh", - mod_boot: "boot-completed.sh", + LATESERVICE: "//service.sh", + POSTSERVICE: "//post-fs-data.sh", + POSTMOUNT: "//post-mount.sh", + BOOTCOMP: "//boot-completed.sh", // status paths - mod_s_mount: "skip_mount", - mod_disable: "disable", - mod_remove: "remove", + SKIPMOUNT: "//skip_mount", + DISABLE: "//disable", + REMOVE: "//remove", + UPDATE: "//update", }; export interface Context { patchSettings: () => void; settings: StorageDeclaration; + _modConf: ModConf; + modConf(key: K, adds?: Record): ModConf[K]; setSettings( key: K, state: SetStateAction, callback?: (state: StorageDeclaration[K]) => void ): void; + setModConf(key: K, state: SetStateAction, callback?: (state: ModConf[K]) => void): void; } export const SettingsContext = createContext({ patchSettings: () => {}, settings: INITIAL_SETTINGS, + _modConf: INITIAL_MOD_CONF, + modConf(key: K, adds?: Record) { + return key; + }, setSettings( key: K, state: SetStateAction, callback?: (state: StorageDeclaration[K]) => void ) {}, + setModConf(key: K, state: SetStateAction, callback?: (state: ModConf[K]) => void) {}, }); export const useSettings = () => { return useContext(SettingsContext); }; +function formatString(template, object) { + return template.replace(/\<(\w+(\.\w+)*)\>/gi, (match, key) => { + const keys = key.split("."); + let value = object; + for (const k of keys) { + if (k in value) { + value = value[k]; + } else { + return match; + } + } + return formatString(String(value), object); + }); +} + export const SettingsProvider = (props: React.PropsWithChildren) => { const [settings, setSettings] = useNativeStorage("settings", INITIAL_SETTINGS); + const [modConf, setModConf] = useNativeStorage("mod-conf", INITIAL_MOD_CONF); + + // Test purposes + // React.useEffect(() => { + // for (const k in modConf) { + // console.info( + // formatString(defaultComposer(INITIAL_MOD_CONF, modConf)[k], { + // ...modConf, + // ...{ + // MODID: "node_on_android", + // ZIPFILE: "/sdard/xh.zip", + // }, + // }) + // ); + // } + // }, [modConf]); return ( { patchSettings: () => { setSettings(defaultComposer(INITIAL_SETTINGS, settings)); }, + _modConf: defaultComposer(INITIAL_MOD_CONF, modConf), + modConf: (key, adds) => { + return formatString(defaultComposer(INITIAL_MOD_CONF, modConf)[key], { ...modConf, ...adds }); + }, settings: defaultComposer(INITIAL_SETTINGS, settings), setSettings: (name, state, callback) => { setSettings( @@ -265,6 +318,18 @@ export const SettingsProvider = (props: React.PropsWithChildren) => { (state) => callback && callback(state[name]) ); }, + setModConf: (name, state, callback) => { + setModConf( + (prev) => { + const newValue = state instanceof Function ? state(prev[name]) : state; + return { + ...prev, + [name]: newValue, + }; + }, + (state) => callback && callback(state[name]) + ); + }, }} children={props.children} />