diff --git a/src/BloomBrowserUI/collectionsTab/BookButton.tsx b/src/BloomBrowserUI/collectionsTab/BookButton.tsx index bd4d93a0352e..95bc447c4d7a 100644 --- a/src/BloomBrowserUI/collectionsTab/BookButton.tsx +++ b/src/BloomBrowserUI/collectionsTab/BookButton.tsx @@ -27,6 +27,8 @@ import { MenuItemSpec } from "./BooksOfCollection"; +export const bookButtonHeight = 120; + export const BookButton: React.FunctionComponent<{ book: IBookInfo; collection: ICollection; @@ -190,7 +192,6 @@ export const BookButton: React.FunctionComponent<{ props.book.title ); - const buttonHeight = 120; const renameHeight = 40; const downSize = 14; // size of down-arrow icon @@ -270,7 +271,7 @@ export const BookButton: React.FunctionComponent<{ (teamCollectionStatus?.who ? " checkedOut" : "") } css={css` - height: ${buttonHeight}px; + height: ${bookButtonHeight}px; width: 90px; border: none; overflow: hidden; @@ -372,7 +373,7 @@ export const BookButton: React.FunctionComponent<{ height: ${renameHeight}px; margin-left: 1px; border: 1px solid ${kBloomLightBlue}; - top: ${buttonHeight - renameHeight - 6}px; + top: ${bookButtonHeight - renameHeight - 6}px; padding-top: 4px; position: absolute; font-size: 12px; diff --git a/src/BloomBrowserUI/collectionsTab/BooksOfCollection.tsx b/src/BloomBrowserUI/collectionsTab/BooksOfCollection.tsx index 67646725bd53..9b466b4f5152 100644 --- a/src/BloomBrowserUI/collectionsTab/BooksOfCollection.tsx +++ b/src/BloomBrowserUI/collectionsTab/BooksOfCollection.tsx @@ -5,7 +5,7 @@ import { BloomApi } from "../utils/bloomApi"; import Menu from "@material-ui/core/Menu"; import MenuItem from "@material-ui/core/MenuItem"; import NestedMenuItem from "material-ui-nested-menu-item"; -import { BookButton } from "./BookButton"; +import { BookButton, bookButtonHeight } from "./BookButton"; import { useMonitorBookSelection } from "../app/selectedBook"; import { element } from "prop-types"; import { useL10n } from "../react_components/l10nHooks"; @@ -13,6 +13,7 @@ import { useState } from "react"; import { useSubscribeToWebSocketForEvent } from "../utils/WebSocketManager"; import { Divider } from "@material-ui/core"; import { BookSelectionManager, useIsSelected } from "./bookSelectionManager"; +import LazyLoad from "react-lazyload"; export interface IBookInfo { id: string; @@ -33,6 +34,11 @@ export const BooksOfCollection: React.FunctionComponent<{ collectionId: string; isEditableCollection: boolean; manager: BookSelectionManager; + // If supplied, the collection will be wrapped in a LazyLoad so that most of its rendering + // isn't done until it is visible on screen. This requires that we can identify the containing + // element which actually scrolls the BooksOfCollection into and out of view. This prop is + // required to be a selector which will select that exact element. + lazyContainer?: string; }> = props => { if (!props.collectionId) { window.alert("null collectionId"); @@ -139,7 +145,13 @@ export const BooksOfCollection: React.FunctionComponent<{ props.collectionId ); - return ( + // This is an approximation. 5 buttons per line is about what we get in a default + // layout on a fairly typical screen. We'd get a better approximation if we used + // the width of a button and knew the width of the container. But I think this is good + // enough. Worst case, we expand a bit more than we need. + const collectionHeight = bookButtonHeight * Math.ceil(books.length / 5); + + const content = (