aboutsummaryrefslogtreecommitdiffstats
path: root/ui/src/components/HistoryList.tsx
diff options
context:
space:
mode:
authorEllie Huxtable <ellie@elliehuxtable.com>2024-05-06 08:11:47 +0100
committerGitHub <noreply@github.com>2024-05-06 08:11:47 +0100
commit754ddeaa8d3e3e4f3efc93d5bb22c68c31bb5c36 (patch)
treef48fb912c2be2d08855e97ff24b6919a115c3c4f /ui/src/components/HistoryList.tsx
parentchore(deps): bump serde_with from 3.7.0 to 3.8.1 (#2002) (diff)
downloadatuin-754ddeaa8d3e3e4f3efc93d5bb22c68c31bb5c36.zip
feat(ui): scroll history infinitely (#1999)
* wip, history scrolls right! * wip * virtual scroll fucking worksssss * paging works :) * scroll search results now too
Diffstat (limited to 'ui/src/components/HistoryList.tsx')
-rw-r--r--ui/src/components/HistoryList.tsx126
1 files changed, 69 insertions, 57 deletions
diff --git a/ui/src/components/HistoryList.tsx b/ui/src/components/HistoryList.tsx
index 9616ecf0..7cdeacd8 100644
--- a/ui/src/components/HistoryList.tsx
+++ b/ui/src/components/HistoryList.tsx
@@ -1,3 +1,4 @@
+import { useRef } from "react";
import { ChevronRightIcon } from "@heroicons/react/20/solid";
// @ts-ignore
@@ -19,70 +20,81 @@ function msToTime(ms: number) {
export default function HistoryList(props: any) {
return (
- <ul
+ <div
role="list"
- className="divide-y divide-gray-100 overflow-hidden bg-white shadow-sm ring-1 ring-gray-900/5"
+ className="divide-y divide-gray-100 bg-white shadow-sm ring-1 ring-gray-900/5 overflow-auto"
+ style={{
+ height: `${props.height}px`,
+ position: "relative",
+ }}
>
- {props.history.map((h: any) => (
- <li
- key={h.id}
- className="relative flex justify-between gap-x-6 px-4 py-5 hover:bg-gray-50 sm:px-6"
- >
- <div className="flex min-w-0 gap-x-4">
- <div className="flex flex-col justify-center">
- <p className="flex text-xs text-gray-500 justify-center">
- {DateTime.fromMillis(h.timestamp / 1000000).toLocaleString(
- DateTime.TIME_WITH_SECONDS,
- )}
- </p>
- <p className="flex text-xs mt-1 text-gray-400 justify-center">
- {DateTime.fromMillis(h.timestamp / 1000000).toLocaleString(
- DateTime.DATE_SHORT,
- )}
- </p>
- </div>
- <div className="min-w-0 flex-col justify-center">
- <pre className="whitespace-pre-wrap">
- <code className="text-sm">{h.command}</code>
- </pre>
- <p className="mt-1 flex text-xs leading-5 text-gray-500">
- <span className="relative truncate ">{h.user}</span>
+ {props.items.map((i: any) => {
+ let h = props.history[i.index];
- <span>&nbsp;on&nbsp;</span>
+ return (
+ <li
+ key={h.id}
+ className="relative flex justify-between gap-x-6 px-4 py-5 hover:bg-gray-50 sm:px-6"
+ style={{
+ position: "absolute",
+ top: 0,
+ left: 0,
+ width: "100%",
+ height: `${i.size}px`,
+ transform: `translateY(${i.start}px)`,
+ }}
+ >
+ <div className="flex min-w-0 gap-x-4">
+ <div className="flex flex-col justify-center">
+ <p className="flex text-xs text-gray-500 justify-center">
+ {DateTime.fromMillis(h.timestamp / 1000000).toLocaleString(
+ DateTime.TIME_WITH_SECONDS,
+ )}
+ </p>
+ <p className="flex text-xs mt-1 text-gray-400 justify-center">
+ {DateTime.fromMillis(h.timestamp / 1000000).toLocaleString(
+ DateTime.DATE_SHORT,
+ )}
+ </p>
+ </div>
+ <div className="min-w-0 flex-col justify-center">
+ <pre className="whitespace-pre-wrap">
+ <code className="text-sm">{h.command}</code>
+ </pre>
+ <p className="mt-1 flex text-xs leading-5 text-gray-500">
+ <span className="relative truncate ">{h.user}</span>
- <span className="relative truncate ">{h.host}</span>
+ <span>&nbsp;on&nbsp;</span>
- <span>&nbsp;in&nbsp;</span>
+ <span className="relative truncate ">{h.host}</span>
- <span className="relative truncate ">{h.cwd}</span>
- </p>
- </div>
- </div>
- <div className="flex shrink-0 items-center gap-x-4">
- <div className="hidden sm:flex sm:flex-col sm:items-end">
- <p className="text-sm leading-6 text-gray-900">{h.exit}</p>
- {h.duration ? (
- <p className="mt-1 text-xs leading-5 text-gray-500">
- <time dateTime={h.duration}>
- {msToTime(h.duration / 1000000)}
- </time>
+ <span>&nbsp;in&nbsp;</span>
+
+ <span className="relative truncate ">{h.cwd}</span>
</p>
- ) : (
- <div className="mt-1 flex items-center gap-x-1.5">
- <div className="flex-none rounded-full bg-emerald-500/20 p-1">
- <div className="h-1.5 w-1.5 rounded-full bg-emerald-500" />
- </div>
- <p className="text-xs leading-5 text-gray-500">Online</p>
- </div>
- )}
+ </div>
+ </div>
+ <div className="flex shrink-0 items-center gap-x-4">
+ <div className="hidden sm:flex sm:flex-col sm:items-end">
+ <p className="text-sm leading-6 text-gray-900">{h.exit}</p>
+ {h.duration ? (
+ <p className="mt-1 text-xs leading-5 text-gray-500">
+ <time dateTime={h.duration}>
+ {msToTime(h.duration / 1000000)}
+ </time>
+ </p>
+ ) : (
+ <div />
+ )}
+ </div>
+ <ChevronRightIcon
+ className="h-5 w-5 flex-none text-gray-400"
+ aria-hidden="true"
+ />
</div>
- <ChevronRightIcon
- className="h-5 w-5 flex-none text-gray-400"
- aria-hidden="true"
- />
- </div>
- </li>
- ))}
- </ul>
+ </li>
+ );
+ })}
+ </div>
);
}