ls display is responsive (#492)

This commit is contained in:
Snarling 2023-04-26 15:18:26 -04:00 committed by GitHub
parent d9ef53e2e8
commit f81297dcd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 99 deletions

@ -106,89 +106,69 @@ export function ls(args: (string | number | boolean)[], server: BaseServer): voi
allMessages.sort(); allMessages.sort();
folders.sort(); folders.sort();
interface ScriptRowProps { function SegmentGrid(props: { colSize: string; children: React.ReactChild[] }): React.ReactElement {
scripts: ScriptFilePath[]; const classes = makeStyles({
segmentGrid: {
display: "grid",
gridTemplateColumns: "repeat(auto-fill, var(--colSize))",
},
})();
const style = { ["--colSize"]: props.colSize } as React.CSSProperties;
return (
<span style={style} className={classes.segmentGrid}>
{props.children}
</span>
);
} }
function ClickableScriptRow({ scripts }: ScriptRowProps): React.ReactElement { function ClickableScriptLink(props: { path: ScriptFilePath }): React.ReactElement {
const classes = makeStyles((theme: Theme) => const classes = makeStyles((theme: Theme) =>
createStyles({ createStyles({
scriptLinksWrap: { link: {
display: "inline-flex",
color: theme.palette.warning.main,
},
scriptLink: {
cursor: "pointer", cursor: "pointer",
textDecorationLine: "underline", textDecorationLine: "underline",
marginRight: "1.5em", color: theme.palette.warning.main,
"&:last-child": { marginRight: 0 },
}, },
}), }),
)(); )();
const fullPath = combinePath(baseDirectory, props.path);
function onScriptLinkClick(filename: ScriptFilePath): void { function onClick() {
const filePath = combinePath(baseDirectory, filename); const code = server.scripts.get(props.path)?.content ?? "";
const code = server.scripts.get(filePath)?.content ?? "";
const map = new Map<ContentFilePath, string>(); const map = new Map<ContentFilePath, string>();
map.set(filePath, code); map.set(fullPath, code);
Router.toScriptEditor(map); Router.toScriptEditor(map);
} }
return ( return (
<span className={classes.scriptLinksWrap}> <span>
{scripts.map((script) => ( <span className={classes.link} onClick={onClick}>
<span key={script}> {props.path}
<span className={classes.scriptLink} onClick={() => onScriptLinkClick(script)}>
{script}
</span> </span>
<span></span>
</span>
))}
</span> </span>
); );
} }
interface MessageRowProps { function ClickableMessageLink(props: { path: FilePath }): React.ReactElement {
messages: FilePath[]; const classes = makeStyles({
}
function ClickableMessageRow({ messages }: MessageRowProps): React.ReactElement {
const classes = makeStyles((theme: Theme) =>
createStyles({
linksWrap: {
display: "inline-flex",
color: theme.palette.primary.main,
},
link: { link: {
cursor: "pointer", cursor: "pointer",
textDecorationLine: "underline", textDecorationLine: "underline",
marginRight: "1.5em",
"&:last-child": { marginRight: 0 },
}, },
}), })();
)(); function onClick(): void {
function onMessageLinkClick(filename: FilePath): void {
if (!server.isConnectedTo) { if (!server.isConnectedTo) {
return Terminal.error(`File is not on this server, connect to ${server.hostname} and try again`); return Terminal.error(`File is not on this server, connect to ${server.hostname} and try again`);
} }
// Message and lit files have no directories // Message and lit files are always in root, no need to combine path with base directory
if (checkEnum(MessageFilename, props.path)) {
if (checkEnum(MessageFilename, filename)) { showMessage(props.path);
showMessage(filename); } else if (checkEnum(LiteratureName, props.path)) {
} else if (checkEnum(LiteratureName, filename)) { showLiterature(props.path);
showLiterature(filename);
} }
} }
return ( return (
<span className={classes.linksWrap}> <span>
{messages.map((message) => ( <span className={classes.link} onClick={onClick}>
<span key={message}> {props.path}
<span className={classes.link} onClick={() => onMessageLinkClick(message)}>
{message}
</span> </span>
<span></span>
</span>
))}
</span> </span>
); );
} }
@ -212,45 +192,28 @@ export function ls(args: (string | number | boolean)[], server: BaseServer): voi
| { type: FileType.Script; segments: ScriptFilePath[] }; | { type: FileType.Script; segments: ScriptFilePath[] };
function postSegments({ type, segments }: FileGroup, flags: LSFlags): void { function postSegments({ type, segments }: FileGroup, flags: LSFlags): void {
const maxLength = Math.max(...segments.map((s) => s.length)) + 1; let segmentElements: React.ReactElement[];
const filesPerRow = flags["-l"] === true ? 1 : Math.ceil(80 / maxLength); const colSize = flags["-l"]
const padLength = Math.max(maxLength + 2, 40); ? "100%"
let i = 0; : Math.ceil(Math.max(...segments.map((segment) => segment.length)) * 0.7) + "em";
if (type === FileType.Script) {
while (i < segments.length) {
const scripts: ScriptFilePath[] = [];
for (let col = 0; col < filesPerRow && i < segments.length; col++, i++) {
scripts.push(segments[i]);
}
Terminal.printRaw(<ClickableScriptRow scripts={scripts} />);
}
return;
}
if (type === FileType.Message) {
while (i < segments.length) {
const messages: FilePath[] = [];
for (let col = 0; col < filesPerRow && i < segments.length; col++, i++) {
messages.push(segments[i]);
}
Terminal.printRaw(<ClickableMessageRow messages={messages} />);
}
return;
}
while (i < segments.length) {
let row = "";
for (let col = 0; col < filesPerRow; col++, i++) {
if (!(i < segments.length)) break;
row += segments[i].padEnd(padLength);
i++;
}
switch (type) { switch (type) {
case FileType.Folder: case FileType.Folder:
Terminal.printRaw(<span style={{ color: "cyan" }}>{row}</span>); segmentElements = segments.map((segment) => (
<span key={segment} style={{ color: "cyan" }}>
{segment}
</span>
));
break;
case FileType.Message:
segmentElements = segments.map((segment) => <ClickableMessageLink key={segment} path={segment} />);
break;
case FileType.Script:
segmentElements = segments.map((segment) => <ClickableScriptLink key={segment} path={segment} />);
break; break;
default: default:
Terminal.print(row); segmentElements = segments.map((segment) => <span key={segment}>{segment}</span>);
}
} }
Terminal.printRaw(<SegmentGrid colSize={colSize}>{segmentElements}</SegmentGrid>);
} }
const groups: FileGroup[] = [ const groups: FileGroup[] = [

@ -35,10 +35,12 @@ const useStyles = makeStyles((theme: Theme) =>
whiteSpace: "pre-wrap", whiteSpace: "pre-wrap",
overflowWrap: "anywhere", overflowWrap: "anywhere",
margin: theme.spacing(0), margin: theme.spacing(0),
width: "100%",
}, },
list: { list: {
padding: theme.spacing(0), padding: theme.spacing(0),
height: "100%", height: "100%",
width: "100%",
}, },
}), }),
); );