Skip to content

Commit

Permalink
polish: books loading (#28)
Browse files Browse the repository at this point in the history
- move the book skeleton loading to the books component so the pagination is displayed while loading
- delay the books loading animation by 50 milliseconds to avoid flicker while developing locally
  • Loading branch information
dylants authored Jan 29, 2024
1 parent 4694576 commit db34da3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 23 deletions.
40 changes: 22 additions & 18 deletions src/app/list/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { DEFAULT_LIMIT } from '@/lib/pagination';
import { useCallback, useEffect, useState } from 'react';
import Book from '@/types/Book';
import PageInfo from '@/types/PageInfo';
import BookSkeleton from '@/components/BookSkeleton';

export default function ListPage() {
const [books, setBooks] = useState<Array<Book> | null>();
const [pageInfo, setPageInfo] = useState<PageInfo>();
const [isLoading, setIsLoading] = useState<boolean>(false);

const initialLoad = useCallback(async () => {
const { books, pageInfo } = await getBooks({
Expand All @@ -26,8 +26,17 @@ export default function ListPage() {
initialLoad();
}, [initialLoad]);

// Delay the loading animation a tiny amount to avoid screen flicker for quick connections (localhost)
const setDelayedLoading = useCallback(() => {
const timeout = setTimeout(() => setIsLoading(true), 50);
return () => {
setIsLoading(false);
clearTimeout(timeout);
};
}, []);

const onNext = useCallback(async () => {
setBooks(null);
const doneLoading = setDelayedLoading();
const { books: newBooks, pageInfo: newPageInfo } = await getBooks({
paginationQuery: {
after: pageInfo?.endCursor,
Expand All @@ -36,10 +45,11 @@ export default function ListPage() {
});
setBooks(newBooks);
setPageInfo(newPageInfo);
}, [pageInfo]);
doneLoading();
}, [pageInfo, setDelayedLoading]);

const onPrevious = useCallback(async () => {
setBooks(null);
const doneLoading = setDelayedLoading();
const { books: newBooks, pageInfo: newPageInfo } = await getBooks({
paginationQuery: {
before: pageInfo?.startCursor,
Expand All @@ -48,26 +58,20 @@ export default function ListPage() {
});
setBooks(newBooks);
setPageInfo(newPageInfo);
}, [pageInfo]);
doneLoading();
}, [pageInfo, setDelayedLoading]);

return (
<>
<h1 className="text-2xl text-customPalette-500 my-4">Books</h1>
<hr className="mt-4 mb-8 border-customPalette-300" />

{!books || !pageInfo ? (
<div className="flex flex-col gap-8">
<BookSkeleton />
<BookSkeleton />
<BookSkeleton />
</div>
) : (
<Books
books={books}
onNext={pageInfo.hasNextPage ? onNext : undefined}
onPrevious={pageInfo.hasPreviousPage ? onPrevious : undefined}
/>
)}
<Books
books={books ?? []}
isLoading={isLoading || !books}
onNext={pageInfo?.hasNextPage ? onNext : undefined}
onPrevious={pageInfo?.hasPreviousPage ? onPrevious : undefined}
/>
</>
);
}
23 changes: 18 additions & 5 deletions src/components/Books.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import Book from '@/components/Book';
import BookSkeleton from '@/components/BookSkeleton';
import {
Pagination,
PaginationContent,
Expand All @@ -12,19 +13,31 @@ import BookType from '@/types/Book';

export default function Books({
books,
isLoading,
onNext,
onPrevious,
}: {
books: Array<BookType>;
isLoading?: boolean;
onNext?: () => Promise<void>;
onPrevious?: () => Promise<void>;
}) {
return (
<>
<div className="flex flex-col gap-8">
{books.map((book) => (
<Book key={book.isbn} book={book} />
))}
{isLoading ? (
<>
<BookSkeleton />
<BookSkeleton />
<BookSkeleton />
</>
) : (
<>
{books.map((book) => (
<Book key={book.isbn} book={book} />
))}
</>
)}
</div>
<div className="mt-8">
<Pagination>
Expand All @@ -33,14 +46,14 @@ export default function Books({
<PaginationPrevious
href="#"
onClick={onPrevious ? onPrevious : undefined}
isDisabled={!onPrevious}
isDisabled={!onPrevious || isLoading}
/>
</PaginationItem>
<PaginationItem>
<PaginationNext
href="#"
onClick={onNext ? onNext : undefined}
isDisabled={!onNext}
isDisabled={!onNext || isLoading}
/>
</PaginationItem>
</PaginationContent>
Expand Down

0 comments on commit db34da3

Please sign in to comment.