Skip to content

Add library filter, sync, and export enhancements#25

Open
kvmgithub wants to merge 1 commit into
Promises:mainfrom
kvmgithub:feat/upstream-23-library-enhancements
Open

Add library filter, sync, and export enhancements#25
kvmgithub wants to merge 1 commit into
Promises:mainfrom
kvmgithub:feat/upstream-23-library-enhancements

Conversation

@kvmgithub

Copy link
Copy Markdown
Contributor

Context

This PR implements the feature requests from #23 except the additional
provider integrations (Libro.fm, Downpour, Chirp), which are a separate
effort. Along the way it fixes the two bugs behind the filter symptoms
described in the issue: selecting a series after clearing filters showed
zero results, and the genre category was always empty.

Fixes #23

What changed

Filter fixes

  • Series filter returned 0 results: the list query's series clause
    referenced a CTE that was never joined in that query, so any series
    selection made the whole query fail. The series/category/account
    clauses are now built by one shared helper used by both the list and
    count queries, and series matching uses an EXISTS over all of a book's
    series instead of only the first one.
  • Genre was never populated: library sync parsed category_ladders
    from the API but never persisted them. Sync now stores each ladder as a
    JSON array of category names in CategoryLadders and links it via
    BookCategories; the genre list is read back with json_each. Genres
    appear after the next library sync.

Filter UI

  • Accounts, genres, and series are multi-select; a book matching any
    selected value is shown.
  • Genre moved above series.
  • Sections with more than 10 options collapse behind a "Show all (N)"
    row; selected options stay visible while collapsed.
  • New Type section (All / Audiobooks / Podcasts).

Multi-account sync

The account screen gains "Sync All Accounts" (shown when more than one
account exists), which syncs every account sequentially with one summary
at the end. Token refresh per account is preserved.

Book details

Tapping a library title opens a detail card with authors, narrators,
series, duration, release date, owning account, and the summary. Long
summaries collapse to 8 lines with Show more/less (shown only when the
text actually exceeds that). Podcast parents open the same card with a
"View Episodes" button, so the episode list is one tap further.

Two data fixes back this up:

  • Sync now prefers publisher_summary (full text) over
    merchandising_summary (a teaser truncated with an ellipsis), and
    update_book now updates the stored description at all — previously
    descriptions were written once at insert and never refreshed.
  • Descriptions render their original <p>/<br> structure as paragraph
    breaks instead of being flattened to one line.

Account badges

When more than one account exists, library cards show a badge with the
owning account's name next to the existing LibriVox badge.

Database export/import

Settings > Database gains Export (a consistent single-file snapshot via
VACUUM INTO, saved through the system directory picker) and Import
(SQLite-header-validated file replaces the current database after a
confirmation).

Goodreads/StoryGraph export

The library export offers a "Goodreads" format: a CSV in Goodreads import
layout (Title, Author, Binding=Audiobook, Year Published, Date Added,
Owned Copies), which StoryGraph's Goodreads importer also accepts.
Audiobooks carry no ISBN, so both services match by title/author.

User-visible behavior

  1. Selecting a series shows its books (previously 0 results).
  2. Genre filter has options after the next sync.
  3. Multiple accounts/genres/series can be selected at once.
  4. Long filter lists collapse; Type filter separates podcasts from books.
  5. "Sync All Accounts" syncs every account in one run.
  6. Tapping a title shows its summary card; podcast parents show it too.
  7. Cards show the owning account when several accounts exist.
  8. The database can be exported and re-imported from Settings.
  9. Library export can produce a Goodreads/StoryGraph-compatible CSV.

Review focus

  • The shared WHERE builder in queries.rs and the new
    test_list_books_with_filters_by_series_and_category covering the
    series bug, multi-select, and the json_each genre list.
  • Category ladder persistence in library.rs (link_categories).
  • The multi-select plumbing through the Kotlin extras JSON into
    jni_bridge.rs (legacy single-value fields still accepted).
  • VACUUM INTO export and the import's header check in
    SettingsScreen.tsx.

Validation

  • npm run typecheck
  • cargo test -p rust-core (lib + integration suites, all green)
  • Android debug build installed; verified manually on device: sync, genre
    filter populated, series selection returns hits, multi-select, detail
    card with Show more/less, podcast parent card + episodes, type filter,
    database export/import, Goodreads CSV import layout

Filters support selecting multiple accounts, series, and genres; long
option lists collapse behind a Show all row and genres sit above series.
Selecting a series no longer returns zero results: the list query
referenced a series CTE it never joined, so the filter always errored.
Genres were never populated because synced category ladders were not
persisted; sync now stores them as JSON name arrays and the genre list
reads them via json_each.

The account screen can sync all accounts in one run, tapping a library
title shows its summary with narrators and owning account, cards show
account badges when several accounts exist, the database can be exported
and imported as a SQLite file, and library exports offer a Goodreads/
StoryGraph compatible CSV.

Refs Promises#23
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.

Random features

1 participant