Clickable accounts in logs and formatting fixes

This commit is contained in:
muzam1l
2022-03-04 15:13:56 +05:30
parent c6359aa853
commit 0fe83811b9
8 changed files with 99 additions and 32 deletions

View File

@@ -27,7 +27,7 @@ const labelStyle = css({
mb: "$0.5", mb: "$0.5",
}); });
const AccountDialog = ({ export const AccountDialog = ({
activeAccountAddress, activeAccountAddress,
setActiveAccountAddress, setActiveAccountAddress,
}: { }: {

View File

@@ -33,17 +33,19 @@ const DebugStream = () => {
const match = str.match(/([\s\S]+(?:UTC|ISO|GMT[+|-]\d+))\ ?([\s\S]*)/m); const match = str.match(/([\s\S]+(?:UTC|ISO|GMT[+|-]\d+))\ ?([\s\S]*)/m);
const [_, time, msg] = match || []; const [_, time, msg] = match || [];
const jsonData = extractJSON(msg); const extracted = extractJSON(msg);
const timestamp = time ? new Date(time) : undefined; const timestamp = time ? new Date(time) : undefined;
const message = !jsonData ? msg : msg.slice(0, jsonData.start) + msg.slice(jsonData.end + 1);
const message = !extracted ? msg : msg.slice(0, extracted.start) + msg.slice(extracted.end + 1);
const jsonData = extracted ? JSON.stringify(extracted.result, null, 2) : undefined;
return { return {
type: "log", type: "log",
message, message,
timestamp, timestamp,
jsonData: jsonData?.result, jsonData,
linkText: 'Expand', defaultCollapsed: true,
defaultCollapsed: true
}; };
}, []); }, []);
@@ -93,7 +95,6 @@ const DebugStream = () => {
socket.close(); socket.close();
}; };
}, [ds_selectedAccount?.value, prepareLog]); }, [ds_selectedAccount?.value, prepareLog]);
return ( return (
<LogBox <LogBox
enhanced enhanced

View File

@@ -3,7 +3,14 @@ import { styled } from "../stitches.config";
const StyledLink = styled("a", { const StyledLink = styled("a", {
color: "CurrentColor", color: "CurrentColor",
textDecoration: "underline", textDecoration: "underline",
cursor: 'pointer' cursor: 'pointer',
variants: {
highlighted: {
true: {
color: '$blue9'
}
}
}
}); });
export default StyledLink; export default StyledLink;

View File

@@ -1,12 +1,15 @@
import { useRef, useLayoutEffect, ReactNode, FC, useState } from "react"; import { useRef, useLayoutEffect, ReactNode, FC, useState, useCallback } from "react";
import { Notepad, Prohibit } from "phosphor-react"; import { Notepad, Prohibit } from "phosphor-react";
import useStayScrolled from "react-stay-scrolled"; import useStayScrolled from "react-stay-scrolled";
import NextLink from "next/link"; import NextLink from "next/link";
import Container from "./Container"; import Container from "./Container";
import LogText from "./LogText"; import LogText from "./LogText";
import { ILog } from "../state"; import state, { ILog } from "../state";
import { Code, Link, Heading, Button, Text, Flex, Box } from "."; import { Pre, Link, Heading, Button, Text, Flex, Box } from ".";
import regexifyString from "regexify-string";
import { useSnapshot } from "valtio";
import { AccountDialog } from "./Accounts";
interface ILogBox { interface ILogBox {
title: string; title: string;
@@ -130,29 +133,69 @@ const LogBox: FC<ILogBox> = ({ title, clearLog, logs, children, renderNav, enhan
export const Log: FC<ILog> = ({ export const Log: FC<ILog> = ({
type, type,
timestamp, timestamp,
message, message: _message,
link, link,
linkText, linkText,
defaultCollapsed, defaultCollapsed,
jsonData, jsonData: _jsonData,
}) => { }) => {
const [expanded, setExpanded] = useState(!defaultCollapsed); 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]
);
const message = enrichAccounts(_message.trim());
const jsonData = enrichAccounts(_jsonData);
return ( return (
<LogText variant={type}> <>
{timestamp && <Text muted>{timestamp.toLocaleTimeString()} </Text>} <AccountDialog
{message}{" "} setActiveAccountAddress={setDialogAccount}
{link && ( activeAccountAddress={dialogAccount}
<NextLink href={link} shallow passHref> />
<Link as="a">{linkText}</Link> <LogText variant={type}>
</NextLink> {timestamp && <Text muted>{timestamp.toLocaleTimeString()} </Text>}
)} <Pre line>{message} </Pre>
{jsonData && ( {link && (
<Link onClick={() => setExpanded(!expanded)} as="a"> <NextLink href={link} shallow passHref>
{expanded ? "Collapse" : "Expand"} <Link as="a">{linkText}</Link>
</Link> </NextLink>
)} )}
{expanded && jsonData && <Code>{JSON.stringify(jsonData, null, 2)}</Code>} {jsonData && (
</LogText> <Link onClick={() => setExpanded(!expanded)} as="a">
{expanded ? "Collapse" : "Expand"}
</Link>
)}
{expanded && jsonData && <Pre block>{jsonData}</Pre>}
</LogText>
</>
); );
}; };

View File

@@ -1,6 +1,6 @@
import { styled } from "../stitches.config"; import { styled } from "../stitches.config";
const Code = styled("pre", { const Pre = styled("span", {
m: 0, m: 0,
wordBreak: "break-all", wordBreak: "break-all",
fontFamily: '$monospace', fontFamily: '$monospace',
@@ -11,7 +11,17 @@ const Code = styled("pre", {
width: "100%", width: "100%",
}, },
}, },
line: {
true: {
whiteSpace: 'pre-line'
}
},
block: {
true: {
display: 'block'
}
}
}, },
}); });
export default Code; export default Pre;

