Skip to content

Commit 5daf210

Browse files
committed
feat: add collapsible console log in footer
#25
1 parent 4d38caa commit 5daf210

File tree

7 files changed

+73
-16
lines changed

7 files changed

+73
-16
lines changed

src/App.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ function App() {
3737

3838
return (
3939
<MemoryRouter>
40-
<div className="flex flex-col min-h-screen">
40+
<div className="flex flex-col min-h-screen gap-y-4">
4141
<Header />
42-
<main className="flex-grow mt-10">
42+
<main className="flex-grow flex flex-col gap-y-4">
4343
<Routes>
4444
<Route path="/" element={<Networks />} />
4545
<Route path="/settings" element={<Settings />} />
4646
</Routes>
47+
<Message />
4748
</main>
48-
<Message />
4949
<Footer />
5050
</div>
5151
</MemoryRouter>

src/components/Footer.tsx

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,40 @@
1+
import { useState } from "react";
12
import { useStore } from "../store";
3+
import { IconCommandLine } from ".";
24

35
export function Footer() {
6+
const [collapsed, setCollapsed] = useState(true as boolean);
7+
48
const appVersion = useStore((s) => s.appVersion);
59
const platformArch = useStore((s) => s.platformArch);
10+
const consoleLines = useStore((s) => s.consoleLines);
11+
612
return (
7-
<footer className="footer footer-center bg-base-200 text-base-content/30 p-4">
8-
<div className="flex flex-row">
9-
<span>ZKNetwork Client</span>
10-
<span className="mx-2">|</span>
11-
<span>Version: {appVersion}</span>
12-
<span className="mx-2">|</span>
13-
<span>Platform: {platformArch}</span>
13+
<footer
14+
tabIndex={0}
15+
className="collapse-arrow collapse bg-base-200 text-base-content/30 border-t border-base-300 rounded-none"
16+
>
17+
<input
18+
type="checkbox"
19+
checked={!collapsed}
20+
onChange={() => setCollapsed(!collapsed)}
21+
/>
22+
<div className="collapse-title flex w-full items-center">
23+
<IconCommandLine />
24+
<div className="mx-auto flex gap-x-4 text-sm">
25+
<span>ZKNetwork Client</span>
26+
<span>|</span>
27+
<span>Version: {appVersion}</span>
28+
<span>|</span>
29+
<span>Platform: {platformArch}</span>
30+
</div>
31+
</div>
32+
<div className="collapse-content border-t border-base-300 px-4">
33+
<div className="flex h-36 flex-col-reverse overflow-y-scroll text-xs sm:text-xs md:text-sm lg:text-base text-base-content/50">
34+
{consoleLines.map((v, i) => (
35+
<span key={i}>{v}</span>
36+
))}
37+
</div>
1438
</div>
1539
</footer>
1640
);

src/components/Header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export function Header() {
7171

7272
// https://v5.daisyui.com/components/navbar/#navbar-with-dropdown-center-logo-and-icon
7373
return (
74-
<div className="navbar bg-base-200 shadow-sm">
74+
<div className="navbar bg-base-200 shadow-sm border-b border-base-300">
7575
<div className="navbar-start">
7676
<SideBar />
7777
</div>

src/components/Message.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function Message() {
1414
return (
1515
<>
1616
{msg && (
17-
<div className="flex justify-center my-5">
17+
<div className="flex justify-center">
1818
<p className={`alert ${msgClass}`}>{msg}</p>
1919
</div>
2020
)}

src/components/icons.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ export const IconCog = () => (
3030
</svg>
3131
);
3232

33+
export const IconCommandLine = () => (
34+
<svg
35+
xmlns="http://www.w3.org/2000/svg"
36+
viewBox="0 0 24 24"
37+
fill="currentColor"
38+
className="size-6"
39+
>
40+
<path
41+
fillRule="evenodd"
42+
d="M2.25 6a3 3 0 0 1 3-3h13.5a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H5.25a3 3 0 0 1-3-3V6Zm3.97.97a.75.75 0 0 1 1.06 0l2.25 2.25a.75.75 0 0 1 0 1.06l-2.25 2.25a.75.75 0 0 1-1.06-1.06l1.72-1.72-1.72-1.72a.75.75 0 0 1 0-1.06Zm4.28 4.28a.75.75 0 0 0 0 1.5h3a.75.75 0 0 0 0-1.5h-3Z"
43+
clipRule="evenodd"
44+
/>
45+
</svg>
46+
);
47+
3348
export const IconGlobe = () => (
3449
<svg
3550
xmlns="http://www.w3.org/2000/svg"

src/pages/Networks.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export function Networks() {
2727
(s) => s.walletshieldListenAddress,
2828
);
2929

30+
const consoleAddLine = useStore((s) => s.consoleAddLine);
3031
const setClientPid = useStore((s) => s.setClientPid);
3132
const setIsConnected = useStore((s) => s.setIsConnected);
3233
const setMessage = useStore((s) => s.setMessage);
@@ -156,21 +157,30 @@ export function Networks() {
156157
PATH: dirNetwork,
157158
},
158159
});
160+
const o = (d: string) => `${d.trim()}`;
159161
log.debug(`spawning command: ${cmd} ${args.join(" ")}`);
160162
command.on("close", (data) => {
161163
log.debug(`closed: ${cmd} code=${data.code} signal=${data.signal}`);
162164
setMessage("info", "Network client stopped.");
163165
});
164-
command.on("error", (e) => log.error(`${cmd}: ${e.trim()}`));
165-
command.stdout.on("data", (d) => log.info(`${cmd}: ${d.trim()}`));
166-
command.stderr.on("data", (d) => log.error(`${cmd}: ${d.trim()}`));
166+
command.on("error", (e) => log.error(o(e)));
167+
168+
command.stdout.on("data", (d) => {
169+
log.info(o(d));
170+
if (d.match(/client2/) === null) consoleAddLine(o(d));
171+
});
172+
173+
command.stderr.on("data", (d) => {
174+
log.error(o(d));
175+
if (d.match(/client2/) === null) consoleAddLine(o(d));
176+
});
167177

168178
const child = await command.spawn();
169179
return child.pid;
170180
}
171181

172182
return (
173-
<div className="flex flex-col items-center justify-center gap-5">
183+
<div className="flex flex-col items-center justify-center gap-4">
174184
<img
175185
src="/zkn.svg"
176186
alt="ZKN"

src/store/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export const useStore = create(
99
{
1010
appVersion: "",
1111
clientPid: 0,
12+
consoleLines: [] as string[],
13+
consoleLinesLimit: 100,
1214
isConnected: false,
1315
isPlatformSupported: false,
1416
message: "",
@@ -19,6 +21,12 @@ export const useStore = create(
1921
walletshieldListenAddress: "",
2022
},
2123
(set) => ({
24+
consoleAddLine: (line: string) =>
25+
set(({ consoleLines, consoleLinesLimit }) => {
26+
const next = [line, ...consoleLines].slice(0, consoleLinesLimit);
27+
return { consoleLines: next };
28+
}),
29+
2230
setAppVersion: (appVersion: string) => set({ appVersion }),
2331
setClientPid: (clientPid: number) => set({ clientPid }),
2432
setIsConnected: (isConnected: boolean) => set({ isConnected }),

0 commit comments

Comments
 (0)