Skip to content

library: shelves + sections merge + Add-to-collection on details + author on saved#203

Merged
mrviduus merged 4 commits into
mainfrom
fix/library-shelves-and-collections
May 4, 2026
Merged

library: shelves + sections merge + Add-to-collection on details + author on saved#203
mrviduus merged 4 commits into
mainfrom
fix/library-shelves-and-collections

Conversation

@mrviduus
Copy link
Copy Markdown
Owner

@mrviduus mrviduus commented May 4, 2026

12 коммитов, все требования из обсуждения в одном PR.

What's inside

1. Shelves "View all →" — dedicated pages

  • /:lang/library/shelf/:shelfId route + LibraryShelfPage (cover/title/author/back-link/grid).
  • LibraryShelves hrefs указывают на dedicated route.

2. Library main: merged saved + uploads sections

  • Single search, single status-tabs (combined counts), single sort, single grid.
  • Combined merge-sort: saved + uploads интерливятся по chosen sort key. Processing/Failed uploads пинятся вверху via attention-rank.
  • Dropped useLibrarySearch('uploads') parallel instance and dead activeTab state.
  • useLibrarySearch tab arg удалён (orphan).

3. Add to collection

  • New AddToCollectionButton with menu | button variants. Menu replaces inline kebab item; button is pill + popover for hero actions.
  • Wired into BookDetailPage (when in library) and UserBookDetailPage (when Ready).
  • Esc + click-outside dismiss; success/error toast.
  • Per-book kebab "Add to collection" из ранних коммитов.

4. Detail page hero

  • Extracted BookDetailHero (cover + title + author + description + meta + actions slots) — used by classic detail page.
  • UserBookDetailPage возвращён к собственному оригинальному дизайну по запросу пользователя; Download EPUB убран.

5. Card visual alignment

  • library-card, user-book-card cover'ы получили тот же shadow что continue-shelf__card.
  • library-card placeholder color/weight выровнен с user-book-card.
  • title="" на title-link и author-span обоих card'ов для truncated-text tooltip.

6. Saved books — author field

  • Backend: LibraryItemDto.Author (joined string.Join, не FirstOrDefault — паритет с book detail).
  • AddToLibrary использует projection вместо Include().ThenInclude().
  • Frontend: type обновлён, combined sort/search использует author, author отображается на saved card'ах.

7. Collection filter — both types

  • Параллельно фетчит saved+upload book IDs для активной коллекции.
  • Filter применяется независимо к обоим спискам в unified-режиме.

8. Tests

  • Новый UserLibraryEndpointTests:
    • 401 без auth.
    • Schema: каждый item имеет Author field (regression guard для EF projection).
    • Stronger test: GET /books → POST /me/library → assert Author equals joined name list → GET /me/library → confirm → DELETE cleanup.
  • Assert.Skip(reason) вместо silent return для visible skip-семантики.

Test plan

  • /en/library — все shelf "View all" → dedicated page.
  • source='all' → один header (search/tabs/sort), combined sorted список.
  • Sidebar Catalog only → uploads + content-search скрыты; saved показаны.
  • Sidebar Uploads only → saved скрыты; FTS toggle виден; bulk-mode работает.
  • Sidebar collection select → filters apply both lists в unified-mode.
  • /en/books/{slug} (in library) → "Add to collection" → philosophy → toast.
  • /en/library/my/{id} (Ready) → same flow.
  • Saved cards показывают author под title.
  • Hover на truncated title → native tooltip с full text.
  • dotnet test tests/TextStack.IntegrationTests --filter UserLibraryEndpointTests — author-projection regression guard.
  • pnpm -C apps/web build — type check + bundle.

🤖 Generated with Claude Code

mrviduus and others added 2 commits May 4, 2026 13:31
- Shelves used wrong query keys (?filter=, ?sort=created_desc).
  Now: ?status=reading|finished|all + ?sort=added (matches existing hooks).
- LibraryPage consumes ?sort= once (sort hook is localStorage-backed).
- BookActionMenu: new "Add to collection" submenu in saved + userbook menus,
  reusing dead addBookToCollection() and useCollections(). Success/error toasts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#3 detail-page duplication:
  - new BookDetailHero (cover + title + author + description + meta + actions slots).
  - BookDetailPage and UserBookDetailPage both render it.
  - user-book-detail__* hero classes replaced by book-hero__* (mark/EPUB
    buttons → book-hero__read-btn--secondary).

#4 card visual drift:
  - library-card and user-book-card cover gain the same shadow as
    continue-shelf__card (0 4px 14px rgba(0,0,0,0.18)).
  - library-card placeholder color/weight aligned to user-book-card.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mrviduus mrviduus changed the title library: fix shelf View all + per-book Add to collection library: shelves + collections + detail-page hero + card polish May 4, 2026
