Skip to content

Commit

Permalink
virtualization shourt hopefully work now
Browse files Browse the repository at this point in the history
  • Loading branch information
marhaupe committed Sep 6, 2024
1 parent edd29e8 commit 6509110
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 2 deletions.
6 changes: 4 additions & 2 deletions packages/frontend/src/LogEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export function LogEntry({
.map((part: anser.AnserJsonEntry, index: number) => (
<span
key={index}
// This should stay stable to keep the line height consistent
className="inline-block h-5 leading-5"
style={{
color: ANSI_COLOR_MAP[part.fg] || "inherit",
backgroundColor: ANSI_COLOR_MAP[part.bg] || "inherit",
Expand All @@ -110,7 +112,7 @@ export function LogEntry({
<div
onClick={onSelect}
className={cn(
"flex w-full group relative min-h-4",
"flex w-full group relative h-full items-center px-4",
isHovered && "bg-slate-50",
isSelected && "bg-slate-100"
)}
Expand All @@ -120,7 +122,7 @@ export function LogEntry({
<div className="flex-shrink-0 w-32 text-slate-400 font-mono text-sm tracking-tighter select-none">
{new Date(log.timestamp).toISOString().split("T")[1]}
</div>
<div className="flex-grow whitespace-pre font-mono text-sm tracking-tight overflow-x-auto">
<div className="flex-grow whitespace-pre font-mono text-sm tracking-tight overflow-x-auto flex-col">
{renderLogMessage(log.message)}
</div>
<div
Expand Down
111 changes: 111 additions & 0 deletions packages/frontend/src/components/LogList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { useRef, useState, useEffect } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { LogEntry } from "../LogEntry";
import { Log } from "../App";
import { CardContent } from "./ui/card";
import { LucideLoaderCircle } from "lucide-react";
import { VariableSizeList as List } from "react-window";

interface LogListProps {
logs: Log[];
}

const REM_IN_PX = 4;
const LINE_HEIGHT = 5 * REM_IN_PX;

export function LogList({ logs }: LogListProps) {
const [selectedLogIndex, setSelectedLogIndex] = useState<number | null>(null);
const [openDropdownIndex, setOpenDropdownIndex] = useState<number | null>(
null
);
const listRef = useRef<List>(null);
const [listHeight, setListHeight] = useState(0);
const containerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const updateHeight = () => {
if (containerRef.current) {
const { top } = containerRef.current.getBoundingClientRect();
setListHeight(window.innerHeight - top);
}
};

updateHeight();
window.addEventListener("resize", updateHeight);
return () => window.removeEventListener("resize", updateHeight);
}, []);

const getItemSize = (index: number) => {
const lineCount = logs[index].message.split("\n").length;
return lineCount * LINE_HEIGHT;
};

useHotkeys(
"j,k",
({ key }) => {
setSelectedLogIndex((prevIndex) => {
if (prevIndex === null) return 0;
const newIndex =
key === "j" || key === "ArrowDown"
? Math.min(prevIndex + 1, logs.length - 1)
: Math.max(prevIndex - 1, 0);
listRef.current?.scrollToItem(newIndex, "smart");
return newIndex;
});
},
{
enabled: openDropdownIndex === null,
}
);

const Row = ({
index,
style,
}: {
index: number;
style: React.CSSProperties;
}) => {
const log = logs[index];
const isSelected = index === selectedLogIndex;
const isDropdownOpen = index === openDropdownIndex;

return (
<div style={style}>
<LogEntry
log={log}
isSelected={isSelected}
isDropdownOpen={isDropdownOpen}
onSelect={() => setSelectedLogIndex(index)}
onDropdownOpenChange={(isOpen) => {
if (isOpen) {
setOpenDropdownIndex(index);
} else {
setOpenDropdownIndex(null);
}
}}
/>
</div>
);
};

return (
<div ref={containerRef} style={{ height: "100%" }}>
{logs.length > 0 ? (
<List
ref={listRef}
height={listHeight}
itemCount={logs.length}
itemSize={getItemSize}
width="100%"
>
{Row}
</List>
) : (
<CardContent className="text-slate-500 flex flex-row gap-2 flex-1 justify-center items-center h-full">
Waiting for logs
<LucideLoaderCircle className="animate-spin" />
</CardContent>
)}
</div>
);
}

0 comments on commit 6509110

Please sign in to comment.