Plainshelf v0.7.0
Added
- Added shelf creation and deletion confirmation modals to the frontend shelf management UI.
- Added
scan_intervalconfiguration support when creating shelves through the settings UI. - Added
book_check_intervalshelf configuration option to rate-limit per-book staleness checks, reducing filesystem and network I/O on SMB mounts. - Added
GET /api/shelves/:id/statusendpoint returning shelf readiness and initialization error state. - Added ETag and
Cache-ControlHTTP caching headers for book cover responses. - Added async shelf cache initialization; list endpoints return 503 with
Retry-Afteruntil the cache is ready. - Added frontend 503 auto-retry with "Shelf is loading…" status during shelf initialization, capped at 10 attempts with a manual retry button on failure.
- Added frontend
AbortControllerrequest timeout on all API fetch calls with distinct timeout error handling. - Added a shelf modify modal in desktop Settings for editing a shelf's name and scan interval.
- Added resizable sidebar and source-list panels (previously fixed-width) via drag handles.
- Added a Homebrew cask for installing the macOS desktop app (
brew install --cask voilelab/plainshelf/plainshelf). - Added a GitHub Actions release workflow publishing prebuilt server binaries (Linux amd64/arm64, macOS arm64) and a Docker image on tagged releases.
- Added application version reporting via
GET /api/version, startup logs, and a Settings page About section, using build-time version injection. - Added native fullscreen mode support for the macOS desktop app.
Changed
- Hardened SMB mount support: configurable flock timeout (default 30 s), atomic writes for source and metadata files, and initialization failures now exposed via
/statusinstead of hanging indefinitely. - Made per-book stat checks asynchronous to reduce round-trips on SMB mounts; list operations serve from the in-memory cache between scheduled checks.
- Changed the Settings page from stacked panels to a tabbed layout (cover, read history, about, shelves).
- Changed native
<select>inputs and hand-rolled dropdown menus throughout the app to a consistent reka-ui-based menu with shared styling and full keyboard navigation. - Changed the layer tree to reka-ui Tree, adding keyboard navigation (arrow keys, Home/End, typeahead) and proper ARIA tree semantics.
- Changed the book tag input so Backspace on an empty field selects the last tag chip before deleting it on a second press (previously deleted immediately), and chips can now be selected with arrow keys.
- Changed reader side-action buttons to show styled hover tooltips instead of native browser title tooltips.
Fixed
- Fixed cache write lock held across filesystem I/O in book cache refresh, blocking concurrent list reads.
- Fixed shelf lock acquisition errors not being propagated to callers.
- Fixed two data races in shelf book-cache scan-interval handling and shelf listing that could corrupt state under concurrent access.
- Fixed source ID collisions when multiple sources for the same book are created within the same second.
- Fixed layer/book path parsing to always split on
/instead of the OS path separator, which broke on Windows. - Fixed shelf startup to clear leftover temp files from a previous crashed run, and to skip unreadable/non-directory source entries instead of failing the whole listing.
- Fixed the desktop app crashing when the backend fails to start (e.g. data directory not creatable, port in use); it now shows an error dialog instead of panicking.
What's Changed
- Add shelf initialization handling and SMB mount optimizations by @mudream4869 in #157
- Improve file write safety and shelf initialization error handling by @mudream4869 in #158
- Add shelf creation modal by @mudream4869 in #161
- Add shelf delete confirmation modal by @mudream4869 in #162
- Support scan_interval when creating shelves by @mudream4869 in #163
- Decouple book staleness checks from full cache scans by @mudream4869 in #164
- Add SMB shelf configuration guide and navigation entry by @mudream4869 in #167
- Add shelf modification functionality to desktop app by @mudream4869 in #166
- Refactor file locking to support multiple lock modes by @mudream4869 in #168
- Refactor Shelf methods and update locking mechanism by @mudream4869 in #169
- Handle backend startup errors gracefully with user dialog by @mudream4869 in #170
- Fix source and book ID collisions and improve robustness by @mudream4869 in #171
- Add release pipeline, version injection, and installation docs by @mudream4869 in #172
- Simplify development workflow with just task runner by @mudream4869 in #173
- Update documentation to reflect planned format support by @mudream4869 in #175
- Enable fullscreen mode on macOS by @mudream4869 in #176
- Add Claude session governance framework and rules by @mudream4869 in #177
- Extract dialog logic into reusable BaseDialog component by @mudream4869 in #178
- Extract modal UI into reusable BaseDialog component by @mudream4869 in #179
- Refactor modals to use BaseDialog component by @mudream4869 in #180
- Refactor ImportBookModal to use BaseDialog component by @mudream4869 in #181
- Refactor ConfirmModal to use BaseDialog component by @mudream4869 in #182
- Replace custom dropdown with reka-ui DropdownMenu by @mudream4869 in #183
- Update go dependency by @mudream4869 in #184
- Add comprehensive e2e tests for layer tree UI interactions by @mudream4869 in #185
- Refactor LayerTree to use reka-ui TreeRoot/TreeItem components by @mudream4869 in #186
- Replace custom tag input with reka-ui TagsInput component by @mudream4869 in #187
- Migrate UI components to reka-ui for consistent design system by @mudream4869 in #188
- Add macOS desktop app distribution via Homebrew cask by @mudream4869 in #174
- Release v0.7.0 by @mudream4869 in #189
Full Changelog: v0.6.0...v0.7.0