diff --git a/app/src/main/java/com/dergoogler/mmrl/MainActivity.java b/app/src/main/java/com/dergoogler/mmrl/MainActivity.java index a59bb8f1..8eebe572 100644 --- a/app/src/main/java/com/dergoogler/mmrl/MainActivity.java +++ b/app/src/main/java/com/dergoogler/mmrl/MainActivity.java @@ -154,7 +154,7 @@ private String mmrlUserAgent() { return "MMRL/" + BuildConfig.VERSION_NAME + " (Linux; Android " + Build.VERSION.RELEASE + "; " + Build.MODEL + " Build/" + Build.DISPLAY + ")"; } - private boolean isEmulator = (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) + private final boolean isEmulator = (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) || Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown") || Build.HARDWARE.contains("goldfish") diff --git a/docs/Installer/README.md b/docs/Installer/README.md index 042d3379..cac424a0 100644 --- a/docs/Installer/README.md +++ b/docs/Installer/README.md @@ -1,19 +1,17 @@ -# Installer V2 +# Installer V3 Implantation ```shell -if [ "$MMRL_INTR" = "true" ]; then - mmrl_exec() { ui_print "#!mmrl:$*"; } - gui_print() { mmrl_exec color "\"$@\""; } - mmrl_setLastLine() { mmrl_exec setLastLine "\"$@\""; } - gui_image() { mmrl_exec addImage "$*"; } -else - mmrl_exec() { true; } - gui_print() { ui_print "$@" | sed 's/<[A-Z.]*>//g'; } - mmrl_setLastLine() { true; } - gui_image() { true; } -fi +mmrl_exec() { + if [ "$MMRL_INTR" = "true" ]; then + local command=$1 + shift + local args=$(printf "|%s" "$@") + args=${args:1} + echo "#!mmrl:<$command=($args)>" + fi +} ``` ## Internal commands @@ -28,9 +26,10 @@ Clears everything from the terminal mmrl_exec clearTerminal ``` -| Args | Description | -| ---- | ----------- | -| No | | +| Args | Description | +| ---- | ---------------- | +| No | | +| | Returns no value | ### Replace last line @@ -40,9 +39,10 @@ You can replace the last placed line, even the last line is a button mmrl_exec setLastLine "This is a cool log" ``` -| Args | Description | -| --------- | -------------------------------------- | -| `args[0]` | Text that should replace the last line | +| Args | Description | +| ---- | -------------------------------------- | +| `$1` | Text that should replace the last line | +| | Returns no value | ### Remove last line @@ -52,11 +52,12 @@ This command just removes the last line mmrl_exec removeLastLine ``` -| Args | Description | -| ---- | ----------- | -| No | | +| Args | Description | +| ---- | ---------------- | +| No | | +| | Returns no value | -### Add a button + ## Making colored text easir! When you implant the API you can start using `gui_print`. ```shell -gui_print "This is MMRL!" +mmrl_exec color "This is MMRL!" ``` +| Args | Description | +| ---- | --------------- | +| `$1` | Text | +| | Returns a value | + > [!NOTE] > Other installer will return `This is MMRL!` because it's a MMRL only syntax diff --git a/docs/Installer/V2.md b/docs/Installer/V2.md new file mode 100644 index 00000000..042d3379 --- /dev/null +++ b/docs/Installer/V2.md @@ -0,0 +1,81 @@ +# Installer V2 + +Implantation + +```shell +if [ "$MMRL_INTR" = "true" ]; then + mmrl_exec() { ui_print "#!mmrl:$*"; } + gui_print() { mmrl_exec color "\"$@\""; } + mmrl_setLastLine() { mmrl_exec setLastLine "\"$@\""; } + gui_image() { mmrl_exec addImage "$*"; } +else + mmrl_exec() { true; } + gui_print() { ui_print "$@" | sed 's/<[A-Z.]*>//g'; } + mmrl_setLastLine() { true; } + gui_image() { true; } +fi +``` + +## Internal commands + +Every internal command starts with `mmrl_exec`! + +### Clear terminal + +Clears everything from the terminal + +```shell +mmrl_exec clearTerminal +``` + +| Args | Description | +| ---- | ----------- | +| No | | + +### Replace last line + +You can replace the last placed line, even the last line is a button + +```shell +mmrl_exec setLastLine "This is a cool log" +``` + +| Args | Description | +| --------- | -------------------------------------- | +| `args[0]` | Text that should replace the last line | + +### Remove last line + +This command just removes the last line + +```shell +mmrl_exec removeLastLine +``` + +| Args | Description | +| ---- | ----------- | +| No | | + +### Add a button + +This command can a little bit more but it has less functionality because you can't a click event + +```shell +mmrl_exec addButton "Button text here" --variant "contained or outlined" +``` + +| Args | Description | +| ----------- | ----------------------------------------- | +| `args[0]` | Button text | +| `--variant` | Choose between `contained` and `outlined` | + +## Making colored text easir! + +When you implant the API you can start using `gui_print`. + +```shell +gui_print "This is MMRL!" +``` + +> [!NOTE] +> Other installer will return `This is MMRL!` because it's a MMRL only syntax diff --git a/docs/Installer/README_az.md b/docs/Installer/V2_az.md similarity index 100% rename from docs/Installer/README_az.md rename to docs/Installer/V2_az.md diff --git a/src/activitys/InstallTerminalV2Activity/hooks/useLines.tsx b/src/activitys/InstallTerminalV2Activity/hooks/useLines.tsx index 7b1e67d6..82bf7cd1 100644 --- a/src/activitys/InstallTerminalV2Activity/hooks/useLines.tsx +++ b/src/activitys/InstallTerminalV2Activity/hooks/useLines.tsx @@ -1,9 +1,11 @@ import { Ansi } from "@Components/Ansi"; +import { Image } from "@Components/dapi/Image"; import { useModFS } from "@Hooks/useModFS"; import { useStrings } from "@Hooks/useStrings"; import Button from "@mui/material/Button"; import { Shell } from "@Native/Shell"; import { useConfirm } from "material-ui-confirm"; +import ModFS from "modfs"; import React from "react"; interface LinesContext { @@ -34,11 +36,36 @@ const LinesContext = React.createContext({ clearTerminal() {}, }); -type IntrCommand = (args: string[], options: Record, add: any) => void; +const colors = { + R: "\x1b[0m", + BRIGHT: "\x1b[1m", + DIM: "\x1b[2m", + UNDERSCORE: "\x1b[4m", + FG: { + BLACK: "\x1b[30m", + RED: "\x1b[31m", + GREEN: "\x1b[32m", + YELLOW: "\x1b[33m", + BLUE: "\x1b[34m", + MAGENTA: "\x1b[35m", + CYAN: "\x1b[36m", + WHITE: "\x1b[37m", + GRAY: "\x1b[90m", + }, + BG: { + BLACK: "\x1b[40m", + RED: "\x1b[41m", + GREEN: "\x1b[42m", + YELLOW: "\x1b[43m", + BLUE: "\x1b[44m", + MAGENTA: "\x1b[45m", + CYAN: "\x1b[46m", + WHITE: "\x1b[47m", + GRAY: "\x1b[100m", + }, +}; -interface LinesProviderProps extends React.PropsWithChildren { - commands: Record; -} +interface LinesProviderProps extends React.PropsWithChildren {} const LinesProvider = (props: LinesProviderProps) => { const { strings } = useStrings(); @@ -46,11 +73,12 @@ const LinesProvider = (props: LinesProviderProps) => { const [useInt, setUseInt] = React.useState(false); const [lines, setLines] = React.useState([]); const confirm = useConfirm(); - const { commands, children } = props; + const { children } = props; const addText = (text: string, props?: object) => { const txt = processCommand(text); - if (typeof txt === "string") { + + if (typeof txt === "string" && txt !== "undefined") { setLines((lines) => [ ...lines, { @@ -113,66 +141,37 @@ const LinesProvider = (props: LinesProviderProps) => { ]); }; - const processCommand = (rawCommand: string) => { + const format = React.useMemo( + () => ({ + addImage(data: string) { + addImage(data); + return "undefined"; + }, + setLastLine(text: string) { + if (typeof text === "undefined") return "undefined"; + setLastLine(text); + return "undefined"; + }, + color: (text: string) => { + if (typeof text === "undefined") return "undefined"; + return ModFS.format(text, colors); + }, + clearTerminal: () => { + setLines([]); + return "undefined"; + }, + removeLastLine: () => { + setLines((p) => p.slice(0, -1)); + return "undefined"; + }, + }), + [] + ); + + const processCommand = (rawCommand: string): string | "undefined" => { if (rawCommand.startsWith("#!mmrl:")) { - let args: string[] = []; - let options = {}; - let command: string; rawCommand = rawCommand.substring(7); - const i = rawCommand.indexOf(" "); - - if (i !== -1 && rawCommand.length !== i + 1) { - // Extract command arguments and options - const argsString = rawCommand.substring(i + 1).trim(); - const matches = argsString.match(/"([^"]+)"|--?[\w-]+|\S+/g); - - if (matches) { - for (let j = 0; j < matches.length; j++) { - let match = matches[j]; - if (match.startsWith("--")) { - // Long option - const key = match.substring(2); - let value: string | boolean = true; - if (j + 1 < matches.length && !matches[j + 1].startsWith("-")) { - value = matches[++j]; - // Remove surrounding quotes if present - if (value.startsWith('"') && value.endsWith('"')) { - value = value.slice(1, -1); - } - } - options[key] = value; - } else if (match.startsWith("-")) { - // Short option - const key = match.substring(1); - let value: string | boolean = true; - if (j + 1 < matches.length && !matches[j + 1].startsWith("-")) { - value = matches[++j]; - // Remove surrounding quotes if present - if (value.startsWith('"') && value.endsWith('"')) { - value = value.slice(1, -1); - } - } - options[key] = value; - } else { - // Positional argument - // Remove surrounding quotes if present - if (match.startsWith('"') && match.endsWith('"')) { - match = match.slice(1, -1); - } - args.push(match); - } - } - } - - command = rawCommand.substring(0, i); - } else { - command = rawCommand; - } - - const handleCommand = commands[command]; - if (handleCommand) { - handleCommand(args, options, { addButton: addButton, addText: addText, addImage: addImage, setLines: setLines, lines: lines }); - } + return ModFS.format(rawCommand, format) as string | "undefined"; } else { const info = /^\-(\s+)?(.+)/gm; const warn = /^\?(\s+)?(.+)/gm; diff --git a/src/activitys/InstallTerminalV2Activity/index.tsx b/src/activitys/InstallTerminalV2Activity/index.tsx index bbc4b3e3..e60c7cf4 100644 --- a/src/activitys/InstallTerminalV2Activity/index.tsx +++ b/src/activitys/InstallTerminalV2Activity/index.tsx @@ -4,7 +4,6 @@ import { useActivity } from "@Hooks/useActivity"; import { useSettings } from "@Hooks/useSettings"; import { alpha, Box, LinearProgress, Stack, Typography } from "@mui/material"; import { view, WindowManager } from "@Native/View"; -import { formatString } from "@Util/stringFormat"; import FlatList from "flatlist-react"; import React from "react"; import { useExploreInstall } from "./hooks/useExploreInstall"; @@ -18,35 +17,6 @@ export interface TerminalActivityExtra { issues?: string; } -const colors = { - R: "\x1b[0m", - BRIGHT: "\x1b[1m", - DIM: "\x1b[2m", - UNDERSCORE: "\x1b[4m", - FG: { - BLACK: "\x1b[30m", - RED: "\x1b[31m", - GREEN: "\x1b[32m", - YELLOW: "\x1b[33m", - BLUE: "\x1b[34m", - MAGENTA: "\x1b[35m", - CYAN: "\x1b[36m", - WHITE: "\x1b[37m", - GRAY: "\x1b[90m", - }, - BG: { - BLACK: "\x1b[40m", - RED: "\x1b[41m", - GREEN: "\x1b[42m", - YELLOW: "\x1b[43m", - BLUE: "\x1b[44m", - MAGENTA: "\x1b[45m", - CYAN: "\x1b[46m", - WHITE: "\x1b[47m", - GRAY: "\x1b[100m", - }, -}; - const InstallerComponent = () => { const { context, extra } = useActivity(); @@ -227,43 +197,7 @@ const InstallerComponent = () => { export const InstallTerminalV2Activity = () => { return ( - { - add.addText(formatString(args[0], colors)); - }, - clearTerminal: (_, __, add) => { - add.setLines([]); - }, - setLastLine: (args, __, add) => { - add.setLines((p) => p.slice(0, -1)); - add.addText(args[0]); - }, - removeLastLine: (_, __, add) => { - add.setLines((p) => p.slice(0, -1)); - }, - addImage: (args, opt, add) => { - const { width, height } = opt; - add.addImage(args[0], { - sx: { - width: width || "80vmin", - height: height, - }, - }); - }, - addButton: (args, opt, add) => { - const { variant } = opt; - add.addButton(args[0], { - sx: { - width: "50vmin", - mt: 1, - mb: 1, - }, - variant: variant, - }); - }, - }} - > + ); diff --git a/src/components/dapi/Image.tsx b/src/components/dapi/Image.tsx index ebd31b1d..8c566b0b 100644 --- a/src/components/dapi/Image.tsx +++ b/src/components/dapi/Image.tsx @@ -25,13 +25,13 @@ function Image(props: Props) { const { context } = useActivity(); const { type = "image/png", src, shadow, noOpen, sx, blur, modFSAdds, noOutline, ...rest } = props; - const [newSrc, setNewSrc] = React.useState(src); - - React.useEffect(() => { + const newSrc = React.useMemo(() => { if (src) { const file = new SuFile(formatString(src, Object.assign(_modFS, modFSAdds))); if (file.exist()) { - setNewSrc(`data:${type};base64,${file.readAsBase64()}`); + return `data:${type};base64,${file.readAsBase64()}`; + } else { + return src; } } }, [src]); diff --git a/src/util/licenses.json b/src/util/licenses.json index 1ac7cf89..de0035c4 100644 --- a/src/util/licenses.json +++ b/src/util/licenses.json @@ -209,7 +209,7 @@ "author": null, "license": "MIT", "description": "ModFS is a json format processor and also used in MMRL as the ModFS system", - "version": "1.3.2", + "version": "1.4.2", "source": "https://www.npmjs.com/package/modfs" }, {