Skip to content

Commit

Permalink
fix scroll to top / bottom buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
marhaupe committed Sep 6, 2024
1 parent 55b978b commit 30f4cee
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 19 deletions.
15 changes: 6 additions & 9 deletions packages/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Histogram } from "@/Histogram";
import { Button } from "@/components/ui/button";
import { config } from "./config";
import { useHotkeys } from "react-hotkeys-hook";
import { LogList } from "./components/LogList";
import { LogList, LogListRef } from "./components/LogList";

const logSchema = Type.Object({
timestamp: Type.String(),
Expand All @@ -29,6 +29,8 @@ export function App() {
const searchInputRef = useRef<HTMLInputElement>(null);
const [eventSource, setEventSource] = useState<EventSource>();

const logListRef = useRef<LogListRef>(null);

useEffect(() => {
const url = new URL(config.agentUrl);
url.searchParams.set("stream", nanoid());
Expand Down Expand Up @@ -107,19 +109,14 @@ export function App() {
<Button
variant="outline"
className="p-2"
onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
onClick={() => logListRef.current?.scrollToTop()}
>
<ChevronsUp />
</Button>
<Button
variant="outline"
className="p-2"
onClick={() =>
window.scrollTo({
top: document.body.scrollHeight,
behavior: "smooth",
})
}
onClick={() => logListRef.current?.scrollToBottom()}
>
<ChevronsDown />
</Button>
Expand All @@ -129,7 +126,7 @@ export function App() {
ref={searchInputRef}
onFilterStateChange={(query) => setFilterState(query)}
/>
<LogList logs={logs} />
<LogList ref={logListRef} logs={logs} />
</Card>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/LogEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ export function LogEntry({
const [selectedMenuItem, setSelectedMenuItem] = useState<number>(0);
const menuItemRefs = useRef<(HTMLDivElement | null)[]>([]);

const handleDropdownOpenChange = (isOpen: boolean) => {
function handleDropdownOpenChange(isOpen: boolean) {
setSelectedMenuItem(0);
onDropdownOpenChange(isOpen);
};
}

useHotkeys(
"l,ArrowRight",
Expand Down
47 changes: 39 additions & 8 deletions packages/frontend/src/components/LogList.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import { useRef, useState, useEffect, useMemo, memo } from "react";
import React, {
useRef,
useState,
useEffect,
useMemo,
memo,
forwardRef,
useImperativeHandle,
} 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, areEqual } from "react-window";

export interface LogListRef {
scrollToTop: () => void;
scrollToBottom: () => void;
}

interface LogListProps {
logs: Log[];
}

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

export function LogList({ logs }: LogListProps) {
export const LogList = forwardRef<LogListRef, LogListProps>(({ logs }, ref) => {
const [selectedLogIndex, setSelectedLogIndex] = useState<number | null>(null);
const [openDropdownIndex, setOpenDropdownIndex] = useState<number | null>(
null
Expand All @@ -35,19 +48,24 @@ export function LogList({ logs }: LogListProps) {
return () => window.removeEventListener("resize", updateHeight);
}, []);

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

function scrollToIndex(index: number) {
listRef.current?.scrollToItem(index, "start");
setSelectedLogIndex(index);
}

useHotkeys(
"g,shift+g",
({ key }) => {
const newIndex = key === "g" ? 0 : logs.length - 1;
listRef.current?.scrollToItem(newIndex, "start");
setSelectedLogIndex(newIndex);
scrollToIndex(newIndex);
},
{ enabled: openDropdownIndex === null }
{ enabled: openDropdownIndex === null },
[logs.length]
);

useHotkeys(
Expand Down Expand Up @@ -86,6 +104,19 @@ export function LogList({ logs }: LogListProps) {
[logs, selectedLogIndex, openDropdownIndex]
);

useImperativeHandle(
ref,
() => ({
scrollToTop: () => {
scrollToIndex(0);
},
scrollToBottom: () => {
scrollToIndex(logs.length - 1);
},
}),
[logs.length]
);

return (
<div ref={containerRef} style={{ height: "100%" }}>
{logs.length > 0 ? (
Expand All @@ -107,7 +138,7 @@ export function LogList({ logs }: LogListProps) {
)}
</div>
);
}
});

interface RowData {
logs: Log[];
Expand Down

0 comments on commit 30f4cee

Please sign in to comment.