Skip to content

Commit

Permalink
Merge pull request #140 from mbret/develop
Browse files Browse the repository at this point in the history
feat: added compact mode
  • Loading branch information
mbret authored Jun 4, 2024
2 parents be59cc1 + 2b9a8fe commit c4915ee
Show file tree
Hide file tree
Showing 13 changed files with 268 additions and 154 deletions.
79 changes: 50 additions & 29 deletions packages/web/src/books/bookList/BookList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
import React, { useCallback, FC, memo } from "react"
import React, { useCallback, FC, memo, ReactNode } from "react"
import { Box, useTheme } from "@mui/material"
import { useWindowSize } from "react-use"
import { BookListGridItem } from "./BookListGridItem"
import { LibrarySorting } from "../../library/states"
import { BookListListItem } from "./BookListListItem"
import { ReactWindowList } from "../../common/lists/ReactWindowList"
import { ListActionViewMode } from "../../common/lists/ListActionsToolbar"
import { BookListCompactItem } from "./BookListCompactItem"
import { useListItemHeight } from "./useListItemHeight"

const ItemListContainer = ({
children,
isLast,
borders = false
}: {
children: ReactNode
isLast: boolean
borders?: boolean
}) => (
<Box
style={{
flex: 1,
alignItems: "center",
display: "flex",
height: "100%"
}}
{...(!isLast &&
borders && {
borderBottom: "1px solid",
borderColor: "grey.200"
})}
>
{children}
</Box>
)

