fix(events): load older logs on terminal scroll

This commit is contained in:
2026-06-21 09:14:32 +03:30
parent c72ca7203f
commit 496b18fc22
2 changed files with 48 additions and 23 deletions

View File

@@ -36,6 +36,7 @@ export function EventsPage() {
const [loadingMore, setLoadingMore] = useState(false);
const [lastRefreshAt, setLastRefreshAt] = useState<string | null>(null);
const sentinelRef = useRef<HTMLDivElement | null>(null);
const feedRef = useRef<HTMLDivElement | null>(null);
const refreshFirstPage = useCallback(async (replace = false) => {
if (replace) setLoading(true);
@@ -74,19 +75,12 @@ export function EventsPage() {
}
}, [loadingMore, nextPageUrl]);
useEffect(() => {
const node = sentinelRef.current;
if (!node || !nextPageUrl) return undefined;
const observer = new IntersectionObserver(
(entries) => {
if (entries.some((entry) => entry.isIntersecting)) void loadMore();
},
{ rootMargin: "280px 0px" }
);
observer.observe(node);
return () => observer.disconnect();
}, [loadMore, nextPageUrl]);
const handleFeedScroll = useCallback(() => {
const node = feedRef.current;
if (!node || !nextPageUrl || loadingMore) return;
const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
if (distanceFromBottom <= 140) void loadMore();
}, [loadMore, loadingMore, nextPageUrl]);
const newestFirst = useMemo(() => [...events].sort((a, b) => b.id - a.id), [events]);
@@ -113,7 +107,7 @@ export function EventsPage() {
<code>job-events.log</code>
<span>refreshed {lastRefreshAt ? new Date(lastRefreshAt).toLocaleTimeString() : "-"}</span>
</div>
<div className="terminal-feed" role="log" aria-live="polite">
<div className="terminal-feed" role="log" aria-live="polite" onScroll={handleFeedScroll} ref={feedRef}>
{newestFirst.map((event) => (
<article className={`terminal-line ${eventTone(event.type)}`} key={event.id}>
<time className="terminal-time" dateTime={event.created_at}>
@@ -131,7 +125,6 @@ export function EventsPage() {
))}
{loading && !newestFirst.length && <EmptyState title="Loading events" />}
{!loading && !newestFirst.length && <EmptyState title="No events yet" />}
</div>
<div className="infinite-sentinel" ref={sentinelRef}>
{loadingMore && <span>Loading older events...</span>}
{!loadingMore && nextPageUrl && (
@@ -141,6 +134,7 @@ export function EventsPage() {
)}
{!loadingMore && !nextPageUrl && newestFirst.length > 0 && <span>End of event history</span>}
</div>
</div>
</section>
</div>
);

View File

@@ -35,6 +35,9 @@
--panel-raised: #f9fbfc;
--background: #f4f7f9;
--shadow: 0 18px 46px rgb(35 36 38 / 8%);
--terminal-scroll-thumb: #0bb3f0;
--terminal-scroll-thumb-hover: #f0bb0b;
--terminal-scroll-track: #171b1f;
color: var(--ink);
background: var(--background);
font-synthesis: none;
@@ -60,6 +63,9 @@
--panel-raised: #25282b;
--background: #141618;
--shadow: 0 18px 46px rgb(0 0 0 / 28%);
--terminal-scroll-thumb: #f0bb0b;
--terminal-scroll-thumb-hover: #55c8ff;
--terminal-scroll-track: #101316;
}
* {
@@ -1250,6 +1256,31 @@ label {
min-height: 420px;
overflow: auto;
padding: 8px;
scrollbar-color: var(--terminal-scroll-thumb) var(--terminal-scroll-track);
scrollbar-width: thin;
}
.terminal-feed::-webkit-scrollbar {
height: 10px;
width: 10px;
}
.terminal-feed::-webkit-scrollbar-track {
background: var(--terminal-scroll-track);
}
.terminal-feed::-webkit-scrollbar-thumb {
background: var(--terminal-scroll-thumb);
border: 2px solid var(--terminal-scroll-track);
border-radius: 999px;
}
.terminal-feed::-webkit-scrollbar-thumb:hover {
background: var(--terminal-scroll-thumb-hover);
}
.terminal-feed::-webkit-scrollbar-corner {
background: var(--terminal-scroll-track);
}
.terminal-line {