diff --git a/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTable.tsx b/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTable.tsx
index 2aa755867..b01c23d19 100644
--- a/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTable.tsx
+++ b/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTable.tsx
@@ -18,6 +18,7 @@ import {
import { ChapterTablePagination } from './ChapterTablePagination';
import {
chapterDownloadStatusesState,
+ chapterFilterGroupNamesState,
chapterListState,
seriesState,
sortedFilteredChapterListState,
@@ -34,13 +35,20 @@ import { Chapter, Languages, Series } from '@tiyo/common';
import routes from '@/common/constants/routes.json';
import {
DropdownMenu,
+ DropdownMenuGroup,
+ DropdownMenuSub,
+ DropdownMenuPortal,
+ DropdownMenuSubTrigger,
+ DropdownMenuSubContent,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
+ DropdownMenuItem
} from '@houdoku/ui/components/DropdownMenu';
import { Button } from '@houdoku/ui/components/Button';
+import { ScrollArea } from '@houdoku/ui/components/ScrollArea';
import {
ArrowDown,
ArrowUp,
@@ -48,21 +56,27 @@ import {
Download,
Eye,
EyeOff,
+ EllipsisVertical,
+ Filter,
FileCheck,
LanguagesIcon,
Play,
Settings2,
+ X,
} from 'lucide-react';
import { ChapterTableLanguageFilter } from './ChapterTableLanguageFilter';
import { ChapterTableGroupFilter } from './ChapterTableGroupFilter';
import { markChapters } from '@/renderer/features/library/utils';
import { downloaderClient } from '@/renderer/services/downloader';
import ipcChannels from '@/common/constants/ipcChannels.json';
+import { Badge } from '@houdoku/ui/components/Badge';
import { Checkbox } from '@houdoku/ui/components/Checkbox';
+import { Separator } from '@houdoku/ui/components/Separator';
import { TableColumnSortOrder } from '@/common/models/types';
import { FS_METADATA } from '@/common/temp_fs_metadata';
import { ContextMenu, ContextMenuTrigger } from '@houdoku/ui/components/ContextMenu';
import { ChapterTableContextMenu } from './ChapterTableContextMenu';
+import { ChapterTableReadFilter } from './ChapterTableReadFilter';
import { useEffect } from 'react';
import { currentTaskState } from '@/renderer/state/downloaderStates';
@@ -83,7 +97,8 @@ export function ChapterTable(props: ChapterTableProps) {
const setSeries = useSetRecoilState(seriesState);
const [chapterList, setChapterList] = useRecoilState(chapterListState);
const sortedFilteredChapterList = useRecoilValue(sortedFilteredChapterListState);
- const chapterLanguages = useRecoilValue(chapterLanguagesState);
+ const [filterGroupNames, setFilterGroupNames] = useRecoilState(chapterFilterGroupNamesState);
+ const [chapterLanguages, setChapterLanguages] = useRecoilState(chapterLanguagesState);
const [chapterListVolOrder, setChapterListVolOrder] = useRecoilState(chapterListVolOrderState);
const [chapterListChOrder, setChapterListChOrder] = useRecoilState(chapterListChOrderState);
const [chapterDownloadStatuses, setChapterDownloadStatuses] = useRecoilState(
@@ -99,11 +114,8 @@ export function ChapterTable(props: ChapterTableProps) {
table.toggleAllRowsSelected(!!value)}
+ checked={table.getIsAllPageRowsSelected()}
+ onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
/>
@@ -269,6 +281,10 @@ export function ChapterTable(props: ChapterTableProps) {
return table.getSelectedRowModel().rows.map((row) => row.original) as Chapter[];
};
+ const getAllChapters = (): Chapter[] => {
+ return table.getCoreRowModel().rows.map((row) => row.original) as Chapter[];
+ };
+
const getNextUnreadChapter = () => {
return sortedFilteredChapterList
.slice()
@@ -300,6 +316,17 @@ export function ChapterTable(props: ChapterTableProps) {
);
};
+ const setAllRead = (read: boolean) => {
+ markChapters(
+ getAllChapters(),
+ props.series,
+ read,
+ setChapterList,
+ setSeries,
+ chapterLanguages,
+ );
+ };
+
const downloadSelected = () => {
downloaderClient.add(
getSelectedChapters().map((chapter) => ({
@@ -311,79 +338,218 @@ export function ChapterTable(props: ChapterTableProps) {
downloaderClient.start();
};
+ const downloadAll = () => {
+ downloaderClient.add(
+ getAllChapters().map((chapter) => ({
+ chapter,
+ series: props.series,
+ downloadsDir: customDownloadsDir || defaultDownloadsDir,
+ })),
+ );
+ downloaderClient.start();
+ };
+
return (
- {table.getIsSomeRowsSelected() || table.getIsAllRowsSelected() ? (
-
-
-
- {/* TODO add confirmation prompt */}
-
-
- ) : (
- <>
-
-
-
chapter.groupName)),
+
+
+
+
+
+
+
+
+
+ chapter.groupName)),
+ )}
+ />
+
+
+
+
+
+
+
+
+
+
+
+ Options
+
+
+
+ Download Chapters
+
+
+
+
+ Download
+
+
+
+
+
+ downloadAll()}
+ className="flex items-center w-full"
>
- {column.id}
-
- );
- })}
-
-
- {getNextUnreadChapter() && (
-
-
-
- Continue
-
-
- )}
-
- >
- )}
+ All Chapters
+
+
+
+ downloadSelected()}
+ className="flex items-center w-full"
+ >
+ Selected Chapters
+
+
+
+
+
+
+
+
+ Mark Chapters
+
+ All Chapters
+
+
+
+ setAllRead(true)}
+ className="flex items-center w-full"
+ >
+
+ Read
+
+
+
+ setAllRead(false)}
+ className="flex items-center w-full"
+ >
+
+ Unread
+
+
+
+
+
+
+
+ Selected Chapters
+
+
+
+ setSelectedRead(true)}
+ className="flex items-center w-full"
+ >
+
+ Read
+
+
+
+ setSelectedRead(false)}
+ className="flex items-center w-full"
+ >
+
+ Unread
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ View
+
+
+
+ Columns
+
+ {table
+ .getAllColumns()
+ .filter((column) => column.getCanHide())
+ .map((column) => {
+ return (
+ column.toggleVisibility(!!value)}
+ onSelect={(event) => event.preventDefault()}
+ >
+ {column.id}
+
+ );
+ })}
+
+
+ {getNextUnreadChapter() && (
+
+
+
+ Continue
+
+
+ )}
+
-
+
-
+
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => {
diff --git a/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableGroupFilter.tsx b/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableGroupFilter.tsx
index 78a931013..c635b7c04 100644
--- a/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableGroupFilter.tsx
+++ b/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableGroupFilter.tsx
@@ -1,8 +1,6 @@
-import { Check, Filter } from 'lucide-react';
-
+import { Check, ChevronRight } from 'lucide-react';
import { cn } from '@houdoku/ui/util';
import { Badge } from '@houdoku/ui/components/Badge';
-import { Button } from '@houdoku/ui/components/Button';
import {
Command,
CommandEmpty,
@@ -35,9 +33,14 @@ export function ChapterTableGroupFilter(props: Props) {
return (
- setFilterGroupNames([])}>
-
+ setFilterGroupNames([])}>
{'Group'}
+
+ {filterGroupNames.length <= 0 && (
+
+ )}
{filterGroupNames.length > 0 && (
<>
@@ -51,9 +54,9 @@ export function ChapterTableGroupFilter(props: Props) {
>
)}
-
+
-
+
diff --git a/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableLanguageFilter.tsx b/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableLanguageFilter.tsx
index 9f30fde66..0e3d62eb1 100644
--- a/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableLanguageFilter.tsx
+++ b/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableLanguageFilter.tsx
@@ -1,7 +1,6 @@
-import { Check, Filter } from 'lucide-react';
+import { Check, ChevronRight } from 'lucide-react';
import { cn } from '@houdoku/ui/util';
import { Badge } from '@houdoku/ui/components/Badge';
-import { Button } from '@houdoku/ui/components/Button';
import {
Command,
CommandEmpty,
@@ -35,9 +34,13 @@ export function ChapterTableLanguageFilter() {
return (
- setChapterLanguages([])}>
-
+ setChapterLanguages([])}>
{'Language'}
+ {chapterLanguages.length <= 0 && (
+
+ )}
{chapterLanguages.length > 0 && (
<>
@@ -65,9 +68,9 @@ export function ChapterTableLanguageFilter() {
>
)}
-
+
-
+
diff --git a/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableReadFilter.tsx b/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableReadFilter.tsx
new file mode 100644
index 000000000..f0c16fc24
--- /dev/null
+++ b/apps/desktop/src/renderer/components/library/series/chapter-table/ChapterTableReadFilter.tsx
@@ -0,0 +1,28 @@
+import { useRecoilState } from 'recoil';
+import { hideUnreadChaptersState } from '@/renderer/state/libraryStates';
+import { Checkbox } from '@houdoku/ui/components/Checkbox';
+import { Label } from '@houdoku/ui/components/Label';
+export function ChapterTableReadFilter() {
+ const [hideReadChapters, setHideReadChapters] = useRecoilState(hideUnreadChaptersState);
+
+ const toggleReadChapters = () => {
+ setHideReadChapters(!hideReadChapters);
+ };
+
+ return (
+ e.stopPropagation()}>
+
+
+
+
+ );
+};
diff --git a/apps/desktop/src/renderer/state/libraryStates.ts b/apps/desktop/src/renderer/state/libraryStates.ts
index f7525e361..354d20210 100644
--- a/apps/desktop/src/renderer/state/libraryStates.ts
+++ b/apps/desktop/src/renderer/state/libraryStates.ts
@@ -95,6 +95,11 @@ export const activeSeriesListState = selector({
},
});
+export const hideUnreadChaptersState = atom({
+ key: 'hideUnreadChaptersState',
+ default: false,
+});
+
export const sortedFilteredChapterListState = selector({
key: 'sortedFilteredChapterListState',
get: ({ get }) => {
@@ -103,8 +108,8 @@ export const sortedFilteredChapterListState = selector({
const chapterFilterGroupNames = get(chapterFilterGroupNamesState);
const chapterListVolOrder = get(chapterListVolOrderState);
const chapterListChOrder = get(chapterListChOrderState);
-
const uniqueChapters = new Map();
+ const toggleReadChapters = get(hideUnreadChaptersState);
if (chapterLanguages.length > 0) {
chapterLanguages.forEach((lang) => {
@@ -129,8 +134,9 @@ export const sortedFilteredChapterListState = selector({
(uniqueChapters.has(chapter.chapterNumber) &&
uniqueChapters.get(chapter.chapterNumber) === chapter) ||
chapterLanguages.length === 0;
+ const readChapters = !toggleReadChapters || !chapter.read;
- return matchesLanguage && matchesGroup && unique;
+ return matchesLanguage && matchesGroup && unique && readChapters;
})
.sort((a, b) => {
const volumeComp = {
diff --git a/packages/ui/src/components/Table.tsx b/packages/ui/src/components/Table.tsx
index 30908eb82..79e1f53d3 100644
--- a/packages/ui/src/components/Table.tsx
+++ b/packages/ui/src/components/Table.tsx
@@ -4,7 +4,7 @@ import { cn } from '@houdoku/ui/util';
const Table = React.forwardRef>(
({ className, ...props }, ref) => (
-