From b7df294d7890111e05020db361f17fe0fa103f68 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Mon, 15 Dec 2025 12:02:52 +0800 Subject: [PATCH] feat(bookshelf): add group books button in context menu, closes #2698 (#2718) --- .../src/app/library/components/Bookshelf.tsx | 1 + .../app/library/components/BookshelfItem.tsx | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/apps/readest-app/src/app/library/components/Bookshelf.tsx b/apps/readest-app/src/app/library/components/Bookshelf.tsx index e7213ef7..606219dd 100644 --- a/apps/readest-app/src/app/library/components/Bookshelf.tsx +++ b/apps/readest-app/src/app/library/components/Bookshelf.tsx @@ -304,6 +304,7 @@ const Bookshelf: React.FC = ({ } setLoading={setLoading} toggleSelection={toggleSelection} + handleGroupBooks={groupSelectedBooks} handleBookUpload={handleBookUpload} handleBookDownload={handleBookDownload} handleBookDelete={handleBookDelete} diff --git a/apps/readest-app/src/app/library/components/BookshelfItem.tsx b/apps/readest-app/src/app/library/components/BookshelfItem.tsx index 854e6f70..a1bfadc2 100644 --- a/apps/readest-app/src/app/library/components/BookshelfItem.tsx +++ b/apps/readest-app/src/app/library/components/BookshelfItem.tsx @@ -81,6 +81,7 @@ interface BookshelfItemProps { transferProgress: number | null; setLoading: React.Dispatch>; toggleSelection: (hash: string) => void; + handleGroupBooks: () => void; handleBookDownload: (book: Book) => Promise; handleBookUpload: (book: Book, syncBooks?: boolean) => Promise; handleBookDelete: (book: Book, syncBooks?: boolean) => Promise; @@ -97,6 +98,7 @@ const BookshelfItem: React.FC = ({ transferProgress, setLoading, toggleSelection, + handleGroupBooks, handleBookUpload, handleBookDownload, handleSetSelectMode, @@ -188,6 +190,16 @@ const BookshelfItem: React.FC = ({ toggleSelection(book.hash); }, }); + const groupBooksMenuItem = await MenuItem.new({ + text: _('Group Books'), + action: async () => { + if (!isSelectMode) handleSetSelectMode(true); + if (!itemSelected) { + toggleSelection(book.hash); + } + handleGroupBooks(); + }, + }); const showBookInFinderMenuItem = await MenuItem.new({ text: _(fileRevealLabel), action: async () => { @@ -221,6 +233,7 @@ const BookshelfItem: React.FC = ({ }); const menu = await Menu.new(); menu.append(selectBookMenuItem); + menu.append(groupBooksMenuItem); menu.append(showBookDetailsMenuItem); menu.append(showBookInFinderMenuItem); if (book.uploadedAt && !book.downloadedAt) { @@ -242,6 +255,16 @@ const BookshelfItem: React.FC = ({ toggleSelection(group.id); }, }); + const groupBooksMenuItem = await MenuItem.new({ + text: _('Group Books'), + action: async () => { + if (!isSelectMode) handleSetSelectMode(true); + if (!itemSelected) { + toggleSelection(group.id); + } + handleGroupBooks(); + }, + }); const deleteGroupMenuItem = await MenuItem.new({ text: _('Delete'), action: async () => { @@ -250,6 +273,7 @@ const BookshelfItem: React.FC = ({ }); const menu = await Menu.new(); menu.append(selectGroupMenuItem); + menu.append(groupBooksMenuItem); menu.append(deleteGroupMenuItem); menu.popup(); };