Skip to content

Commit

Permalink
feat: added new collections filter
Browse files Browse the repository at this point in the history
  • Loading branch information
mbret committed Feb 25, 2024
1 parent e365d3a commit 6458c6c
Show file tree
Hide file tree
Showing 11 changed files with 797 additions and 656 deletions.
1,226 changes: 621 additions & 605 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
"@mui/material": "^5.11.11",
"@mui/styles": "^5.11.11",
"@oboku/shared": "0.8.0",
"@prose-reader/core": "1.39.0",
"@prose-reader/enhancer-hammer-gesture": "1.39.0",
"@prose-reader/react": "1.39.0",
"@prose-reader/shared": "1.39.0",
"@prose-reader/streamer": "1.39.0",
"@prose-reader/core": "1.41.0",
"@prose-reader/enhancer-hammer-gesture": "1.41.0",
"@prose-reader/react": "1.41.0",
"@prose-reader/shared": "1.41.0",
"@prose-reader/streamer": "1.41.0",
"@sentry/integrations": "^7.40.0",
"@sentry/react": "^7.40.0",
"buffer": "^6.0.3",
Expand Down
4 changes: 2 additions & 2 deletions packages/web/src/books/bookList/SortByDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Sorting = "alpha" | "date" | "activity"
export const SortByDialog: FC<{
onClose: () => void
open: boolean
onChange: (sort: Sorting) => void
onChange?: (sort: Sorting) => void
value?: Sorting
}> = ({ onClose, open, onChange, value = "date" }) => {
const [innerSorting, setInnerSorting] = useState<Sorting>(value)
Expand All @@ -28,7 +28,7 @@ export const SortByDialog: FC<{
const onSortChange = (newSorting: Sorting) => {
onClose()
setInnerSorting(newSorting)
onChange(newSorting)
onChange?.(newSorting)
}

return (
Expand Down
102 changes: 66 additions & 36 deletions packages/web/src/common/lists/ListActionsToolbar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { ComponentProps, FC, useState } from "react"
import { Toolbar, IconButton, useTheme, Button } from "@mui/material"
import { Toolbar, IconButton, useTheme, Button, Badge } from "@mui/material"
import {
AppsRounded,
ListRounded,
LockOpenRounded,
SortRounded
SortRounded,
TuneRounded
} from "@mui/icons-material"
import { SortByDialog } from "../../books/bookList/SortByDialog"
import { useSignalValue } from "reactjrx"
Expand All @@ -13,11 +14,20 @@ import { libraryStateSignal } from "../../library/states"
type Sorting = ComponentProps<typeof SortByDialog>["value"]

export const ListActionsToolbar: FC<{
viewMode: "grid" | "list"
sorting: Sorting
onViewModeChange: (viewMode: "list" | "grid") => void
onSortingChange: (sorting: Sorting) => void
}> = ({ viewMode, onViewModeChange, onSortingChange, sorting }) => {
viewMode?: "grid" | "list"
sorting?: Sorting
onViewModeChange?: (viewMode: "list" | "grid") => void
onSortingChange?: (sorting: Sorting) => void
numberOfFiltersApplied?: number
onFilterClick?: () => void
}> = ({
viewMode,
onViewModeChange,
onSortingChange,
sorting,
onFilterClick,
numberOfFiltersApplied = 0
}) => {
const theme = useTheme()
const library = useSignalValue(libraryStateSignal)
const [isSortingDialogOpened, setIsSortingDialogOpened] = useState(false)
Expand All @@ -30,27 +40,45 @@ export const ListActionsToolbar: FC<{
boxSizing: "border-box"
}}
>
<div
style={{
flexGrow: 1,
justifyContent: "flex-start",
flexFlow: "row",
display: "flex",
alignItems: "center"
}}
>
<Button
variant="text"
onClick={() => setIsSortingDialogOpened(true)}
startIcon={<SortRounded />}
{!!onFilterClick && (
<IconButton
edge="start"
onClick={() => onFilterClick && onFilterClick()}
size="large"
color="primary"
>
{sorting === "activity"
? "Recent activity"
: sorting === "alpha"
? "A > Z"
: "Date added"}
</Button>
</div>
{numberOfFiltersApplied > 0 ? (
<Badge badgeContent={numberOfFiltersApplied}>
<TuneRounded />
</Badge>
) : (
<TuneRounded />
)}
</IconButton>
)}
{!!sorting && (
<div
style={{
flexGrow: 1,
justifyContent: "flex-start",
flexFlow: "row",
display: "flex",
alignItems: "center"
}}
>
<Button
variant="text"
onClick={() => setIsSortingDialogOpened(true)}
startIcon={<SortRounded />}
>
{sorting === "activity"
? "Recent activity"
: sorting === "alpha"
? "A > Z"
: "Date added"}
</Button>
</div>
)}
{library.isLibraryUnlocked && (
<div
style={{
Expand All @@ -64,15 +92,17 @@ export const ListActionsToolbar: FC<{
<LockOpenRounded fontSize="small" />
</div>
)}
<IconButton
color="primary"
onClick={() => {
onViewModeChange(viewMode === "grid" ? "list" : "grid")
}}
size="large"
>
{viewMode === "grid" ? <AppsRounded /> : <ListRounded />}
</IconButton>
{!!viewMode && (
<IconButton
color="primary"
onClick={() => {
onViewModeChange?.(viewMode === "grid" ? "list" : "grid")
}}
size="large"
>
{viewMode === "grid" ? <AppsRounded /> : <ListRounded />}
</IconButton>
)}
</Toolbar>
<SortByDialog
value={sorting}
Expand Down
9 changes: 5 additions & 4 deletions packages/web/src/library/LibraryBooksScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
IconButton,
Badge,
Typography,
useTheme
useTheme,
Box
} from "@mui/material"
import makeStyles from "@mui/styles/makeStyles"
import {
Expand Down Expand Up @@ -98,7 +99,7 @@ export const LibraryBooksScreen = () => {
<Toolbar
style={{
borderBottom: `1px solid ${theme.palette.grey[200]}`,
boxSizing: "border-box"
boxSizing: "border-box",
}}
>
<IconButton
Expand Down Expand Up @@ -171,7 +172,7 @@ export const LibraryBooksScreen = () => {
{library.viewMode === "grid" ? <AppsRounded /> : <ListRounded />}
</IconButton>
</Toolbar>
<div
<Box
style={{
display: "flex",
flexDirection: "column",
Expand Down Expand Up @@ -263,7 +264,7 @@ export const LibraryBooksScreen = () => {
}
}}
/>
</div>
</Box>
</div>
)
}
Expand Down
25 changes: 25 additions & 0 deletions packages/web/src/library/collections/FilterBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ListActionsToolbar } from "../../common/lists/ListActionsToolbar"
import { FiltersDrawer } from "./FiltersDrawer"
import { useCallback, useState } from "react"

export const FilterBar = () => {
const [isFiltersDrawerOpen, setIsFiltersDrawerOpen] = useState(false)

const onFiltersDrawerClose = useCallback(() => {
setIsFiltersDrawerOpen(false)
}, [setIsFiltersDrawerOpen])

return (
<>
<ListActionsToolbar
onFilterClick={() => {
setIsFiltersDrawerOpen(true)
}}
/>
<FiltersDrawer
onClose={onFiltersDrawerClose}
open={isFiltersDrawerOpen}
/>
</>
)
}
56 changes: 56 additions & 0 deletions packages/web/src/library/collections/FiltersDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { FC, memo } from "react"
import {
Drawer,
List,
ListItemText,
ListItemIcon,
ListItemButton
} from "@mui/material"
import {
CheckCircleRounded,
RadioButtonUncheckedOutlined
} from "@mui/icons-material"
import { useSignalValue } from "reactjrx"
import { libraryStateSignal } from "../states"

export const FiltersDrawer: FC<{
open: boolean
onClose: () => void
}> = memo(({ open, onClose }) => {
const { showNotInterestedCollections } = useSignalValue(
libraryStateSignal,
({ showNotInterestedCollections }) => ({ showNotInterestedCollections })
)

return (
<>
<Drawer anchor="bottom" open={open} onClose={onClose}>
<div role="presentation">
<List>
<ListItemButton
onClick={() =>
libraryStateSignal.setValue((state) => ({
...state,
showNotInterestedCollections:
!state.showNotInterestedCollections
}))
}
>
<ListItemText
primary="Show not interested collections"
secondary="Does not hide collections which contains only not interested books"
/>
<ListItemIcon>
{showNotInterestedCollections ? (
<CheckCircleRounded />
) : (
<RadioButtonUncheckedOutlined />
)}
</ListItemIcon>
</ListItemButton>
</List>
</div>
</Drawer>
</>
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CollectionList } from "../../collections/list/CollectionList"
import { useDebouncedCallback } from "use-debounce"
import { signal, useSignalValue } from "reactjrx"
import { useLibraryCollections } from "../useLibraryCollections"
import { FilterBar } from "./FilterBar"

type Scroll = Parameters<
NonNullable<ComponentProps<typeof CollectionList>["onScroll"]>
Expand Down Expand Up @@ -46,7 +47,6 @@ export const LibraryCollectionScreen = () => {
const onScroll = useDebouncedCallback((value: Scroll) => {
libraryCollectionScreenPreviousScrollState.setValue(value)
}, 300)

const listHeader = useMemo(
() => (
<Toolbar>
Expand Down Expand Up @@ -80,6 +80,7 @@ export const LibraryCollectionScreen = () => {
return (
<div style={classes.container}>
{listHeaderDimTracker}
<FilterBar />
<CollectionList
style={classes.list}
data={collections}
Expand Down
1 change: 1 addition & 0 deletions packages/web/src/library/states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type LibraryDocType = {
readingStates: ReadingStateState[]
downloadState?: DownloadState | undefined
isNotInterested?: "only" | "hide"
showNotInterestedCollections?: boolean
}

export type LibrarySorting = "date" | "activity" | "alpha"
Expand Down
15 changes: 13 additions & 2 deletions packages/web/src/library/useLibraryCollections.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import { useCollectionsWithPrivacy } from "../collections/states"
import { useBooks } from "../books/states"
import { useMemo } from "react"
import { libraryStateSignal } from "./states"
import { useSignalValue } from "reactjrx"

export const useLibraryCollections = () => {
const { showNotInterestedCollections } = useSignalValue(
libraryStateSignal,
({ showNotInterestedCollections }) => ({ showNotInterestedCollections })
)
const { data: visibleCollections } = useCollectionsWithPrivacy()
const { data: books } = useBooks()

const collectionIds = useMemo(
() =>
visibleCollections
?.filter((collection) => {
if (collection.books.length === 0 || !books?.length) return true
if (
collection.books.length === 0 ||
!books?.length ||
showNotInterestedCollections
)
return true

const hasOneInterestedBook = collection.books.some((bookId) => {
const book = books?.find((item) => item._id === bookId)
Expand All @@ -21,7 +32,7 @@ export const useLibraryCollections = () => {
return hasOneInterestedBook
})
.map((collection) => collection._id),
[visibleCollections, books]
[visibleCollections, books, showNotInterestedCollections]
)

return { data: collectionIds }
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/navigation/AppNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { BackToReadingDialog } from "../reading/BackToReadingDialog"
import { CollectionActionsDrawer } from "../collections/CollectionActionsDrawer"
import { ProblemsScreen } from "../problems/ProblemsScreen"
import { LibraryBooksScreen } from "../library/LibraryBooksScreen"
import { LibraryCollectionScreen } from "../library/LibraryCollectionScreen"
import { LibraryCollectionScreen } from "../library/collections/LibraryCollectionScreen"
import { LibraryTagsScreen } from "../library/LibraryTagsScreen"
import { memo, useEffect, useRef } from "react"
import { UnlockLibraryDialog } from "../auth/UnlockLibraryDialog"
Expand Down

0 comments on commit 6458c6c

Please sign in to comment.