Goodreads - No Negative Reviews

Hides book reviews under a certain amount of stars

目前為 2023-07-14 提交的版本,檢視 最新版本

// ==UserScript==
// @name        Goodreads - No Negative Reviews
// @version     1.0.0
// @author      petracoding
// @namespace   petracoding
// @grant       none
// @license     MIT
// @include  		https://www.goodreads.com/*
// @include  		http://www.goodreads.com/*
// @include  		https://goodreads.com/*
// @include  		http://goodreads.com/*
// @description Hides book reviews under a certain amount of stars
// ==/UserScript==


// SETTINGS:

// How many stars (at least) should a review give a book for the review to be shown?
const minRatingToShow = 3; 

// Also hide negative reviews of books you haven't read yet?
const hideReviewsOfUnreadBooks = true; // true or false

// Do the opposite for books you dislike (= Hide positive reviews)
const hideGoodReviewsOfBooksIDislike = true; // true or false

// How many stars (at most) do you give books you dislike?
const maxRatingOfBooksIDislike = 2;

// Bonus option: Should images in reviews be hidden?
const hideImagesInReviews = false; // true or false







// DO NOT CHANGE ANYTHING BELOW HERE.

const wrapper = document.querySelector(".ReviewsList");
let hideGoodReviewsInstead = false;

if (wrapper) {
  const isBookRead = checkIfBookIsRead();
	if (!hideReviewsOfUnreadBooks && !isBookRead) return;
  
  const isDisliked = checkIfBookIsDisliked();
	if (hideGoodReviewsOfBooksIDislike && isDisliked) {
   	 hideGoodReviewsInstead = true;
  }
  
  addCSS();
  searchForReviews();

  setTimeout(() => {
    searchForReviews();
    document.addEventListener("scroll", searchForReviews);
  }, 1000);
}


function searchForReviews() {
  const reviewElements = document.querySelectorAll(".ReviewCard:not(.no-negative-reviews-done)");
  
  if (reviewElements.length > 0) {
    hideReviews(reviewElements);
  }
}


function hideReviews(reviewEls) {
  [...reviewEls].forEach((reviewEl) => {
    if (shouldReviewBeHidden(reviewEl)) {
      reviewEl.classList.add("no-negative-reviews-hidden");
    }
    reviewEl.classList.add("no-negative-reviews-done");
  });
  reviewCount = 0;
  searchForReviews();
}

function shouldReviewBeHidden(reviewEl) {
  if (!reviewEl) return false;
  
  // do not hide liked reviews
  const isLiked = reviewEl.querySelector(".SocialFooter__action .Button--active");
  if (isLiked) return false;
  
  const ratingWrapper = reviewEl.querySelector(".RatingStars");
  if (!ratingWrapper) return false;
  
  const rating = ratingWrapper.querySelectorAll(".RatingStar__fill:first-child").length;
  
  if (hideGoodReviewsInstead) {
    if (rating > maxRatingOfBooksIDislike) {
      return true;
    } else {
      return false;
    }
  } else {
    if (rating < minRatingToShow) {
      return true;
    } else {
      return false;
    }
  }
}

function addCSS() {
  var styleSheet = document.createElement("style");
  styleSheet.setAttribute("type", "text/css");
  document.head.appendChild(styleSheet);
  styleSheet.innerText = `.no-negative-reviews-hidden { height: 0 !important; overflow: hidden; }` + (hideImagesInReviews ? `.ReviewText__content .gr-hostedUserImg { display: none !important; }` : ``);
}

function checkIfBookIsRead() {
  const el1 = document.querySelector(".BookActions");
  if (!el1) return false;
  const el2 = el1.querySelector(".BookActions__button:first-child");
  if (!el2) return false;
  const el3 = el2.querySelector(".Button");
  if (!el3) return false;
  const label = el3.getAttribute("aria-label").replace("Shelved as '", "").replace("'. Tap to edit shelf for this book", "").toLowerCase();
  if (label == 'read' || label == 'currently reading') {
   return true; 
  }
  return false;
}

function checkIfBookIsDisliked() {
  const el1 = document.querySelector(".BookActions");
  if (!el1) return false;
  const ratingWrapper = el1.querySelector(".BookRatingStars");
  if (!ratingWrapper) return false;
  const rating  = ratingWrapper.querySelectorAll(".RatingStar__fill--selectable:first-child").length;
  if (rating == 0) {
    return false;
  }
  if (rating <= maxRatingOfBooksIDislike) {
   return true; 
  }
  return false;
}