{ await bookOps.markBooksAsComplete(selectionState.getSelectedIds()); selectionState.deselectAll(); }} class={buttonVariants({ variant: 'ghost', size: 'icon' })} >

Mark as finished

{#snippet child({ props })} Shelves {#each bookshelfState.getBookshelves(libraryState.activeLibrary!.id) ?? [] as shelf (shelf.id)} book.lists.findIndex((sh) => sh.id === shelf.id) !== -1 )} onclick={async () => { // Check if all books are in the shelf const allBooksInShelf = selectedBooks.every((book) => book.lists.find((sh) => sh.id === shelf.id) ); if (allBooksInShelf) { // Remove all books from the shelf const bookIds = selectedBooks.map((book) => book.id); await bookshelfState.removeBooksFromShelf(shelf.id, bookIds); selectedBooks.forEach((book) => { book.lists = book.lists.filter((sh) => sh.id !== shelf.id); }); } else { // Add all books to the shelf const bookIds = selectedBooks.map((book) => book.id); await bookshelfState.addBooksToShelf(shelf.id, bookIds); selectedBooks.forEach((book) => { if (!book.lists.find((sh) => sh.id === shelf.id)) { book.lists.push(shelf); } }); } selectionState.deselectAll(); }} > {shelf.title} {/each} (createShelfDialogOpen = true)} class="text-muted-foreground " > New Shelf {/snippet}

Add/Remove from shelf

{ bookOps.downloadBooks(selectionState.getSelectedIds()); }} class={buttonVariants({ variant: 'ghost', size: 'icon' })} >

Download selected

{#if selectedBooks.length > 1} (mergingBooks = selectedBooks)} class={buttonVariants({ variant: 'ghost', size: 'icon' })} >

Merge {selectedBooks.length} books

{/if} { bookOps.deleteDialogTitle = `Delete ${selectionState.getSelectedIds().length} books?`; bookOps.deleteFn = async (deleteFiles: boolean) => { await bookOps.deleteBooks(selectionState.getSelectedIds(), deleteFiles); libraryState.activeLibrary!.total! -= selectedBooks.length; bookshelfState.deletedBooks(selectedBooks); selectionState.deselectAll(); }; bookOps.deleteDialogOpen = true; }} class={buttonVariants({ variant: 'ghost', size: 'icon' })} >

Delete selected

{ selectionState.selectAll(collectionState.books); }} class={buttonVariants({ variant: 'ghost', size: 'icon' })} >

Select all

{ selectionState.deselectAll(); }} class={buttonVariants({ variant: 'ghost', size: 'icon' })} >

Deselect all

{ const bookshelf = await bookshelfState.addBookshelf( name, libraryState.activeLibrary!.id, selectionState.getSelectedIds() ); selectedBooks.forEach((book) => book.lists.push(bookshelf)); selectionState.deselectAll(); createShelfDialogOpen = false; }} /> {#if mergingBooks} {#key mergingBooks.map((book) => book.id).join()} { // Only the folded records are gone; the survivor is still in the library. libraryState.activeLibrary!.total! -= folded.length; bookshelfState.deletedBooks(folded); selectionState.deselectAll(); mergingBooks = null; }} /> {/key} {/if}