Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion app/hooks/paginate.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { useCallback, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';

export default function usePagination(length) {
const [page, setPage] = useState({ start: 0, size: 10 });

// Keep the current page within bounds when the number of items shrinks.
useEffect(() => {
const maxStart = length <= 0 ? 0 : Math.floor((length - 1) / page.size) * page.size;
if (page.start > maxStart) {
setPage((current) => ({ ...current, start: maxStart }));
}
}, [length, page.start, page.size]);

const nextPage = useCallback(
() => setPage((current) => ({ ...current, start: current.start + current.size })),
[]
Expand Down
8 changes: 4 additions & 4 deletions app/routes/streams.$streamName.$from.$direction.$amount.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,26 +174,26 @@ export default function EventStreamPaged() {
<div className="button-row">
{prev <= 0 ? (
<button type="button" className="btn btn--ghost" disabled>
Prev
Newer
</button>
) : (
<Link
to={`/streams/${encodeURIComponent(streamName)}/${prev}/${direction}/${amount}`}
className="btn btn--ghost"
>
Prev
Newer
</Link>
)}
{next <= 0 ? (
<button type="button" className="btn btn--ghost" disabled>
Next
Older
</button>
) : (
<Link
to={`/streams/${encodeURIComponent(streamName)}/${next}/${direction}/${amount}`}
className="btn btn--ghost"
>
Next
Older
</Link>
)}
</div>
Expand Down
20 changes: 10 additions & 10 deletions app/routes/streams.$streamName.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ export async function loader({ params, request }) {
const storeNameOverride = url.searchParams.get('store') || undefined;
const { eventstore } = await getEventStore({ readOnly: true }, storeNameOverride);

const from = 1;
const amount = 10;
const direction = 'forwards';
const direction = 'backwards';
const events = [];
const streamIndex = eventstore.streams[streamName]?.index;
const streamIndexMetadata = streamIndex?.metadata || null;
Expand All @@ -31,11 +30,12 @@ export async function loader({ params, request }) {
partitionMetadata = writePartition.metadata || null;
}

const until = from + amount - 1;
const streamLength = eventstore.getStreamVersion(streamName);
const from = streamLength; // start from the newest event
const until = Math.max(1, from - amount + 1);
let stream = eventstore.getEventStream(streamName);
if (stream !== false) {
stream = stream.from(from).forwards(amount);
stream = stream.from(from).backwards(amount);
stream.forEach((payload, metadata, stream) => {
events.push({ payload, metadata, stream });
});
Expand All @@ -46,8 +46,8 @@ export async function loader({ params, request }) {
stream: events,
direction,
amount,
next: until >= streamLength ? 0 : until + 1,
prev: from - amount,
next: until <= 1 ? 0 : until - 1, // older events
prev: 0, // already at newest
streamInfo: {
indexMetadata: streamIndexMetadata,
matcher,
Expand Down Expand Up @@ -163,26 +163,26 @@ export default function EventStream() {
<div className="button-row">
{prev <= 0 ? (
<button type="button" className="btn btn--soft-primary" disabled>
Prev
Newer
</button>
) : (
<Link
to={`/streams/${encodeURIComponent(streamName)}/${prev}/${direction}/${amount}`}
className="btn btn--soft-primary"
>
Prev
Newer
</Link>
)}
{next <= 0 ? (
<button type="button" className="btn btn--soft-primary" disabled>
Next
Older
</button>
) : (
<Link
to={`/streams/${encodeURIComponent(streamName)}/${next}/${direction}/${amount}`}
className="btn btn--soft-primary"
>
Next
Older
</Link>
)}
</div>
Expand Down
Loading
Loading