fallbackwidth
and fallbackheight
are empty when you run the config in the browser
Note
The current version is messy.
import { Page, Toolbar, CodeBlock } from "@mmrl/ui"; | |
import { useActivity, useConfig } from "@mmrl/hooks"; | |
import { withRequireNewVersion } from "@mmrl/hoc"; | |
import { ConfigProvider } from "@mmrl/providers"; | |
import { | |
List, | |
ListItem, | |
ListItemButton, | |
ListItemText, | |
ListSubheader, | |
DialogTitle, | |
Dialog, | |
ListItemIcon, | |
Switch, | |
Checkbox, | |
Button, | |
Divider, | |
TextField, | |
DialogActions | |
} from "@mui/material"; | |
import { Check } from "@mui/icons-material" | |
const screen_dims = Shell.cmd("wm size").result() | |
const width_height = Shell.cmd(`${screen_dims} | tr -s ' ' ':' | cut -d':' -f3`).result() | |
const width = Shell.cmd(`${width_height} | cut -d'x' -f1`).result() | |
const height = Shell.cmd(`${width_height} | cut -d'x' -f2`).result() | |
const initialConfig = { | |
background: "transparent", | |
colors: true, | |
wordwrap: true, // assuming true since it's present | |
logcatlevels: { | |
V: true, | |
D: true, | |
I: true, | |
W: true, | |
E: true, | |
F: true, | |
S: true, | |
}, | |
logcatbuffers: { | |
M: true, | |
S: true, | |
R: true, | |
E: true, | |
C: true, | |
}, | |
logcatformat: 'threadtime', | |
dmesg: true, | |
lines: '80', | |
save: true, | |
fallbackwidth: width, | |
fallbackheight: height, | |
} | |
const backgroundsList = [ | |
{ | |
name: "Default", | |
value: " " | |
}, | |
{ | |
name: "Transparent", | |
value: "transparent" | |
}, | |
{ | |
name: "Dark", | |
value: "dark" | |
}, | |
] | |
const logcatFormatsList = [ | |
{ | |
name: "Brief", | |
value: "brief" | |
}, | |
{ | |
name: "Process", | |
value: "process" | |
}, | |
{ | |
name: "Tag", | |
value: "tag" | |
}, | |
{ | |
name: "Thread", | |
value: "thread" | |
}, | |
{ | |
name: "Time", | |
value: "time" | |
}, | |
{ | |
name: "Thread time", | |
value: "threadtime" | |
} | |
] | |
const logcatBuffersList = [ | |
{ | |
name: "Main", | |
value: "M" | |
}, | |
{ | |
name: "System", | |
value: "S" | |
}, | |
{ | |
name: "Radio", | |
value: "R" | |
}, | |
{ | |
name: "Events", | |
value: "E" | |
}, | |
{ | |
name: "Crash", | |
value: "C" | |
}, | |
] | |
const logcatLevelsList = [ | |
{ | |
name: "Verbose", | |
value: "V" | |
}, | |
{ | |
name: "Debug", | |
value: "D" | |
}, | |
{ | |
name: "Info", | |
value: "I" | |
}, | |
{ | |
name: "Warning", | |
value: "W" | |
}, | |
{ | |
name: "Error", | |
value: "E" | |
}, | |
{ | |
name: "Fatal", | |
value: "F" | |
}, | |
{ | |
name: "Silent", | |
value: "S" | |
}, | |
] | |
const RenderToolbar = () => { | |
const { context } = useActivity() | |
return ( | |
<Toolbar modifier="noshadow"> | |
<Toolbar.Left> | |
<Toolbar.BackButton onClick={context.popPage} /> | |
</Toolbar.Left> | |
<Toolbar.Center> | |
Liveboot Magisk | |
</Toolbar.Center> | |
</Toolbar> | |
) | |
} | |
function ListItemSelectDialog(props) { | |
const [config, setConfig] = useConfig(); | |
const [open, setOpen] = React.useState(false); | |
const { conf, primary, secondary, items } = props; | |
const handleClickOpen = () => { | |
setOpen(true); | |
}; | |
const handleClose = () => { | |
setOpen(false) | |
setConfig(conf, items[0].value) | |
}; | |
const handleListItemClick = (value) => { | |
setOpen(false) | |
setConfig(conf, value); | |
}; | |
return ( | |
<> | |
<ListItemButton onClick={handleClickOpen}> | |
<ListItemText primary={primary} secondary={secondary} /> | |
</ListItemButton> | |
<Dialog fullWidth onClose={handleClose} open={open}> | |
<DialogTitle>{primary}</DialogTitle> | |
<List sx={{ pt: 0 }}> | |
{items.map((item) => ( | |
<ListItem disablePadding key={item.value}> | |
<ListItemButton onClick={() => handleListItemClick(item.value)}> | |
<ListItemText primary={item.name} /> | |
{item.value === config[conf] && ( | |
<ListItemIcon> | |
<Check /> | |
</ListItemIcon> | |
)} | |
</ListItemButton> | |
</ListItem> | |
))} | |
</List> | |
</Dialog> | |
</> | |
); | |
} | |
const ListItemCheckboxDialog = (props) => { | |
const [config, setConfig] = useConfig(); | |
const [open, setOpen] = React.useState(false); | |
const { conf, primary, secondary, items } = props; | |
const handleClickOpen = () => { | |
setOpen(true); | |
}; | |
const handleClose = () => { | |
setOpen(false) | |
}; | |
const handleToggle = (e, item) => { | |
setConfig(conf, (prev) => { | |
return Object.assign(prev, { | |
[item.value]: e.target.checked | |
}) | |
}); | |
}; | |
return ( | |
<> | |
<ListItemButton onClick={handleClickOpen}> | |
<ListItemText primary={primary} secondary={secondary} /> | |
</ListItemButton> | |
<Dialog fullWidth open={open} onClose={handleClose}> | |
<DialogTitle>{props.primary}</DialogTitle> | |
<List> | |
{items.map((item) => ( | |
<ListItem key={item.value}> | |
<ListItemIcon> | |
<Checkbox | |
edge="start" | |
checked={config[conf][item.value]} | |
onChange={(e) => handleToggle(e, item)} | |
/> | |
</ListItemIcon> | |
<ListItemText primary={item.name} secondary={item.desc} /> | |
</ListItem> | |
))} | |
</List> | |
<DialogActions> | |
<Button onClick={handleClose} color="primary"> | |
Close | |
</Button> | |
</DialogActions> | |
</Dialog> | |
</> | |
) | |
} | |
const ListItemSwitch = (props) => { | |
const [config, setConfig] = useConfig(); | |
return ( | |
<ListItem> | |
<ListItemText primary={props.primary} secondary={props.secondary} /> | |
<Switch checked={config[props.conf]} onChange={(e) => setConfig(props.conf, e.target.checked)} /> | |
</ListItem> | |
) | |
} | |
const App = () => { | |
const [config, setConfig] = useConfig(); | |
const logcatbuffers = React.useMemo(() => Object.entries(config.logcatbuffers).map((buf) => { | |
const key = buf[0] | |
const value = buf[1] | |
if (value) return key | |
}).join(""), [config]) | |
const logcatlevels = React.useMemo(() => Object.entries(config.logcatlevels).map((lvl) => { | |
const key = lvl[0] | |
const value = lvl[1] | |
if (value) return key | |
}).join(""), [config]) | |
const commandString = React.useMemo(() => { | |
let command = ""; | |
if (config.background) command += `${config.background} `; | |
if (config.colors) { | |
command += "colors "; | |
} else { | |
command += "logcatnocolors "; | |
} | |
if (config.wordwrap) command += "wordwrap "; | |
if (config.save) command += "save "; | |
if (logcatlevels.length !== 0) { | |
command += `logcatlevels=${logcatlevels} `; | |
} | |
if (logcatbuffers.length !== 0) { | |
command += `logcatbuffers=${logcatbuffers} `; | |
} | |
command += `logcatformat=${config.logcatformat} `; | |
if (config.dmesg) { | |
command += `dmesg=0-99 `; | |
} else { | |
command += `dmesg=0--1 `; | |
} | |
command += `lines=${config.lines} `; | |
command += `fallbackwidth=${config.fallbackwidth} `; | |
command += `fallbackheight=${config.fallbackheight}`; | |
const parsedCommand = command.trim() | |
SuFile.write("/data/adb/liveboot.args.txt", parsedCommand) | |
return parsedCommand; | |
}, [config]) | |
const findBackground = React.useMemo(() => backgroundsList.find((t) => t.value === config.background), [config.background]) | |
const findLogcatFormat = React.useMemo(() => logcatFormatsList.find((t) => t.value === config.logcatformat), [config.logcatformat]) | |
const findLogcatBuffers = React.useMemo(() => logcatBuffersList.filter((buf) => logcatbuffers.includes(buf.value)).map((n) => n.name), [config.logcatbuffers]) | |
const findLogcatLevels = React.useMemo(() => logcatLevelsList.filter((lvl) => logcatlevels.includes(lvl.value)).map((n) => n.name), [config.logcatlevels]) | |
return ( | |
<Page sx={{ p: 2 }} renderToolbar={RenderToolbar}> | |
<CodeBlock lang="">{`liveboot ${commandString}`}</CodeBlock> | |
<List subheader={<ListSubheader>Logcat appearence</ListSubheader>}> | |
<ListItemSwitch conf="wordwrap" primary="Word wrap" /> | |
<ListItemSwitch conf="colors" primary="Colorful logs" /> | |
<ListItemSelectDialog conf="background" primary="Background" secondary={findBackground.name} items={backgroundsList} /> | |
</List> | |
<Divider /> | |
<List subheader={<ListSubheader>Settings</ListSubheader>}> | |
<ListItemSelectDialog conf="logcatformat" primary="Logcat format" secondary={findLogcatFormat.name} items={logcatFormatsList} /> | |
<ListItemCheckboxDialog conf="logcatbuffers" primary="Logcat buffers" secondary={findLogcatBuffers.join(", ")} items={logcatBuffersList} /> | |
<ListItemCheckboxDialog conf="logcatlevels" primary="Logcat levels" secondary={findLogcatLevels.join(", ")} items={logcatLevelsList} /> | |
</List> | |
<Divider /> | |
<List subheader={<ListSubheader>Other</ListSubheader>}> | |
<ListItemSwitch conf="save" primary="Save logs" /> | |
<ListItemSwitch conf="dmesg" primary="DMESG" /> | |
<TextField | |
sx={{ m: 1, width: "calc(100% - 16px)" }} | |
type="number" | |
label="Lines" | |
variant="outlined" | |
value={config.lines} | |
onInput={(e) => { | |
e.target.value = Math.max(0, parseInt(e.target.value)).toString().slice(0, 5) | |
}} | |
onChange={(e) => setConfig("lines", e.target.value)} /> | |
</List> | |
</Page> | |
) | |
} | |
export default withRequireNewVersion({ | |
versionCode: 32325, | |
component: () => { | |
return ( | |
<ConfigProvider | |
loadFromFile="/data/adb/liveboot.config.json" | |
initialConfig={initialConfig} | |
loader="json" | |
> | |
<App /> | |
</ConfigProvider> | |
); | |
}, | |
}); |
@DerGoogler Isn't it possible to get the fallbackwidth and fallbackheight values of the device with this code? Or at least run the shell command and use its output?