View File

@@ -10,7 +10,7 @@ export * from "./Tabs";
export * from "./AlertDialog"; export * from "./AlertDialog";
export { default as Box } from "./Box"; export { default as Box } from "./Box";
export { default as Button } from "./Button"; export { default as Button } from "./Button";
export { default as Code } from "./Code"; export { default as Pre } from "./Pre";
export { default as ButtonGroup } from "./ButtonGroup"; export { default as ButtonGroup } from "./ButtonGroup";
export { default as DeployFooter } from "./DeployFooter"; export { default as DeployFooter } from "./DeployFooter";
export * from "./Dialog"; export * from "./Dialog";

View File

@@ -47,6 +47,7 @@
"react-stay-scrolled": "^7.4.0", "react-stay-scrolled": "^7.4.0",
"react-time-ago": "^7.1.9", "react-time-ago": "^7.1.9",
"reconnecting-websocket": "^4.4.0", "reconnecting-websocket": "^4.4.0",
"regexify-string": "^1.0.17",
"valtio": "^1.2.5", "valtio": "^1.2.5",
"vscode-languageserver": "^7.0.0", "vscode-languageserver": "^7.0.0",
"vscode-uri": "^3.0.2", "vscode-uri": "^3.0.2",
@@ -63,4 +64,4 @@
"eslint-config-next": "11.1.2", "eslint-config-next": "11.1.2",
"typescript": "4.4.4" "typescript": "4.4.4"
} }
} }

View File

@@ -3989,6 +3989,11 @@ regenerator-runtime@^0.13.4:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
regexify-string@^1.0.17:
version "1.0.17"
resolved "https://registry.yarnpkg.com/regexify-string/-/regexify-string-1.0.17.tgz#b9e571b51c8ec566eb82b7121744dae0d8e829de"
integrity sha512-mmD0AUNaY/piGW2AyACWdQOjIAwNuWz+KIvxfBZPDdCBAexiROeQxdxTaYAWcIxwtUAOwojdTta6CMMil84jXw==
regexp.prototype.flags@^1.3.1: regexp.prototype.flags@^1.3.1:
version "1.3.1" version "1.3.1"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"