mrviduus and others added 2 commits May 4, 2026 13:51
After hero extraction, large blocks of user-book-detail__* CSS have no
references in TS/TSX. Removed: __content/__cover/__info/__title/__author/
__description/__meta/__actions/__read-btn/__mark-btn/__delete-btn and the
mobile overrides + dark-mode rule for __read-btn. -55 lines, CSS bundle
-1.55 kB.

Delete button now uses new book-hero__read-btn--danger modifier (pill,
red text+border) so its shape matches the other hero buttons.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Processing/Failed banners were being rendered inside book-hero__actions
flex row after the hero refactor, which would distort the row. They are
page-level alerts — moved above the hero.

The "Read" badge moves into the meta slot as an inline-flex span so it
sits next to chapters/pages instead of standing alone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mrviduus mrviduus merged commit 40d2e3d into main May 4, 2026
4 of 5 checks passed
@mrviduus mrviduus changed the title library: shelves + collections + detail-page hero + card polish library: shelf pages + merged sections + Add-to-collection on details May 4, 2026
@mrviduus mrviduus changed the title library: shelf pages + merged sections + Add-to-collection on details library: shelves + sections merge + Add-to-collection on details + author on saved May 5, 2026
mrviduus added a commit that referenced this pull request May 5, 2026
…n + author + EPUB removal) (#204)

PR #203 squash-merge picked up only first 4 of 12 commits. This PR adds the remaining 8.

- /:lang/library/shelf/:shelfId — new dedicated page (LibraryShelfPage) for shelf "View all"
- /library merged saved+uploads sections (single search/tabs/sort/grid, combined merge-sort)
- AddToCollectionButton (menu/button variants) on kebab + BookDetailPage + UserBookDetailPage
- UserBookDetailPage reverted to original layout, Download EPUB removed
- Card cover shadow + placeholder + title="" parity across all card variants
- Backend LibraryItemDto.Author (joined names, memory-projection); AddToLibrary uses projection
- Frontend LibraryItem.author wired into combined sort/search + rendered on saved cards
- Collection sidebar filter applies to both savedbook + userbook in unified mode
- useLibrarySearch tab arg removed (orphan); activeTab state removed
- New UserLibraryEndpointTests with schema + fixture-based author regression guards
mrviduus added a commit that referenced this pull request May 5, 2026
…tons) (#208)

Mobile had zero collections UI. Web has had them since PR #203.

shared:
- new packages/shared/src/api/collections.ts with list/create/update/delete/
  addBookToCollection/removeBookFromCollection/getCollectionBookIds, exposed
  via collectionsApi + Collection / CollectionBookType types.
- en.json gains library.actions.addToCollection*, library.collections.*
  strings (mirroring web).

mobile:
- useCollections hook (cache 60s + subs + refresh + create/update/remove),
  ported from the web version.
- new AddToCollectionSheet (bottom-sheet modal): list of collections, "+ New
  collection" inline create flow, success/error feedback, native UX rather
  than the web popover.
- useBookActions: showSavedActions / showUploadActions now accept an
  optional onAddToCollection callback that, when provided, prepends an
  "Add to collection" entry to the action sheet.
- (tabs)/library.tsx: SavedList and UploadsList host their own sheet
  instances, wire onAddToCollection in handleAction, toast on success.
- app/book/[slug].tsx: "Add to collection" button in the secondary actions
  row, only when the book is in the library (web parity).
- app/my-books/[id].tsx: "Add to collection" button alongside Mark as
  read / Download EPUB / Share for ready uploads.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mrviduus added a commit that referenced this pull request May 5, 2026
…con + CHANGELOG (#221)

User audit on the icon "+" affordance:
- Hover state was just a faint border colour change — no signal what the
  button does until you click it.
- "Add to collection" popover only listed existing collections; creating
  a new one meant closing it, walking back to the sidebar, typing the
  name, then re-opening to assign. Five clicks for a one-step intent.
- Big "Delete Book" outline-pill in the danger zone (after #220) was
  better than the primary-row pill but still louder than the circular
  "+" sitting nearby — visual hierarchy mismatch.

Fixes:

- Custom CSS tooltip on icon buttons (.add-to-collection-button--icon
  and .user-book-detail__delete-icon) reads aria-label, shows after a
  250ms hover delay (instant feel without flickering), styled to match
  the dark/light theme. Skips the 1–2s native title delay entirely.
- Popover gains an inline "+ New collection" row that swaps to a small
  text input + Add button on click, creates the collection AND adds
  the current book in one round-trip, then closes. Apple Notes pattern.
- Delete is now a circular trash icon (lucide-style svg, hand-rolled to
  avoid pulling another dependency) sized 36×36 to match the "+" icon
  on the page. Same custom tooltip ("Delete this book"). Same red
  accent. Confirm dialog stays.

CHANGELOG.md updated for everything since 2026-04-26 (PR #203 onward —
17 PRs of library + mobile + cleanup work that was missing entries).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant