Commit Graph

1664 Commits

Author SHA1 Message Date
ACX
37ea0b156f feat(google-books): add optional API key configuration (#2629) 2026-02-05 22:37:12 -07:00
ACX
e0c3d8b50d feat(sorting): add multi-field sorting support (#2628) 2026-02-05 22:22:50 -07:00
ACX
f34b18f2b8 fix(book-browser): resolve footer menu not hiding after navigation back (#2626) 2026-02-05 21:22:04 -07:00
ACX
f71966a9b6 feat(filters): add customizable visible filters setting (#2625) 2026-02-05 20:59:07 -07:00
ACX
555cd13f8a fix(auth): resolve DST-related login failure for refresh tokens (#2624) 2026-02-05 20:16:27 -07:00
ACX
9f9c762180 feat(content-restrictions): add age rating and content rating support (#2619) 2026-02-05 17:10:44 -07:00
ACX
89b4319970 feat(filters): implement cascading sidebar filters (#2616) 2026-02-05 15:50:18 -07:00
Balázs Szücs
c7dd23ed85 fix(file-move): implement transaction management for file moves and rollback on failure (#2588)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-02-05 14:01:34 -07:00
xcashy
539734a3cf feat(kobo-sync): Sync Shelves and Magic Shelves to Kobo Tags (#2236)
* feat(kobo-sync): sync shelves and magic shelves to kobo tags

* refactor(kobo-sync): replace `EntityNotFoundException` with `NoSuchElementException`, update timestamps handling, and add unit tests for `generateTags`

---------

Co-authored-by: ACX <8075870+acx10@users.noreply.github.com>
2026-02-05 13:59:08 -07:00
dependabot[bot]
6e43b01e76 chore(deps): bump actions/setup-node from 4 to 6 (#2573)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-05 13:58:04 -07:00
dependabot[bot]
175c58180a chore(deps): bump the npm-dependencies group (#2542)
Bumps the npm-dependencies group in /booklore-ui with 20 updates:

| Package | From | To |
| --- | --- | --- |
| [@angular/animations](https://github.com/angular/angular/tree/HEAD/packages/animations) | `21.1.1` | `21.1.2` |
| [@angular/cdk](https://github.com/angular/components) | `21.1.1` | `21.1.2` |
| [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `21.1.1` | `21.1.2` |
| [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `21.1.1` | `21.1.2` |
| [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `21.1.1` | `21.1.2` |
| [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `21.1.1` | `21.1.2` |
| [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `21.1.1` | `21.1.2` |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) | `21.1.1` | `21.1.2` |
| [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `21.1.1` | `21.1.2` |
| [@angular/service-worker](https://github.com/angular/angular/tree/HEAD/packages/service-worker) | `21.1.1` | `21.1.2` |
| [primeng](https://github.com/primefaces/primeng/tree/HEAD/packages/primeng) | `21.0.4` | `21.1.1` |
| [@analogjs/vite-plugin-angular](https://github.com/analogjs/analog) | `2.2.2` | `2.2.3` |
| [@analogjs/vitest-angular](https://github.com/analogjs/analog) | `2.2.2` | `2.2.3` |
| [@angular/build](https://github.com/angular/angular-cli) | `21.1.1` | `21.1.2` |
| [@angular/cli](https://github.com/angular/angular-cli) | `21.1.1` | `21.1.2` |
| [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `21.1.1` | `21.1.2` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.0.10` | `25.1.0` |
| [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid) | `10.0.0` | `11.0.0` |
| [angular-eslint](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/angular-eslint) | `21.1.0` | `21.2.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.53.1` | `8.54.0` |


Updates `@angular/animations` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/animations)

Updates `@angular/cdk` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/components/releases)
- [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/components/compare/v21.1.1...v21.1.2)

Updates `@angular/common` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/common)

Updates `@angular/compiler` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/compiler)

Updates `@angular/core` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/core)

Updates `@angular/forms` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/forms)

Updates `@angular/platform-browser` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/platform-browser)

Updates `@angular/platform-browser-dynamic` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/platform-browser-dynamic)

Updates `@angular/router` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/router)

Updates `@angular/service-worker` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/service-worker)

Updates `primeng` from 21.0.4 to 21.1.1
- [Release notes](https://github.com/primefaces/primeng/releases)
- [Changelog](https://github.com/primefaces/primeng/blob/master/CHANGELOG.md)
- [Commits](https://github.com/primefaces/primeng/commits/21.1.1/packages/primeng)

Updates `@analogjs/vite-plugin-angular` from 2.2.2 to 2.2.3
- [Release notes](https://github.com/analogjs/analog/releases)
- [Changelog](https://github.com/analogjs/analog/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/analogjs/analog/compare/v2.2.2...v2.2.3)

Updates `@analogjs/vitest-angular` from 2.2.2 to 2.2.3
- [Release notes](https://github.com/analogjs/analog/releases)
- [Changelog](https://github.com/analogjs/analog/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/analogjs/analog/compare/v2.2.2...v2.2.3)

Updates `@angular/build` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/v21.1.1...v21.1.2)

Updates `@angular/cli` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/v21.1.1...v21.1.2)

Updates `@angular/compiler-cli` from 21.1.1 to 21.1.2
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.1.2/packages/compiler-cli)

Updates `@types/node` from 25.0.10 to 25.1.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/uuid` from 10.0.0 to 11.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid)

Updates `angular-eslint` from 21.1.0 to 21.2.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/angular-eslint/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v21.2.0/packages/angular-eslint)

Updates `typescript-eslint` from 8.53.1 to 8.54.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.54.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@angular/animations"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/cdk"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/common"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/compiler"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/core"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/forms"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/platform-browser"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/platform-browser-dynamic"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/router"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/service-worker"
  dependency-version: 21.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: primeng
  dependency-version: 21.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: "@analogjs/vite-plugin-angular"
  dependency-version: 2.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@analogjs/vitest-angular"
  dependency-version: 2.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/build"
  dependency-version: 21.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/cli"
  dependency-version: 21.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@angular/compiler-cli"
  dependency-version: 21.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@types/node"
  dependency-version: 25.1.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: "@types/uuid"
  dependency-version: 11.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: angular-eslint
  dependency-version: 21.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: typescript-eslint
  dependency-version: 8.54.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-05 13:57:22 -07:00
ACX
d38271de9c Audiobook enhancement (#2611)
* Audiobook enhancement

* Fix choppy virtual scroller with mixed audiobook/ebook cards by using uniform heights

* Fix audiobook cover regeneration for combined books and improve error messages

* Fix cover extraction when attaching audiobook files during rescan

* Set audiobookCoverUpdatedOn for cache busting when generating cover

* Add support for regenerating covers from specific book files

* Fix Continue Reading/Listening scrollers to filter by actual progress instead of primary file type

* Show ebook cover and open ebook reader in Continue Reading scroller for combined books

* Prevent read status from being downgraded when saving audiobook progress

* Fix BookCoverServiceTest to match updated regenerateCover method signature
---------

Co-authored-by: acx10 <acx10@users.noreply.github.com>
2026-02-05 13:33:08 -07:00
Balázs Szücs
92d1334f25 Refactor confirmation dialogs to standardize button labels and styles across components (#2562)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-02-02 10:38:31 -07:00
Ben Szabo
a77cecdf21 feat(kobo-sync): add user scoped 2 way kobo sync (#2452)
* fix(kobo-sync): Kobo reading state sync by returning the device expected shape and improve management with new DTOs and timestamp normalization

- Introduced `KoboReadingStateList` and `KoboReadingStateRequest` DTOs for improved handling of reading states.
- Updated `KoboController` to utilize the new DTOs and log request bodies.
- Enhanced `KoboReadingStateService` to normalize timestamps during reading state updates and merges.
- Adjusted repository queries to include user ID for better data integrity.
- Updated tests to reflect changes in DTOs and repository interactions.

* feat(kobo-sync): Enhance Kobo reading state management with user ID integration

* feat(kobo-sync): Add JSON annotations to KoboReadingStateList for improved serialization

* refactor(kobo-sync): Update repository and service methods to enhance reading state retrieval logic

- Replaced the existing method for fetching reading states with a new query that orders results by priority and timestamps.
- Updated service classes to utilize the new repository method for improved data handling.
- Adjusted unit tests to reflect changes in repository interactions.

* Enhance KoboReadingStateService and add database migration for user_id

- Added a new column `user_id` to the `kobo_reading_state` table with a foreign key constraint referencing the `users` table.
- Updated the `KoboReadingStateService` class by adding a new method to check for blank values, improving code readability and maintainability.
2026-02-02 10:27:58 -07:00
Balázs Szücs
cb5f703c7e fix(epub-cover-extract): improve cover image extraction with fallback handling (#2585)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-02-02 10:26:49 -07:00
chiguirepower
2cbb0c80a2 Add sort by filePath (#1180 and #2364) (#2512)
Co-authored-by: Eduardo <eo@wavecode.com>
2026-02-02 10:25:57 -07:00
acx10
6a36d7823d chore(readme): add JetBrains logo for open source collaboration 2026-02-02 09:24:01 -07:00
acx10
91c0382527 refactor: rename package to org.booklore 2026-02-02 00:02:12 -07:00
acx10
17fef505cb Fix ebook reader text selection and audiobook reader 2026-02-01 23:49:20 -07:00
acx10
a402f98e08 Merge branch 'experimental/fix-adb' into develop
* experimental/fix-adb:
  Fix audiobook player
2026-01-31 15:56:27 -07:00
acx10
b6057588f6 Fix audiobook player 2026-01-31 15:55:42 -07:00
Balázs Szücs
a27c9d57fb Fix: handle file modifications in Bookdrop event handler (#2559)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-31 14:49:58 -07:00
Balázs Szücs
3b460134fe Refactor series page footer: rename .footer-inner to .footer-content and update responsive styles (#2555)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-31 14:47:39 -07:00
Balázs Szücs
8264639bbc Refactor confirmation dialogs to standardize button labels and styles across components (#2560)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-31 14:45:11 -07:00
Sebastian Hewelt
0a7b67b829 fix(ui): correctly format lubimyczytac external rating link (#2491)
Appends the required '/ksiazka' suffix to the Lubimyczytac URL and ensures
the href is an empty string if the ID is missing to prevent malformed links.
2026-01-31 14:44:32 -07:00
acx10
830bb5e9de Refactor sidebar filter 2026-01-30 13:00:58 -07:00
ACX
2310681c66 Fix sidebar filter text truncation (#2541)
* ...

* Fix sidebar filter text truncation

---------

Co-authored-by: acx10 <acx10@users.noreply.github.com>
2026-01-29 19:46:07 -07:00
ACX
20a65d7214 Fix: Filter text overwrites on long options (#2540)
Co-authored-by: acx10 <acx10@users.noreply.github.com>
2026-01-29 19:34:35 -07:00
ACX
bda07e1877 Fix: Lock icons do not stay with publisher and series name input fields (#2539)
Co-authored-by: acx10 <acx10@users.noreply.github.com>
2026-01-29 19:06:25 -07:00
acx10
b215dbb692 Fix tests 2026-01-29 18:18:37 -07:00
Balázs Szücs
3a4de95c8c fix(metadata-update): ensure per-book transaction isolation in bulk updates to prevent race conditions (#2536)
Refactor bulkUpdateMetadata to process each book update in its own transaction using PROPAGATION_REQUIRES_NEW, improving concurrency safety. Add BookMetadataServiceConcurrencyTest to verify correct fetching strategy and transactional behavior.

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-29 18:00:27 -07:00
Jadehawk
5ad66daae6 feat(metadata) Save basic metadata to EPUB file - Bonus use Calibre Custom Columns for importing metadata. (#1879)
* feat: Add comprehensive Calibre metadata extraction system - Implemented configurable field mapping system for Calibre user_metadata - Added support for series_total custom column extraction - Pre-built mappings for ALL BookMetadata fields (20+ fields) - Added support for Set fields (tags, moods, categories, authors) - Lowercase field names with underscores (Calibre requirement) - Multiple ISBN support (ISBN-10 and ISBN-13 simultaneously) - ISBN hyphen handling (strips hyphens before validation) - Type-safe parsing (String, Integer, Float, Double, Set) - Professional logging with IDENTIFIER prefix - Added CALIBRE_FIELD_MAPPING_REFERENCE.txt documentation - Updated .gitignore and created .dockerignore for test files

* Updated gitignore

* Delete CALIBRE_FIELD_MAPPING_REFERENCE.txt

* Remove unnecessary files: example.epub and og_metadata.java

* Refactor EpubMetadataExtractor to address PR review feedback

- Eliminate DRY violations in identifier extraction with helper methods
- Fix Build-to-Check anti-pattern using processedFields tracking
- Move regex patterns to static constants to avoid recompilation
- Replace magic numbers with calculated prefix lengths
- Consolidate repetitive Set field and pagecount parsing patterns
- Remove excessive documentation and comments
- Remove unrelated .dockerignore and .gitignore entries

* chore: trigger CI/CD pipeline

* Add @Singular annotation to collection fields to support builder accumulation

* Update identifiers to URN format for Calibre compatibility

* fix: resolve MetadataChangeDetectorTest failures and enhance Calibre EPUB integration

- Fixed NullPointerException in testEdgeCase_emptyCollectionToNull_returnsTrue()

- Fixed NullPointerException in testHasValueChanges_whenEmptySetToNull_returnsTrue()

Implementing @Singular for moods and tags prevents metadata fields from being null,

which then fails edge test cases. Since we are no longer double looping during

metadata extraction, @Singular is not needed. Removing it allows the edge case

tests (by Balázs Szücs) to pass.

- Removed douban fields from persistence layer (kept in DTO for DoubanBookParser)

I was under the impression we were saving this value to the DB, but as far as I

can find, we only use Douban data for searching. Adding to the identifiers section

would raise issues with the database not having where to store that value.

Database modifications are left to the professionals.

- Added support for all identifier formats (URN and simple prefix)

Calibre only detects identifiers during IMPORT if they are in URN format.

However, it saves them back as simple prefix. Booklore now handles both.

- Added removeAllCalibreMetadata() to strip all Calibre traces

Cleans up saved EPUBs in Booklore's library, removing all Calibre metadata traces.

- Ensures clean EPUB 3 compliant output with only booklore:* tags

ALL metadata is now saved by Booklore into EPUBs using booklore:* tags.

This preserves Booklore's metadata and we can read it back during import.

Calibre support is ONLY during IMPORT, as it should be since this is the

Booklore project.

(If Calibre users want to extract Booklore metadata, they can build a Calibre

plugin to extract booklore:* tags.)

No longer use #genres or #categories. We stick to dc:subject as suggested,

and Booklore tags can be read from Calibre custom column #extra_tags.

We store tags as booklore:tags.

Removed all tests that used #genres/#categories.

Added tests to check booklore:* tags extraction.

* fix: Remove DoubanId copy helper call - upstream MetadataClearFlags missing isDoubanId()

* Fix Calibre moods and tags extraction from EPUB metadata

- Add fallback logic to check alternative key names (value, #val#) if #value# is missing

- Maintain compatibility with upstream metadata structure changes

* fix: resolve rebase conflicts and compilation errors - Fixed missing closing brace in MetadataRefreshService.java - Added MoodRepository and TagRepository to BookCreatorService - Added addMoodsToBook() and addTagsToBook() methods - Fixed EpubProcessor to use new methods

* Restore Booklore's metadata persistance, Logic Lost during Rebase + Added support for Lubimyczytac and ranobedb

Fixed lubimyczytac metadata not saving during EPUB bookdrop imports.

Root cause: The Angular bookdrop form was missing lubimyczytacId and lubimyczytacRating fields, preventing these values from being sent to the backend during finalization.

Backend fixes:

- EpubMetadataExtractor: Fixed method references with explicit lambdas for lubimyczytac field setters (ranobedb also updated preventively)

- BookMetadataUpdater: Fixed method references with explicit lambdas for lubimyczytac field updates (ranobedb also updated preventively)

Frontend fix:

- bookdrop-file-review.component.ts: Added lubimyczytacId and lubimyczytacRating form fields to createMetadataForm() and resetMetadata() methods

This ensures lubimyczytac metadata extracted from EPUB booklore:tags flows correctly through: extraction → database → UI form → backend → final book record.

* Restore Original ONLY Calibre custom column name to #pagecount So as not to break other users flow.

* fix: resolve compilation error in EpubProcessor.java - Changed bookEntity.getFileName() to bookEntity.getPrimaryBookFile().getFileName() to fix gradlew build check

* Add EPUB 3 compliant prefix declaration for custom booklore metadata

Declares the booklore: prefix in the package element's prefix attribute according to EPUB 3 specification for custom vocabularies.

* Move hardcoverBookId to standard URN identifier format

Changed hardcoverBookId from custom booklore metadata to standard dc:identifier with urn:hardcoverbook: prefix for consistency with other identifiers.

* UPDATE: migrate hardcover_book_id to VARCHAR and fix related issues

## Changes

### 1. Database Migration
- Changed hardcover_book_id column from INTEGER to VARCHAR(255)
- Supports alphanumeric book IDs from Hardcover API
- Updated HardcoverSyncService to handle String ↔ Integer conversion

### 2. Metadata Editor Fixes
- Fixed metadata change detection for provider-specific fields
- Added missing clearFlags entries: hardcoverBookId, lubimyczytacId, lubimyczytacRating
- Resolves issue where rating/review count fields wouldn't save independently

Affected fields now save properly independently:
- Amazon rating & review count
- Goodreads rating & review count
- Hardcover rating & review count
- Lubimyczytac rating
- Ranobedb rating

### 3. Web Reader Hardcover Sync (Major Fix)
Since I changed the data type for hardcover_book_id I had to update references in the HardCoverSyncService.java This turned out to reveal
the Sync Service was not fully implemented:
- Added Hardcover progress sync to ReadingProgressService
- Previously, HARDCOVER sync only worked for Kobo and KOReader devices
- Web browser reading progress now syncs to Hardcover.app

## Files Modified
- booklore-api/src/main/resources/db/migration/V107__Change_hardcover_book_id_to_varchar.sql
- booklore-api/src/main/java/.../service/hardcover/HardcoverSyncService.java
- booklore-api/src/main/java/.../service/progress/ReadingProgressService.java
- booklore-ui/src/app/features/metadata/.../metadata-editor.component.ts

## Breaking Changes
None - migration handles existing integer IDs gracefully

## Testing
- Hardcover sync tested with web reader
- Metadata editor field updates verified
- Database migration confirmed successful

---------

Co-authored-by: ACX <8075870+acx10@users.noreply.github.com>
2026-01-29 17:59:50 -07:00
PhasecoreX
09d4a3025a fix(api): Select correct Hardcover.app ISBN from lookup results (#2530) 2026-01-29 17:55:30 -07:00
Sergio Visinoni
4db2006afd test(API): add missing tests for BookMapperV2 (#2495)
* fix(API): add missing fields to BookMapperV2

This fixes a regression introduced in the data model refactoring work
for multi-format support.
BookMapperV2 was missing mapping for file-related fields.

* Added missing mappings for BookMapperV2
* Added a test for BookMapperV2 to prevent future regressions

* fix(api): fix the code after rebase
2026-01-29 17:46:14 -07:00
ACX
67269ffe4c fix(audiobook-reader): use preload=none with explicit load() for faster streaming (#2520)
* fix(audiobook-reader): use preload=none with API duration for instant load

* fix(audiobook-reader): debounce seek and limit streaming chunk size to 2MB

* no message

---------

Co-authored-by: acx10 <acx10@users.noreply.github.com>
2026-01-29 17:45:10 -07:00
acx10
17aa633b41 Backend APIs 2026-01-29 17:37:11 -07:00
acx10
2b6cc4be7c feat(mobile-api): add updatedAt to progress DTOs for conflict detection
Add updatedAt timestamp field to EpubProgress, PdfProgress, and CbxProgress
DTOs to support progress conflict detection in the mobile app.

The mobile app uses this timestamp to detect when progress has changed on the
server (e.g., from reading in the web UI) while the app was offline with
local progress, enabling automatic conflict resolution.
2026-01-29 14:44:38 -07:00
acx10
0c56b7b720 feat(user-stats): add monthly heatmap endpoint
- Add GET /api/v1/user-stats/heatmap/monthly endpoint for month-based data
- Keep original /heatmap endpoint unchanged for backward compatibility
- Add findSessionCountsByUserAndYearAndMonth repository method
- Add getSessionHeatmapForMonth service method
2026-01-29 00:21:33 -07:00
Balázs Szücs
bbea391c9c fix(metadata-refresh): filter book shelves by authenticated user (#2481)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-27 16:38:47 -07:00
Balázs Szücs
878bc44138 fix(library-processing): re-fetch library entity after clearing entity manager during rescan (#2507)
* fix(library-processing): re-fetch library entity after clearing entity manager during rescan

Ensure the latest library entity state is retrieved after clearing the entity manager in rescanLibrary. Add test to verify fresh entity is used for subsequent processing.

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>

* test(library-processing): update rescan test to verify grouping service usage and remove obsolete assertions

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>

---------

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-27 16:38:30 -07:00
Balázs Szücs
257c016f3f fix(metadata-parsers): improve ISBN search logic and fallback strategies for metadata fetching (#2502)
* fix(metadata-parsers): improve ISBN search logic and fallback strategies for metadata fetching

- Update GoogleParser, HardcoverParser, and ComicvineBookParser to prioritize ISBN search and implement robust fallbacks to title+author and title-only queries
- Refactor GoogleParser to allow dependency injection for HttpClient and Jsoup connections, improving testability
- Enhance HardcoverParser to retry with title-only search if combined title+author results are filtered out
- Adjust MetadataRefreshService to prefer ISBN-13 over ISBN-10 when building fetch requests
- Add JsoupConnectionFactory and DefaultJsoupConnectionFactory for injectable Jsoup connections
- Expand and improve unit tests for GoogleParser and HardcoverParser to cover new fallback behaviors

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>

* fix(google-parser): handle null primary file and correct search term return

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>

---------

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-27 16:37:28 -07:00
Balázs Szücs
58bfe2293a fix(metadata-refresh): correct provider priority order and enhance REPLACE_ALL handling (#2503)
- Update provider priority logic to ensure P1 > P2 > P3 > P4 for all metadata fields
- Refactor buildFetchMetadata to accept existing metadata and preserve fields when using REPLACE_ALL mode
- Adjust service and test method signatures for new parameter
- Add unit test to verify provider priority order

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-27 16:35:06 -07:00
Balázs Szücs
6c4934b8ba fix(metadata-match): include cover image in match score calculation and correct weight aggregation (#2513)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-27 16:29:29 -07:00
Benjamin Erb
54eb3e0ee0 feat(ui): provide hyperlinks for books as book cards in grid view (#2500)
* feat(ui): provide hyperlinks for books as book cards in grid view

* feat(ui): provide hyperlinks for books as book cards in grid view
2026-01-27 16:28:34 -07:00
Sergio Visinoni
be16c7ef3c fix(ui): clean cached properties (#2499)
This fixes the issue with buttons and icons reported in #2472 due to
properties being cached.
2026-01-27 16:27:34 -07:00
ACX
872bf5a3f7 fix(audiobook-reader): use preload=none for immediate streaming playback (#2518) 2026-01-27 16:20:55 -07:00
ACX
74ac2d25d1 fix(additional-file-uploader): add file size validation with UI feedback (#2516) 2026-01-27 11:09:24 -07:00
ACX
2efe452441 refactor: centralize access-denied card styles into shared mixin (#2515)
* refactor: centralize access-denied card styles into shared mixin

* fix: use bracket notation for bookType index signature access
2026-01-27 10:49:57 -07:00
Balázs Szücs
df52e9924e fix(book-rule-evaluator): fix file type handling and add mapping for specific formats to fix magic shelve based on filetype (#2480)
* fix(book-rule-evaluator): fix file type handling and add mapping for specific formats to fix magic shelve based on filetype

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>

* fix(book-rule-evaluator): update test to simplify book creation for group rule evaluation

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>

---------

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-27 10:27:19 -07:00
Balázs Szücs
fab7c14030 fix(os_x-conversion): ignore __MACOSX directory for conversions (#2479)
Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2026-01-27 10:26:31 -07:00