wombley / Audible Cloud Player Enhancements

// ==UserScript==
// @name         Audible Cloud Player Enhancements
// @version      0.11
// @description  Play audiobooks in a sidebar or in new tabs with Audible's Cloud Player.
// @copyright    2018, wombley (https://openuserjs.org/users/wombley)
// @license      MIT
// @match        https://www.audible.co.uk/a/library*
// @match        https://www.audible.com/a/library*
// @match        https://www.audible.co.uk/lib*
// @match        https://www.audible.com/lib*
// @grant        none
// @require      http://code.jquery.com/jquery-2.2.4.min.js
// ==/UserScript==

(function () {
  'use strict';

  function getASIN(e) {
    console.log(e);
    return $(e.currentTarget).parent().find('input[name=asin]').val();
  }

  function getCloudPlayerLink(asin) {
    return "/cloudplayer?asin=" + asin + "&ref_=a_libraryItem_cloudplayer_" + asin + "#";
  }

  function getBookDetails(e) {
    const row = $(e.currentTarget).closest("tr");
    const asin = getASIN(e);
    const image = row.children("td").first().find('img').attr("src").trim();
    const title = row.children("td").eq(1).find('a').first().text().trim();
    const author = row.children("td").eq(2).find('a').first().text().trim();
    const returnVal = {
      asin: asin,
      title: title,
      author: author,
      image: image
    };
    console.log(returnVal);
    return returnVal;
  }

  function getBookList() {
    let bookList = localStorage.getItem("audible_extension_book_list");
    if (!bookList) {
      bookList = {}
    }
    else {
      bookList = JSON.parse(bookList);
    }
    return bookList;
  }

  function setBookList(bookList) {
    localStorage.setItem("audible_extension_book_list", JSON.stringify(bookList));
  }

  function renderBookList() {
    let bookList = getBookList();
    bookList = Object.values(bookList); // Sort by access time
    bookList.sort(function (a, b) {
      return a.accessTime < b.accessTime
    });
    let html = $("<div></div>");
    html.append($("<div style='text-align:center; font-size: 25px; height: 40px; line-height: 40px'>☰</div>"));
    html.css("transition", "all 0.5s ease");
    //console.log(bookList);
    for (let bookASIN in bookList) {
      const book = bookList[bookASIN];
      const element = $("<img width='60' height='60' title='" + book.title + " by " + book.author + "' src='" + book.image + "' />");
      element.css("transition", "all 0.5s ease");
      element.click(function (e) {
        addToBookmarks(book); // Bring to top
        playInSidebar(book.asin);
        openSidebar();
        e.stopImmediatePropagation()
      });
      html.append(element);
    }
    $('#audible-extension-sidebar-bookmarks').html(html);
  }

  function addToBookmarks(bookDetails) {
    bookDetails.accessTime = Date.now();
    const bookList = getBookList();
    bookList[bookDetails.asin] = bookDetails;
    setBookList(bookList);
    renderBookList();
  }

  // "Add" buttons next to each book
  const bookmarkButton = $('<button/>', {
    html: '+&nbsp;Sidebar',
    "class": 'bc-size-small bc-button bc-button-small bc-button-secondary bc-button-text-inner',
    style: "width:100%;",
    click: function (e) {
      addToBookmarks(getBookDetails(e));
    }
  });
  const playSidebarButton = $('<button/>', {
    html: '&#9658;&nbsp;Sidebar',
    "class": 'bc-size-small bc-button bc-button-small bc-button-secondary bc-button-text-inner',
    style: "width:100%;",
    click: function (e) {
      addToBookmarks(getBookDetails(e));
      playInSidebar(getASIN(e));
      e.stopImmediatePropagation()
    }
  });
  const playTabButton = $('<button/>', {
    html: '&#9658;&nbsp;New&nbsp;Tab',
    "class": 'bc-size-small bc-button bc-button-small bc-button-secondary bc-button-text-inner',
    style: "width:100%;",
    click: function (e) {
      var win = window.open(getCloudPlayerLink(getASIN(e)), '_blank');
    }
  });

  $('.adbl-library-action .bc-col-responsive').prepend(playTabButton);
  $('.adbl-library-action .bc-col-responsive').prepend(playSidebarButton);
  $('.adbl-library-action .bc-col-responsive').prepend(bookmarkButton);

  let sidebarOpen = true;

  function openSidebar() {
    console.log("openSidebar");
    $(".adbl-page.desktop").css("marginRight", 460);
    $("#audible-extension-sidebar").css("marginRight", 0);
    $('#adbl-library-content-main table tr th:nth-of-type(6), #adbl-library-content-main table tr td:nth-of-type(6)').hide();
    $('#adbl-library-content-main table tr th:nth-of-type(7), #adbl-library-content-main table tr td:nth-of-type(7)').hide();
    $('.adbl-page.desktop').css("minWidth", 0);
    $('#center-3 .bc-container').css("minWidth", 0);
    $('#adbl-library-content-main').css("minWidth", 0);
    sidebarOpen = true;
  }

  function closeSidebar() {
    $(".adbl-page.desktop").css("marginRight", 60);
    $("#audible-extension-sidebar").css("marginRight", -400);
    $('#adbl-library-content-main table tr th:nth-of-type(6), #adbl-library-content-main table tr td:nth-of-type(6)').show();
    $('#adbl-library-content-main table tr th:nth-of-type(7), #adbl-library-content-main table tr td:nth-of-type(7)').show();
    $('.adbl-page.desktop').css("minWidth", 1040);
    $('#adbl-library-content-main').css("minWidth", 1020);
    sidebarOpen = false;
  }

  function playInSidebar(asin) {
    if ($('#audible-extension-sidebar-player').length < 1) { // Got to dynamically create as Audible does odd things to preexisting iframes
      $('#audible-extension-sidebar-player-div').append("<iframe style='overflow:hidden' scrolling='no' frameborder='0' width='400' height='100%' id='audible-extension-sidebar-player'></iframe>")
    }
    $('#audible-extension-sidebar-player').attr('src', getCloudPlayerLink(asin));
  }
  $(".adbl-page.desktop").css("transition", "all 0.5s ease");
  const sidebar = $('<div/>', {
    style: "position:fixed!important; display:block; right:0; top:0; height: 100%; width: 460px; border-left: 1px solid lightgray; background-color: white; transition: all 0.5s ease;",
    html: "<div id='audible-extension-sidebar-bookmarks' style='width:60px; height:100%; background-color: white; border-right: 1px solid lightgray;'>SB</div>\
               <div id='audible-extension-sidebar-player-div' style='width: 400px; height:100%; position:absolute; top:0; right:0;'></div>",
    id: "audible-extension-sidebar",
    click: function (e) {
      if (sidebarOpen) {
        closeSidebar();
      }
      else {
        openSidebar();
      }
    }
  });
  $("body").append(sidebar);
  closeSidebar();
  renderBookList();

  $.noConflict()
})();