Skip to content

Commit

Permalink
feat: added collection reading state
Browse files Browse the repository at this point in the history
  • Loading branch information
mbret committed Feb 27, 2024
1 parent be00b2e commit 0c393f6
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 52 deletions.
2 changes: 1 addition & 1 deletion packages/web/src/collections/CollectionDetailsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import CollectionBgSvg from "../assets/series-bg.svg"
import { useCollection } from "./states"
import { BookListWithControls } from "../books/bookList/BookListWithControls"
import { useVisibleBookIds } from "../books/states"
import { useCollectionActionsDrawer } from "./CollectionActionsDrawer/useCollectionActionsDrawer"
import { useCollectionActionsDrawer } from "../library/collections/CollectionActionsDrawer/useCollectionActionsDrawer"

type ScreenParams = {
id: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { CollectionDocType } from "@oboku/shared"
import { Cover } from "../../books/Cover"
import { useCollection } from "../states"
import { DeepReadonlyObject } from "rxdb"
import { useCollectionActionsDrawer } from "../CollectionActionsDrawer/useCollectionActionsDrawer"
import { useCollectionActionsDrawer } from "../../library/collections/CollectionActionsDrawer/useCollectionActionsDrawer"

const ListItem = styled(MuiListItem)(() => ({
height: `100%`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ import {
ThumbDownOutlined,
ThumbUpOutlined
} from "@mui/icons-material"
import { useCollection } from "../states"
import { ManageCollectionBooksDialog } from "../ManageCollectionBooksDialog"
import { useModalNavigationControl } from "../../navigation/useModalNavigationControl"
import { libraryStateSignal } from "../../library/states"
import { useCollection } from "../../../collections/states"
import { ManageCollectionBooksDialog } from "../../../collections/ManageCollectionBooksDialog"
import { useModalNavigationControl } from "../../../navigation/useModalNavigationControl"
import { libraryStateSignal } from "../../states"
import { useSignalValue } from "reactjrx"
import { useRemoveCollection } from "../useRemoveCollection"
import { useUpdateCollection } from "../useUpdateCollection"
import { useRemoveCollection } from "../../../collections/useRemoveCollection"
import { useUpdateCollection } from "../../../collections/useUpdateCollection"
import {
collectionActionDrawerChangesState,
collectionActionDrawerState
} from "./useCollectionActionsDrawer"
import { useUpdateBooks } from "../../books/useUpdateBooks"
import { useUpdateCollectionBooks } from "../useUpdateCollectionBooks"
import { useUpdateBooks } from "../../../books/useUpdateBooks"
import { useUpdateCollectionBooks } from "../../../collections/useUpdateCollectionBooks"

export const CollectionActionsDrawer: FC<{}> = () => {
const { openedWith: collectionId } = useSignalValue(
Expand Down
70 changes: 70 additions & 0 deletions packages/web/src/library/collections/CollectionStateDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
FormControl,
FormControlLabel,
Radio,
RadioGroup
} from "@mui/material"
import { FC } from "react"
import { useSignalValue } from "reactjrx"
import { collectionsListSignal } from "./state"

type State = ReturnType<(typeof collectionsListSignal)["getValue"]>
type ReadingState = State["readingState"]

export const getDisplayableReadingState = (readingState: ReadingState) => {
switch (readingState) {
case "ongoing":
return "Ongoing"
case "finished":
return "Finished"
default:
return "Any"
}
}

export const CollectionReadingStateDialog: FC<{
open: boolean
onClose: () => void
}> = ({ open, onClose }) => {
const state = useSignalValue(collectionsListSignal)
const readingStates = ["any", "ongoing", "finished"] as ReadingState[]

return (
<Dialog onClose={onClose} open={open}>
<DialogTitle>Reading state</DialogTitle>
<DialogContent>
<FormControl>
<RadioGroup
name="collection-state-radio-group"
value={state.readingState}
onChange={(event) => {
collectionsListSignal.setValue((state) => ({
...state,
readingState: event.target.value as ReadingState
}))
}}
>
{readingStates.map((readingState) => (
<FormControlLabel
key={readingState}
value={readingState}
control={<Radio />}
label={getDisplayableReadingState(readingState)}
/>
))}
</RadioGroup>
</FormControl>
</DialogContent>
<DialogActions>
<Button onClick={onClose} autoFocus>
Ok
</Button>
</DialogActions>
</Dialog>
)
}
33 changes: 32 additions & 1 deletion packages/web/src/library/collections/FiltersDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, memo } from "react"
import { FC, memo, useState } from "react"
import {
Drawer,
List,
Expand All @@ -7,11 +7,17 @@ import {
ListItemButton
} from "@mui/material"
import {
ArrowForwardIosRounded,
CheckCircleRounded,
RadioButtonUncheckedOutlined
} from "@mui/icons-material"
import { useSignalValue } from "reactjrx"
import { libraryStateSignal } from "../states"
import {
CollectionReadingStateDialog,
getDisplayableReadingState
} from "./CollectionStateDialog"
import { collectionsListSignal } from "./state"

export const FiltersDrawer: FC<{
open: boolean
Expand All @@ -21,12 +27,33 @@ export const FiltersDrawer: FC<{
libraryStateSignal,
({ showNotInterestedCollections }) => ({ showNotInterestedCollections })
)
const [isReadingStateDialogOpened, setIsReadingStateDialogOpened] =
useState(false)
const { readingState: collectionReadingState } = useSignalValue(
collectionsListSignal,
({ readingState }) => ({
readingState
})
)

return (
<>
<Drawer anchor="bottom" open={open} onClose={onClose}>
<div role="presentation">
<List>
<ListItemButton
onClick={() => {
setIsReadingStateDialogOpened(true)
}}
>
<ListItemText
primary="Reading state"
secondary={getDisplayableReadingState(collectionReadingState)}
/>
<ListItemIcon>
<ArrowForwardIosRounded />
</ListItemIcon>
</ListItemButton>
<ListItemButton
onClick={() =>
libraryStateSignal.setValue((state) => ({
Expand All @@ -51,6 +78,10 @@ export const FiltersDrawer: FC<{
</List>
</div>
</Drawer>
<CollectionReadingStateDialog
open={isReadingStateDialogOpened}
onClose={() => setIsReadingStateDialogOpened(false)}
/>
</>
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useCSS, useMeasureElement } from "../../common/utils"
import { CollectionList } from "../../collections/list/CollectionList"
import { useDebouncedCallback } from "use-debounce"
import { signal, useSignalValue } from "reactjrx"
import { useLibraryCollections } from "../useLibraryCollections"
import { useLibraryCollections } from "./useLibraryCollections"
import { FilterBar } from "./FilterBar"
import { useCreateCollection } from "../../collections/useCreateCollection"

Expand Down
10 changes: 10 additions & 0 deletions packages/web/src/library/collections/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { signal } from "reactjrx"

export const collectionsListSignal = signal<{
readingState: "ongoing" | "finished" | "any"
}>({
key: "collectionsListSignal",
default: {
readingState: "any"
}
})
76 changes: 76 additions & 0 deletions packages/web/src/library/collections/useLibraryCollections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useCollectionsWithPrivacy } from "../../collections/states"
import { useBooks } from "../../books/states"
import { useMemo } from "react"
import { libraryStateSignal } from "../states"
import { useSignalValue } from "reactjrx"
import { collectionsListSignal } from "./state"
import { ReadingStateState } from "@oboku/shared"

export const useLibraryCollections = () => {
const { showNotInterestedCollections } = useSignalValue(
libraryStateSignal,
({ showNotInterestedCollections }) => ({ showNotInterestedCollections })
)
const collectionReadingState = useSignalValue(
collectionsListSignal,
(state) => state.readingState
)
const { data: visibleCollections } = useCollectionsWithPrivacy()
const { data: books } = useBooks()

const collectionIds = useMemo(
() =>
visibleCollections
?.filter((collection) => {
const booksFromCollection =
books?.filter((book) => collection.books.includes(book._id)) ?? []

const onlyWantOngoingAndIsFinished =
collectionReadingState === "ongoing" &&
booksFromCollection.length > 0 &&
booksFromCollection.every(
(book) =>
book.readingStateCurrentState === ReadingStateState.Finished
)

const onlyWantFinishedAndHasSomeNonFinished =
collectionReadingState === "finished" &&
(booksFromCollection.some(
(book) =>
book.readingStateCurrentState !== ReadingStateState.Finished
) ||
booksFromCollection.length === 0)

if (
onlyWantFinishedAndHasSomeNonFinished ||
onlyWantOngoingAndIsFinished
) {
return false
}

if (
collection.books.length === 0 ||
!books?.length ||
showNotInterestedCollections
)
return true

const hasOneInterestedBook = collection.books.some((bookId) => {
const book = books?.find((item) => item._id === bookId)

return !book?.isNotInterested
})

return hasOneInterestedBook
})
.map((collection) => collection._id),
[
visibleCollections,
books,
showNotInterestedCollections,
collectionReadingState
]
)

return { data: collectionIds }
}
39 changes: 0 additions & 39 deletions packages/web/src/library/useLibraryCollections.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/web/src/navigation/AppNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { AuthCallbackScreen } from "../auth/AuthCallbackScreen"
import { SettingsScreen } from "../settings/SettingsScreen"
import { StatisticsScreen } from "../settings/StatisticsScreen"
import { BackToReadingDialog } from "../reading/BackToReadingDialog"
import { CollectionActionsDrawer } from "../collections/CollectionActionsDrawer/CollectionActionsDrawer"
import { CollectionActionsDrawer } from "../library/collections/CollectionActionsDrawer/CollectionActionsDrawer"
import { ProblemsScreen } from "../problems/ProblemsScreen"
import { LibraryBooksScreen } from "../library/LibraryBooksScreen"
import { LibraryCollectionScreen } from "../library/collections/LibraryCollectionScreen"
Expand Down
2 changes: 2 additions & 0 deletions packages/web/src/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { libraryStateSignal } from "../library/states"
import { readerSettingsStateSignal } from "../reader/settings/states"
import { bookBeingReadStatePersist } from "../reading/states"
import { localSettingsStatePersist } from "../settings/states"
import { collectionsListSignal } from "../library/collections/state"

export const signalEntriesToPersist = [
{ signal: libraryStateSignal, version: 0 },
{ signal: collectionsListSignal, version: 0 },
{ signal: normalizedBookDownloadsStatePersist, version: 0 },
{ signal: firstTimeExperienceStatePersist, version: 0 },
{ signal: localSettingsStatePersist, version: 0 },
Expand Down

0 comments on commit 0c393f6

Please sign in to comment.