export const BookList: FC<{
viewMode?: ListActionViewMode
Expand Down Expand Up @@ -43,47 +71,40 @@ export const BookList: FC<{
: dynamicNumberOfItems
: 1
const adjustedRatioWhichConsiderBottom = theme.custom.coverAverageRatio - 0.1
const densityMultiplier = density === "dense" ? 0.8 : 1
const listItemMargin =
(windowSize.width > theme.breakpoints.values["sm"] ? 20 : 10) *
densityMultiplier
const itemHeight =
viewMode === "grid"
? undefined
: ((windowSize.width > theme.breakpoints.values["sm"] ? 200 : 150) *
theme.custom.coverAverageRatio +
listItemMargin) *
densityMultiplier
const { itemHeight, itemMargin } = useListItemHeight({
density,
viewMode
})

// const rowBorderColor = theme.palette.grey[100]

const rowRenderer = useCallback(
(item: string, _: number, isLast: boolean) => {
return viewMode === "grid" ? (
<BookListGridItem bookId={item} />
) : (
<Box
{...(!isLast &&
{
// borderBottom: `1px solid ${rowBorderColor}`
})}
style={{
flex: 1,
alignItems: "center",
display: "flex",
height: "100%"
}}
>
) : viewMode === "list" ? (
<ItemListContainer isLast={isLast}>
<BookListListItem
bookId={item}
itemHeight={(itemHeight || 0) - listItemMargin}
itemHeight={(itemHeight || 0) - itemMargin}
onItemClick={onItemClick}
withDrawerActions={withBookActions}
pl={1}
/>
</ItemListContainer>
) : (
<ItemListContainer isLast={isLast} borders>
<BookListCompactItem
bookId={item}
itemHeight={(itemHeight || 0) - itemMargin}
onItemClick={onItemClick}
withDrawerActions={withBookActions}
pl={1}
/>
</Box>
</ItemListContainer>
)
},
[viewMode, itemHeight, listItemMargin, onItemClick, withBookActions]
[viewMode, itemHeight, itemMargin, onItemClick, withBookActions]
)

if (props.static) {
Expand All @@ -104,7 +125,7 @@ export const BookList: FC<{
}

return (
<Box style={style} px={isHorizontal ? 0 : 1} display="flex">
<Box style={style} display="flex">
<ReactWindowList
data={data}
rowRenderer={rowRenderer}
Expand Down
15 changes: 15 additions & 0 deletions packages/web/src/books/bookList/BookListCompactItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ComponentProps, memo } from "react"
import { BookListListItem } from "./BookListListItem"

export const BookListCompactItem = memo(
({ ...rest }: ComponentProps<typeof BookListListItem>) => {
return (
<BookListListItem
withCover={false}
withAuthors={false}
withDownloadIcons
{...rest}
/>
)
}
)
26 changes: 15 additions & 11 deletions packages/web/src/books/bookList/BookListCoverContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { FC, memo } from "react"
import { Box, Chip, useTheme } from "@mui/material"
import { Box, BoxProps, Chip, useTheme } from "@mui/material"
import {
CheckOutlined,
CloudDownloadRounded,
Expand All @@ -18,23 +18,26 @@ import { CoverIconBadge } from "./CoverIconBadge"

type Book = ReturnType<typeof useBook>["data"]

export const BookListCoverContainer: FC<{
bookId: string
className?: string
style?: React.CSSProperties
withReadingProgressStatus?: boolean
withDownloadStatus?: boolean
withBadges: boolean
size?: "small" | "large" | "medium"
}> = memo(
export const BookListCoverContainer: FC<
{
bookId: string
className?: string
style?: React.CSSProperties
withReadingProgressStatus?: boolean
withDownloadStatus?: boolean
withBadges: boolean
size?: "small" | "large" | "medium"
} & BoxProps
> = memo(
({
bookId,
className,
style,
withDownloadStatus = true,
withReadingProgressStatus = true,
withBadges,
size = "small"
size = "small",
...rest
}) => {
const { data: item } = useBook({ id: bookId })
const bookDownloadState = useBookDownloadState(bookId)
Expand All @@ -45,6 +48,7 @@ export const BookListCoverContainer: FC<{
<Box
style={{ ...classes.coverContainer, ...style }}
className={className}
{...rest}
>
{item && <Cover bookId={item?._id} />}
{bookDownloadState?.downloadState !== DownloadState.Downloaded && (
Expand Down
81 changes: 56 additions & 25 deletions packages/web/src/books/bookList/BookListListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Box, Chip, Stack, Typography, useTheme } from "@mui/material"
import { Box, BoxProps, Chip, Stack, Typography, useTheme } from "@mui/material"
import { FC, memo } from "react"
import { useDefaultItemClickHandler } from "./helpers"
import { useBook, useIsBookProtected } from "../states"
import { ReadingStateState } from "@oboku/shared"
import {
CloudDoneRounded,
CloudDownloadRounded,
DoneRounded,
DownloadDoneRounded,
DownloadingRounded,
ErrorRounded,
LoopRounded,
MenuBookRounded,
Expand All @@ -16,21 +20,31 @@ import { bookActionDrawerSignal } from "../drawer/BookActionsDrawer"
import { useCSS } from "../../common/utils"
import { BookListCoverContainer } from "./BookListCoverContainer"
import { getMetadataFromBook } from "../getMetadataFromBook"
import { useBookDownloadState } from "../../download/states"

export const BookListListItem: FC<{
bookId: string
onItemClick?: (id: string) => void
isSelected?: (id: string) => boolean
size?: "small" | "large"
itemHeight?: number
withDrawerActions?: boolean
}> = memo(
export const BookListListItem: FC<
{
bookId: string
onItemClick?: (id: string) => void
isSelected?: (id: string) => boolean
size?: "small" | "large"
itemHeight?: number
withDrawerActions?: boolean
withCover?: boolean
withAuthors?: boolean
withDownloadIcons?: boolean
} & BoxProps
> = memo(
({
bookId,
onItemClick,
size = "large",
itemHeight,
withDrawerActions = true
withDrawerActions = true,
withCover = true,
withAuthors = true,
withDownloadIcons = false,
...rest
}) => {
const { data: book } = useBook({
id: bookId
Expand All @@ -40,6 +54,7 @@ export const BookListListItem: FC<{
const computedHeight = itemHeight || (size === "small" ? 50 : 100)
const coverWidth = computedHeight * theme.custom.coverAverageRatio
const classes = useStyles({ coverWidth })
const bookDownloadState = useBookDownloadState(bookId)
const { data: isBookProtected = true } = useIsBookProtected(book)

const metadata = getMetadataFromBook(book)
Expand All @@ -57,20 +72,23 @@ export const BookListListItem: FC<{
cursor: "pointer",
flexGrow: 1
}}
{...rest}
>
<BookListCoverContainer
bookId={bookId}
style={classes.coverContainer}
withBadges={false}
withReadingProgressStatus={false}
/>
{withCover && (
<BookListCoverContainer
bookId={bookId}
style={classes.coverContainer}
withBadges={false}
withReadingProgressStatus={false}
mr={1}
/>
)}
<div
style={{
display: "flex",
flex: 1,
minHeight: 0,
flexDirection: "column",
marginLeft: theme.spacing(1),
overflow: "hidden"
}}
>
Expand All @@ -84,9 +102,11 @@ export const BookListListItem: FC<{
>
{metadata?.title || "Unknown"}
</Typography>
<Typography noWrap color="textSecondary" variant="body2">
{(metadata?.authors ?? [])[0] || "Unknown"}
</Typography>
{withAuthors && (
<Typography noWrap color="textSecondary" variant="body2">
{(metadata?.authors ?? [])[0] || "Unknown"}
</Typography>
)}
<Box
style={{
display: "flex",
Expand All @@ -96,17 +116,28 @@ export const BookListListItem: FC<{
}}
>
<Box display="flex" flexDirection="row" gap={1}>
{isBookProtected && <NoEncryptionRounded />}
{book?.isNotInterested && <ThumbDownOutlined />}
{withDownloadIcons && (
<>
{bookDownloadState?.isDownloading ? (
<DownloadingRounded color="action" />
) : bookDownloadState?.isDownloaded ? (
<CloudDoneRounded color="action" />
) : (
<CloudDownloadRounded color="action" />
)}
</>
)}
{isBookProtected && <NoEncryptionRounded color="action" />}
{book?.isNotInterested && <ThumbDownOutlined color="action" />}
{book?.readingStateCurrentState ===
ReadingStateState.Finished && (
<div style={{ display: "flex", flexDirection: "row" }}>
<DoneRounded style={{}} />
<DoneRounded style={{}} color="action" />
</div>
)}
{book?.readingStateCurrentState === ReadingStateState.Reading && (
<div style={{ display: "flex", flexDirection: "row" }}>
<MenuBookRounded />
<MenuBookRounded color="action" />
<Typography
style={{
marginLeft: theme.spacing(0.5)
Expand Down Expand Up @@ -165,7 +196,7 @@ export const BookListListItem: FC<{
{withDrawerActions && (
<Stack
justifyContent="center"
width={[30, 50]}
width={[40, 50]}
flexDirection="row"
style={{
alignItems: "center",
Expand Down
4 changes: 2 additions & 2 deletions packages/web/src/books/bookList/BookListWithControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export const BookListWithControls: FC<
}}
>
<ListActionsToolbar
viewMode={viewMode}
viewMode={viewMode ?? "grid"}
onViewModeChange={onViewModeChange}
sorting={sorting}
sorting={sorting ?? "alpha"}
onSortingChange={onSortingChange}
/>
<div
Expand Down
Loading

0 comments on commit c4915ee

Please sign in to comment.