v0.4.0
[0.4.0] — 2026-06-10
First PyPI release as bookreader-tui. Bundles every change from
the post-0.3.0 cleanup waves plus the Phase 4 / 5.0 polish work.
Added
- Phase 4 — Library curation.
Copens a Collections overview
(every book grouped by collection);Wopens a Wishlist overview
with in-place removal viad. - Reader-side library actions.
ctoggles completion,CandW
push the collection / wishlist overviews from inside the reader —
no more "quit to library first" round-trip. - Inline images in two-page mode.
PagedViewwas rewritten from
Static-render to widget-mount: each spread isHorizontal[Vertical, Vertical]with mountedStatic+Imagewidgets per page. Images
render at natural EPUB size withwidth: auto; max-width: 100%. - Auto-enable inline images in graphics-capable terminals
(xterm-kitty, iTerm2, WezTerm). ExplicitBOOKREADER_IMAGES_ENABLED
still wins. NewIkey toggles at runtime. - Configurable reading width.
BOOKREADER_READING_WIDTH(60–200)
overrides the column max. Default raised 84 → 110. - Library UX polish. Empty-state hints when a filter has 0 books;
filter-aware status strip (showing 0 of 1 · filter: Want to Read);
sidebar + table get accent-coloured focus borders; book table has
explicit column widths. - RepositoryError at the SQLite boundary so UI code can route
through the centralBookReaderErrorhandler. - Lowercase
whint on the library — instead of silently doing
nothing, surfaces "Press Shift+W to open the wishlist". - Dark theme contrast — Tokyo-Night-adjacent palette replaces the
muted Catppuccin Mocha values (brighter foreground, punchier accent). Ctrl+Ptheme picker scoped to bookreader-* — the 20+ Textual
built-in themes no longer pollute the picker.- CI on every push / PR — ruff format + check, mypy --strict,
pytest across Python 3.11 and 3.12.
Fixed
- Bare
except Exceptionin UI handlers replaced with
except BookReaderError; programming bugs (KeyError, AttributeError)
no longer get silently rendered as "Add failed" notifications. qtyped inside a modalInputcan no longer quit the app
(verified with a pilot regression test).Ttheme cycle now snaps back to the bookreader theme set after the
user picks a Textual built-in via the palette.- Inline
Imagewidget no longer eats all vertical space — explicit
height: autokeeps the text below the figure visible. PagedViewre-renders use class selectors instead of static IDs;
the asyncremove_children()race no longer raisesDuplicateIds
on resize / chapter jump (regression test added).
Changed
- Versioning:
__version__andpyproject.tomlbumped 0.1.0 → 0.4.0
(matches the actual shipped surface — Phase 4 was onmainlong
before the version field caught up). - PyPI package name:
bookreader-tui(the barebookreadername was
already taken). The Python import path is stillbookreader. - License declaration in
pyproject.tomlcorrected fromMITto
Apache-2.0to match the actual LICENSE file.