[PR #4301] Issue: 4300 Sorting Square/Rectangle aspect ratios, sub-sorting by width #4212

Open
opened 2026-04-25 00:18:49 +02:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/advplyr/audiobookshelf/pull/4301
Author: @tagmeh
Created: 5/17/2025
Status: 🔄 Open

Base: masterHead: Issue-4300-book-cover-sorting


📝 Commits (10+)

  • 42eb4e3 Feature mostly implemented, has UI/CSS bug, not super DRY, no tests.
  • 6edfcfb Merge branch 'master' of https://github.com/tagmeh/audiobookshelf
  • 3cdf16e Merge branch 'advplyr:master' into master
  • 093be36 Merge branch 'advplyr:master' into master
  • 28d98b4 Merge branch 'advplyr:master' into master
  • a2c7d64 Working 1.0. Removed duplicate api calls per image. Attempted testing, removed, unable to figure out either testing option.
  • fc655bc Removed Cover.cy.js file. Wasn't able to figure out cypress testing.
  • faa0a83 Removed console logs.
  • 43ca263 Fixed rectangle book cover sub-sorting and conditional divider display.
  • 34c4e7b Added cy-ids to divs for testing purposes. Added a basic test for Cover.vue, and actual logic tests for SortedCovers.vue. All tests are passing.

📊 Changes

5 files changed (+602 additions, -28 deletions)

View changed files

client/components/covers/DisplayCover.vue (+113 -0)
client/components/covers/SortedCovers.vue (+102 -0)
📝 client/components/modals/item/tabs/Cover.vue (+72 -28)
client/cypress/tests/components/covers/SortedCovers.cy.js (+184 -0)
client/cypress/tests/components/modals/item/tab/Cover.cy.js (+131 -0)

📄 Description

Brief summary

Sorts book covers by square or rectangle aspect ratios, sub-sorting on width. Shows square covers first if the library-specific setting "Use Square Book Covers" is true, otherwise shows rectangle book covers first. Always shows both aspect ratios. Divider is not shown if there are only covers of one aspect ratio.

Looking for feedback and guidance. I'm not new to programming, but I don't know all of JS/Nuxt/Vue's magics.

Which issue is fixed?

Fixes #4300

In-depth Description

Describe your solution in more depth.
Upon book covers query, Cover.vue's submitSearchForm returns an array of book cover image urls.
Cover.vue runs resolveImages to pre-load the returned results (array of book cover images) in order to get their dimensions,. Once that's done, the array of Image objects is passed into covers/SortedCovers.vue for display. covers/SortedCovers.vue sorts the images into rectangle and square images, sub-sorting by x, then y values. Conditionally displaying one group or the other first based on the "Use square book covers" library setting. Also conditionally shows a divider if both rectangle and square images exist, keeping both image types separate. covers/SortedCovers.vue uses covers/DisplayCover.vue to display the pre-queried image object without reloading the image, which would have happened if we used covers/PreviewCovers.vue.

Cover.vue continues to use covers/PreviewCover.vue to display the current/main book cover image and any local images displayed in the tab.

How does it work? Why is this the best solution?
Relies on the Cover.vue to pre-query the images so we can sort before calling the loop to render the images. By adding new components, existing processes aren't affected by any changes. Due to a few factors: Cover.vue calling the backend in sequence for each remote api book cover provider, the response being an array of strings, and the images being loaded with height and width at the component level, all make sorting the images difficult without pre-querying the images at some point in the process, before they're displayed to the user.

There may be a more optimal approach. The image querying could be done in the covers/SortedCover.vue file or the SortedCover.vue and DisplayCover.vue could be merged together. JavaScript/Frontend coding isn't exactly my forte, I'm much more comfortable on the backend. However, this doesn't appear to slow anything down, greatly improves the book covers display, and doesn't appear to affect any of the existing systems. I wish I could have had some mocha or cypress tests to further verify/codify the changes, but I guess those frameworks are just a bit much for me.

Does it solve a problem that affects multiple users or is this an edge case for your setup?
Mostly a preference thing. More like an ease of use/polish-level enhancement. Not required, but a nice to have. Technically it affects any user who is looking to update/improve a book's cover and has to hunt for their preferred ratio/size/style. With this change, it should be easier to quickly identify if there are any, say, square images in the return, or if you'll have to settle for a rectangular image.

How have you tested this?

Most testing was done manually, side by side the current version of the app to verify nothing outside of the intended change, changed. Added some cypress tests to validate the square/rectangle sorting, sub-sorting (ascending), and tests to validate border (between image groupings/sections) behavior.

Screenshots

All images are shown, square images are sorted first, then rectangle images.

User prefers square images.
image
image

User prefers rectangle images.
image
image

Book only returns one of Rectangle or Square images (The divider is hidden).
Images are sub-sorted by size (x, then y) in ascending order (not a togglable option).

Rectangles only:
image

Squares only (Coerced into rectangles):
image

Short demo to show existing behavior is retained:
abbCoverRatioDemo


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/advplyr/audiobookshelf/pull/4301 **Author:** [@tagmeh](https://github.com/tagmeh) **Created:** 5/17/2025 **Status:** 🔄 Open **Base:** `master` ← **Head:** `Issue-4300-book-cover-sorting` --- ### 📝 Commits (10+) - [`42eb4e3`](https://github.com/advplyr/audiobookshelf/commit/42eb4e3f0411b16146dc27b65fb55b9c0afbd069) Feature mostly implemented, has UI/CSS bug, not super DRY, no tests. - [`6edfcfb`](https://github.com/advplyr/audiobookshelf/commit/6edfcfb271573dad415e47c60a6a7dc0d6d14893) Merge branch 'master' of https://github.com/tagmeh/audiobookshelf - [`3cdf16e`](https://github.com/advplyr/audiobookshelf/commit/3cdf16e86fdd0da17c4077917d74821177da7f4b) Merge branch 'advplyr:master' into master - [`093be36`](https://github.com/advplyr/audiobookshelf/commit/093be36192acaf437dec980729103f732a7dd120) Merge branch 'advplyr:master' into master - [`28d98b4`](https://github.com/advplyr/audiobookshelf/commit/28d98b4dbce8709c955529ce70caf10f39c34506) Merge branch 'advplyr:master' into master - [`a2c7d64`](https://github.com/advplyr/audiobookshelf/commit/a2c7d645445683cda3e8d683d69dcde4fde74f2a) Working 1.0. Removed duplicate api calls per image. Attempted testing, removed, unable to figure out either testing option. - [`fc655bc`](https://github.com/advplyr/audiobookshelf/commit/fc655bc0e29cacabbf6f264d4b50a82969a3e170) Removed Cover.cy.js file. Wasn't able to figure out cypress testing. - [`faa0a83`](https://github.com/advplyr/audiobookshelf/commit/faa0a833e2c254efc84780ac7933a07102569f9a) Removed console logs. - [`43ca263`](https://github.com/advplyr/audiobookshelf/commit/43ca263eac95d63a57e7fb5ba83f6c7f52945cce) Fixed rectangle book cover sub-sorting and conditional divider display. - [`34c4e7b`](https://github.com/advplyr/audiobookshelf/commit/34c4e7b08457bfa53ca4d0e7bfe4429007a1ce7d) Added cy-ids to divs for testing purposes. Added a basic test for Cover.vue, and actual logic tests for SortedCovers.vue. All tests are passing. ### 📊 Changes **5 files changed** (+602 additions, -28 deletions) <details> <summary>View changed files</summary> ➕ `client/components/covers/DisplayCover.vue` (+113 -0) ➕ `client/components/covers/SortedCovers.vue` (+102 -0) 📝 `client/components/modals/item/tabs/Cover.vue` (+72 -28) ➕ `client/cypress/tests/components/covers/SortedCovers.cy.js` (+184 -0) ➕ `client/cypress/tests/components/modals/item/tab/Cover.cy.js` (+131 -0) </details> ### 📄 Description <!-- For Work In Progress Pull Requests, please use the Draft PR feature, see https://github.blog/2019-02-14-introducing-draft-pull-requests/ for further details. If you do not follow this template, the PR may be closed without review. Please ensure all checks pass. If you are a new contributor, the workflows will need to be manually approved before they run. --> ## Brief summary Sorts book covers by square or rectangle aspect ratios, sub-sorting on width. Shows square covers first if the library-specific setting "Use Square Book Covers" is true, otherwise shows rectangle book covers first. Always shows both aspect ratios. Divider is not shown if there are only covers of one aspect ratio. Looking for feedback and guidance. I'm not new to programming, but I don't know all of JS/Nuxt/Vue's magics. ## Which issue is fixed? Fixes #4300 ## In-depth Description Describe your solution in more depth. Upon book covers query, Cover.vue's submitSearchForm returns an array of book cover image urls. Cover.vue runs resolveImages to pre-load the returned results (array of book cover images) in order to get their dimensions,. Once that's done, the array of Image objects is passed into covers/SortedCovers.vue for display. covers/SortedCovers.vue sorts the images into rectangle and square images, sub-sorting by x, then y values. Conditionally displaying one group or the other first based on the "Use square book covers" library setting. Also conditionally shows a divider if both rectangle and square images exist, keeping both image types separate. covers/SortedCovers.vue uses covers/DisplayCover.vue to display the pre-queried image object without reloading the image, which would have happened if we used covers/PreviewCovers.vue. Cover.vue continues to use covers/PreviewCover.vue to display the current/main book cover image and any local images displayed in the tab. How does it work? Why is this the best solution? Relies on the Cover.vue to pre-query the images so we can sort before calling the loop to render the images. By adding new components, existing processes aren't affected by any changes. Due to a few factors: Cover.vue calling the backend in sequence for each remote api book cover provider, the response being an array of strings, and the images being loaded with height and width at the component level, all make sorting the images difficult without pre-querying the images at some point in the process, before they're displayed to the user. There may be a more optimal approach. The image querying could be done in the covers/SortedCover.vue file or the SortedCover.vue and DisplayCover.vue could be merged together. JavaScript/Frontend coding isn't exactly my forte, I'm much more comfortable on the backend. However, this doesn't appear to slow anything down, greatly improves the book covers display, and doesn't appear to affect any of the existing systems. I wish I could have had some mocha or cypress tests to further verify/codify the changes, but I guess those frameworks are just a bit much for me. Does it solve a problem that affects multiple users or is this an edge case for your setup? Mostly a preference thing. More like an ease of use/polish-level enhancement. Not required, but a nice to have. Technically it affects any user who is looking to update/improve a book's cover and has to hunt for their preferred ratio/size/style. With this change, it should be easier to quickly identify if there are any, say, square images in the return, or if you'll have to settle for a rectangular image. ## How have you tested this? Most testing was done manually, side by side the current version of the app to verify nothing outside of the intended change, changed. Added some cypress tests to validate the square/rectangle sorting, sub-sorting (ascending), and tests to validate border (between image groupings/sections) behavior. ## Screenshots All images are shown, square images are sorted first, then rectangle images. User prefers square images. <img width="505.5" height="399.5" alt="image" src="https://github.com/user-attachments/assets/a32443de-5b6d-4d15-8c53-542b6d0f5616" /> <img width="506" height="400" alt="image" src="https://github.com/user-attachments/assets/f5372ff1-3a00-45c4-99a7-353d9c485830" /> User prefers rectangle images. <img width="505.5" height="437" alt="image" src="https://github.com/user-attachments/assets/77f624f5-5c8e-404e-a3cc-f99b21eb7ae4" /> <img width="504.5" height="435" alt="image" src="https://github.com/user-attachments/assets/e31fae34-b114-49d5-8c73-23b34fc464b9" /> Book only returns one of Rectangle or Square images (The divider is hidden). Images are sub-sorted by size (x, then y) in ascending order (not a togglable option). Rectangles only: <img width="504" height="434" alt="image" src="https://github.com/user-attachments/assets/a53da404-ae37-4826-938d-cb61b95a095d" /> Squares only (Coerced into rectangles): <img width="503" height="434" alt="image" src="https://github.com/user-attachments/assets/756e7a28-29a5-42b1-a557-698dbdde2ae3" /> Short demo to show existing behavior is retained: ![abbCoverRatioDemo](https://github.com/user-attachments/assets/47cd15f2-3c9b-4444-b335-d6e8d945bdcb) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2026-04-25 00:18:49 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#4212