Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,17 @@ 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 {
Expand All @@ -48,6 +54,8 @@ import {
Download,
Eye,
EyeOff,
EllipsisVertical,
Filter,
FileCheck,
LanguagesIcon,
Play,
Expand All @@ -63,6 +71,7 @@ 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';

Expand Down Expand Up @@ -99,11 +108,8 @@ export function ChapterTable(props: ChapterTableProps) {
<div className="flex justify-start">
<span className="w-5 h-5">
<Checkbox
checked={
table.getIsAllRowsSelected() ||
(table.getIsSomePageRowsSelected() && 'indeterminate')
}
onCheckedChange={(value) => table.toggleAllRowsSelected(!!value)}
checked={table.getIsAllPageRowsSelected()}
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
/>
</span>
</div>
Expand Down Expand Up @@ -269,6 +275,11 @@ export function ChapterTable(props: ChapterTableProps) {
return table.getSelectedRowModel().rows.map((row) => row.original) as Chapter[];
};

const getAllChapters = (): Chapter[] => {
console.log(table.getCoreRowModel())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this

return table.getCoreRowModel().rows.map((row) => row.original) as Chapter[];
};

const getNextUnreadChapter = () => {
return sortedFilteredChapterList
.slice()
Expand Down Expand Up @@ -300,6 +311,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) => ({
Expand All @@ -311,75 +333,197 @@ export function ChapterTable(props: ChapterTableProps) {
downloaderClient.start();
};

const downloadAll = () => {
downloaderClient.add(
getAllChapters().map((chapter) => ({
chapter,
series: props.series,
downloadsDir: customDownloadsDir || defaultDownloadsDir,
})),
);
downloaderClient.start();
};

return (
<div className="space-y-2 pb-4">
<div className="flex items-center justify-between">
{table.getIsSomeRowsSelected() || table.getIsAllRowsSelected() ? (
<div className="flex space-x-2 items-end">
<Button className="ml-auto" onClick={() => setSelectedRead(true)}>
<Eye className="w-4 h-4" />
Mark selected read
</Button>
<Button className="ml-auto" onClick={() => setSelectedRead(false)}>
<EyeOff className="w-4 h-4" />
Mark selected unread
</Button>
{/* TODO add confirmation prompt */}
<Button className="ml-auto" onClick={() => downloadSelected()}>
<Download className="w-4 h-4" />
Download selected
</Button>
</div>
) : (
<>
<div className="flex space-x-2">
<ChapterTableLanguageFilter />
<ChapterTableGroupFilter
uniqueGroupNames={Array.from(
new Set(chapterList.map((chapter) => chapter.groupName)),
)}
/>
</div>
<div className="flex space-x-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="ml-auto">
<Settings2 className="w-4 h-4" />
View
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Columns</DropdownMenuLabel>
<DropdownMenuSeparator />
{table
.getAllColumns()
.filter((column) => column.getCanHide())
.map((column) => {
return (
<DropdownMenuCheckboxItem
key={column.id}
className="capitalize"
checked={column.getIsVisible()}
onCheckedChange={(value) => column.toggleVisibility(!!value)}
onSelect={(event) => event.preventDefault()}
<div className="flex space-x-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">
<Filter className="w-4 h-4" />
Filters
</Button>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't need to be part of this PR, but I think it would be good to have a badge with X selected on the button when either language/group filters are applied.

</DropdownMenuTrigger>
<DropdownMenuContent className="w-51 flex flex-col" align="start">
<DropdownMenuItem asChild>
<ChapterTableLanguageFilter />
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild className="w-full">
<ChapterTableGroupFilter
uniqueGroupNames={Array.from(
new Set(chapterList.map((chapter) => chapter.groupName)),
)}
/>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<ChapterTableReadFilter />
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">
<EllipsisVertical className="w-4 h-4" />
Options</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-51" align="start">
<DropdownMenuGroup>
<DropdownMenuLabel>Download Chapters</DropdownMenuLabel>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<div
className="flex items-center w-full"
>
<Download className="w-4 h-4 mr-2" />
Download
</div>
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>
<div
onClick={() => downloadAll()}
className="flex items-center w-full"
>
<span>All Chapters</span>
</div>
</DropdownMenuItem>
<DropdownMenuSeparator />
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this separator

<DropdownMenuItem>
<div
onClick={() => downloadSelected()}
className="flex items-center w-full"
>
<span>Selected Chapters</span>
</div>
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel>Mark Chapters</DropdownMenuLabel>
<DropdownMenuSub>
<DropdownMenuSubTrigger>All Chapters</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>
<div
onClick={() => setAllRead(true)}
className="flex items-center w-full"
>
<Eye className="w-4 h-4 mr-2" />
<span>Read</span>
</div>
</DropdownMenuItem>
<DropdownMenuSeparator />
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this separator

<DropdownMenuItem>
<div
onClick={() => setAllRead(false)}
className="flex items-center w-full"
>
<EyeOff className="w-4 h-4 mr-2" />
<span>Unread</span>
</div>
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>

<DropdownMenuSub>
<DropdownMenuSubTrigger>Selected Chapters</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>
<div
onClick={() => setSelectedRead(true)}
className="flex items-center w-full"
>
{column.id}
</DropdownMenuCheckboxItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
{getNextUnreadChapter() && (
<Link to={`${routes.READER}/${props.series.id}/${getNextUnreadChapter()?.id}`}>
<Button variant="outline">
<Play className="w-4 h-4" />
Continue
</Button>
</Link>
)}
<Eye className="w-4 h-4 mr-2" />
<span>Read</span>
</div>
</DropdownMenuItem>
<DropdownMenuItem>
<div
onClick={() => setSelectedRead(false)}
className="flex items-center w-full"
>
<EyeOff className="w-4 h-4 mr-2" />
<span>Unread</span>
</div>
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
{table.getIsSomeRowsSelected() && (
<div className="flex space-x-2 items-end">
<Button variant="outline" className="ml-auto" onClick={() => setSelectedRead(true)}>
<Eye className="w-4 h-4" />
Mark selected read
</Button>
<Button variant="outline" className="ml-auto" onClick={() => setSelectedRead(false)}>
<EyeOff className="w-4 h-4" />
Mark selected unread
</Button>
</div>
</>
)}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just get rid of these buttons

)}
</div>

<div className="flex space-x-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="ml-auto">
<Settings2 className="w-4 h-4" />
View
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Columns</DropdownMenuLabel>
<DropdownMenuSeparator />
{table
.getAllColumns()
.filter((column) => column.getCanHide())
.map((column) => {
return (
<DropdownMenuCheckboxItem
key={column.id}
className="capitalize"
checked={column.getIsVisible()}
onCheckedChange={(value) => column.toggleVisibility(!!value)}
onSelect={(event) => event.preventDefault()}
>
{column.id}
</DropdownMenuCheckboxItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
{getNextUnreadChapter() && (
<Link to={`${routes.READER}/${props.series.id}/${getNextUnreadChapter()?.id}`}>
<Button variant="outline">
<Play className="w-4 h-4" />
Continue
</Button>
</Link>
)}
</div>
</div>
<div className="rounded-md border">
<Table>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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';
Expand Down Expand Up @@ -35,9 +35,14 @@ export function ChapterTableGroupFilter(props: Props) {
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" onContextMenu={() => setFilterGroupNames([])}>
<Filter />
<div
className="flex items-center justify-between px-2 py-1.5 mr-2 text-sm cursor-pointer relative w-full rounded-md transition-colors focus:outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground active:bg-accent/80"
onContextMenu={() => setFilterGroupNames([])}>
{'Group'}

{filterGroupNames.length <= 0 && (
<ChevronRight className="h-4" />
)}
{filterGroupNames.length > 0 && (
<>
<Separator orientation="vertical" className="mx-2 h-4" />
Expand All @@ -51,9 +56,9 @@ export function ChapterTableGroupFilter(props: Props) {
</div>
</>
)}
</Button>
</div>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0" align="start">
<PopoverContent className="w-[200px] p-0" align="start" side="right">
<Command>
<CommandInput placeholder={'Group'} />
<CommandList className="-mr-3">
Expand Down
Loading