Last active
November 1, 2025 21:59
-
-
Save zonca/e91085c6fcc74bc98f6acbe8074fe8b9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Audible filter (>=4.0, >=500, skip "Not rated yet") | |
| // @namespace https://audible.com/ | |
| // @version 2.4 | |
| // @description Hide entire Audible book rows failing thresholds | |
| // @match https://www.audible.com/* | |
| // @run-at document-end | |
| // @grant none | |
| // ==/UserScript== | |
| (function () { | |
| "use strict"; | |
| const MIN_RATING = 4.0; | |
| const MIN_REVIEWS = 500; | |
| const BOOK_SELECTOR = 'li.productListItem[id^="product-list-item-"], li.bc-list-item.productListItem'; | |
| function getBook(el) { | |
| return el.closest(BOOK_SELECTOR); | |
| } | |
| function parseRating(text) { | |
| const m = text.match(/(\d(?:\.\d)?)\s*out of 5 stars/i); | |
| return m ? parseFloat(m[1]) : null; | |
| } | |
| function parseReviews(text) { | |
| const m = text.match(/([\d,]+)\s+ratings?/i); | |
| return m ? parseInt(m[1].replace(/,/g, ""), 10) : null; | |
| } | |
| function shouldHide(rating, reviews, rawText) { | |
| if (/not rated yet/i.test(rawText)) return true; | |
| if (rating !== null && rating < MIN_RATING) return true; | |
| if (reviews !== null && reviews < MIN_REVIEWS) return true; | |
| return false; | |
| } | |
| function filterBooks(root) { | |
| const rows = root.querySelectorAll(BOOK_SELECTOR); | |
| rows.forEach((row) => { | |
| const text = row.innerText; | |
| const rating = parseRating(text); | |
| const reviews = parseReviews(text); | |
| if (shouldHide(rating, reviews, text)) { | |
| row.style.display = "none"; | |
| } | |
| }); | |
| } | |
| function badge() { | |
| if (document.getElementById("audible-filter-badge")) return; | |
| const b = document.createElement("div"); | |
| b.id = "audible-filter-badge"; | |
| b.textContent = "Audible filter ≥4.0★, ≥500 ratings, no 'Not rated yet'"; | |
| Object.assign(b.style, { | |
| position: "fixed", | |
| top: "6px", | |
| right: "6px", | |
| background: "#000", | |
| color: "#fff", | |
| padding: "4px 6px", | |
| fontSize: "11px", | |
| zIndex: 999999, | |
| }); | |
| document.body.appendChild(b); | |
| } | |
| badge(); | |
| filterBooks(document); | |
| const obs = new MutationObserver((m) => | |
| m.forEach((x) => | |
| x.addedNodes.forEach((n) => n.nodeType === 1 && filterBooks(n)) | |
| ) | |
| ); | |
| obs.observe(document.body, { childList: true, subtree: true }); | |
| })(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment