Files
xrpl-hooks-ide/components/LogBox.tsx
2022-03-24 16:09:05 +02:00

224 lines
5.6 KiB
TypeScript

import {
useRef,
useLayoutEffect,
ReactNode,
FC,
useState,
// useCallback,
} from "react";
import { Notepad, Prohibit } from "phosphor-react";
import useStayScrolled from "react-stay-scrolled";
import NextLink from "next/link";
import Container from "./Container";
import LogText from "./LogText";
// import state, { ILog } from "../state";
import { ILog } from "../state";
import { Pre, Link, Heading, Button, Text, Flex, Box } from ".";
// import regexifyString from "regexify-string";
// import { useSnapshot } from "valtio";
import { AccountDialog } from "./Accounts";
interface ILogBox {
title: string;
clearLog?: () => void;
logs: ILog[];
renderNav?: () => ReactNode;
enhanced?: boolean;
}
const LogBox: FC<ILogBox> = ({
title,
clearLog,
logs,
children,
renderNav,
enhanced,
}) => {
const logRef = useRef<HTMLPreElement>(null);
const { stayScrolled /*, scrollBottom*/ } = useStayScrolled(logRef);
useLayoutEffect(() => {
stayScrolled();
}, [stayScrolled, logs]);
return (
<Flex
as="div"
css={{
display: "flex",
borderTop: "1px solid $mauve6",
background: "$mauve1",
position: "relative",
flex: 1,
height: "100%",
}}
>
<Container
css={{
px: 0,
height: "100%",
}}
>
<Flex
fluid
css={{
height: "48px",
alignItems: "center",
fontSize: "$sm",
fontWeight: 300,
}}
>
<Heading
as="h3"
css={{
fontWeight: 300,
m: 0,
fontSize: "11px",
color: "$mauve12",
px: "$3",
textTransform: "uppercase",
alignItems: "center",
display: "inline-flex",
gap: "$3",
}}
>
<Notepad size="15px" /> <Text css={{ lineHeight: 1 }}>{title}</Text>
</Heading>
<Flex
row
align="center"
css={{
width: "50%", // TODO make it max without breaking layout!
}}
>
{renderNav?.()}
</Flex>
<Flex css={{ ml: "auto", gap: "$3", marginRight: "$3" }}>
{clearLog && (
<Button ghost size="xs" onClick={clearLog}>
<Prohibit size="14px" />
</Button>
)}
</Flex>
</Flex>
<Box
as="pre"
ref={logRef}
css={{
margin: 0,
// display: "inline-block",
display: "flex",
flexDirection: "column",
width: "100%",
height: "calc(100% - 48px)", // 100% minus the logbox header height
overflowY: "auto",
fontSize: "13px",
fontWeight: "$body",
fontFamily: "$monospace",
px: "$3",
pb: "$2",
whiteSpace: "normal",
}}
>
{logs?.map((log, index) => (
<Box
as="span"
key={log.type + index}
css={{
"@hover": {
"&:hover": {
backgroundColor: enhanced ? "$backgroundAlt" : undefined,
},
},
p: enhanced ? "$1" : undefined,
my: enhanced ? "$1" : undefined,
}}
>
<Log {...log} />
</Box>
))}
{children}
</Box>
</Container>
</Flex>
);
};
export const Log: FC<ILog> = ({
type,
timestamp: timestamp,
message: _message,
link,
linkText,
defaultCollapsed,
jsonData: _jsonData,
}) => {
// const [expanded, setExpanded] = useState(!defaultCollapsed);
// const { accounts } = useSnapshot(state);
const [dialogAccount, setDialogAccount] = useState<string | null>(null);
// const enrichAccounts = useCallback(
// (str?: string): ReactNode => {
// if (!str || !accounts.length) return null;
// const pattern = `(${accounts.map((acc) => acc.address).join("|")})`;
// const res = regexifyString({
// pattern: new RegExp(pattern, "gim"),
// decorator: (match, idx) => {
// const name = accounts.find((acc) => acc.address === match)?.name;
// return (
// <Link
// key={match + idx}
// as="a"
// onClick={() => setDialogAccount(match)}
// title={match}
// highlighted
// >
// {name || match}
// </Link>
// );
// },
// input: str,
// });
// return <>{res}</>;
// },
// [accounts]
// );
_message = _message.trim().replace(/\n /gi, "\n");
// const message = enrichAccounts(_message);
// const jsonData = enrichAccounts(_jsonData);
return (
<>
<AccountDialog
setActiveAccountAddress={setDialogAccount}
activeAccountAddress={dialogAccount}
/>
<LogText variant={type}>
{timestamp && (
<Text muted monospace>
{timestamp}{" "}
</Text>
)}
<Pre>{_message} </Pre>
{link && (
<NextLink href={link} shallow passHref>
<Link as="a">{linkText}</Link>
</NextLink>
)}
{/* {jsonData && (
<Link onClick={() => setExpanded(!expanded)} as="a">
{expanded ? "Collapse" : "Expand"}
</Link>
)}
{expanded && jsonData && <Pre block>{jsonData}</Pre>} */}
</LogText>
</>
);
};
export default LogBox;