navchandar / Gaana Dark Auto-Enable & Auto-Play

// ==UserScript==
// @name            Gaana Dark Auto-Enable & Auto-Play
// @description     Auto-enables Gaana Dark theme. Works only on gaana.com
// @author          navchandar
// @license         MIT
// @version         2.4
// @match           *://*.gaana.com/*
// @excludes        *
// @run-at          document-start
// @homepage        https://github.com/navchandar
// @copyright       2022, navchandar(https://openuserjs.org/users/navchandar)
// @updateURL       https://openuserjs.org/meta/navchandar/Gaana_Dark_Auto-Enable_Auto-Play.meta.js
// @downloadURL     https://openuserjs.org/install/navchandar/Gaana_Dark_Auto-Enable_Auto-Play.user.js
// @icon            https://css375.gaanacdn.com/images/favicon.ico
// @require         http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @grant           GM_addStyle
// ==/UserScript==

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for (var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1, c.length);
    }
    if (c.indexOf(nameEQ) === 0) {
      return c.substring(nameEQ.length, c.length);
    }
  }
  return null;
}

function createCookie(name, value, days) {
  var expires = ""
  if (days) {
    var date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    expires = "; expires=" + date.toGMTString();
  }
  else {
    expires = "";
  }
  document.cookie = name + "=" + value + expires + "; domain='gaana.com'; path=/";
}

function eraseCookie(name) {
  createCookie(name, "", -1);
}

// Make theme black
createCookie('hd_marker', true, 100);
createCookie('themecolor_v1', 'black', 100);
createCookie('themedetect1', 1, 100);

// Play HD songs
createCookie('songquality', 'HD', 100);

// Removes ADs hopefully.
eraseCookie('globalAdsCounterThreeMin');
eraseCookie('globalAdsCounterTwoMin');
eraseCookie('globalAdsCounterTwoMinBg');
createCookie('globalAdsCounterThreeMin', 0, 100);
createCookie('globalAdsCounterTwoMin', 0, 100);
createCookie('globalAdsCounterTwoMinBg', 0, 100);

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleepFunc() {
  await sleep(3000);
}

/*--- waitForKeyElements():  A utility function, for Greasemonkey scripts,
    that detects and handles AJAXed content.

    Usage example:

        waitForKeyElements (
            "div.comments"
            , commentCallbackFunction
        );

        //--- Page-specific function to do what we want when the node is found.
        function commentCallbackFunction (jNode) {
            jNode.text ("This comment changed by waitForKeyElements().");
        }

    IMPORTANT: This function requires your script to have loaded jQuery.
*/
function waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector) {
  var targetNodes, btargetsFound;
  if (typeof iframeSelector == "undefined")
    targetNodes = $(selectorTxt);
  else
    targetNodes = $(iframeSelector).contents()
    .find(selectorTxt);

  if (targetNodes && targetNodes.length > 0) {
    btargetsFound = true;
    /*--- Found target node(s).  Go through each and act if they
        are new.
    */
    targetNodes.each(function () {
      var jThis = $(this);
      var alreadyFound = jThis.data('alreadyFound') || false;

      if (!alreadyFound) {
        //--- Call the payload function.
        var cancelFound = actionFunction(jThis);
        if (cancelFound)
          btargetsFound = false;
        else
          jThis.data('alreadyFound', true);
      }
    });
  }
  else {
    btargetsFound = false;
  }

  //--- Get the timer-control variable for this selector.
  var controlObj = waitForKeyElements.controlObj || {};
  var controlKey = selectorTxt.replace(/[^\w]/g, "_");
  var timeControl = controlObj[controlKey];

  //--- Now set or clear the timer as appropriate.
  if (btargetsFound && bWaitOnce && timeControl) {
    //--- The only condition where we need to clear the timer.
    clearInterval(timeControl);
    delete controlObj[controlKey]
  }
  else {
    //--- Set a timer, if needed.
    if (!timeControl) {
      timeControl = setInterval(function () {
        waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector);
      }, 300);
      controlObj[controlKey] = timeControl;
    }
  }
  waitForKeyElements.controlObj = controlObj;
}

function delete_ad_elems(classname) {
  try {
    var my_elems = document.getElementsByClassName(classname);
    for (var k = my_elems.length - 1; k >= 0; --k) {
      my_elems[k].parentElement.removeChild(my_elems[k]);
    }
  }
  catch (Exception) {};
}

function deleteAds() {
  delete_ad_elems("rhs-container");
  delete_ad_elems("right add_block ads-section");
  delete_ad_elems("adunit");
  delete_ad_elems("appdow_inner clearfix");
  delete_ad_elems("homeappdownolad");
}

function UpdateWidth() {
  try {
    document.querySelector('div.activeonscroll.clearfix').style.width = "100%";
  }
  catch (Exception) {};
}

function UpdateStyle() {
  try {
    document.querySelector('#mainarea').style.padding = "0 10px 0 70px";
  }
  catch (Exception) {};
}

function enableDarkMode() {
  if (!document.querySelector('body[class="dark"]') && document.querySelector('button[aria-label="theme button"]')) {
    document.querySelector('button[aria-label="theme button"]').click();
  }
}

function autoPlay() {
  if (document.querySelector('button[title="Play All"]')) {
    document.querySelector('button[title="Play All"]').click();
    clearInterval(playinterval);
  }
}

waitForKeyElements("div.activeonscroll.clearfix", UpdateWidth);
waitForKeyElements("#mainarea", UpdateStyle);

// call this every 3 seconds to update according to page load
let playinterval = setInterval(function () {
  waitForKeyElements('button[aria-label="theme button"]', enableDarkMode);
  waitForKeyElements('button[title="Play All"]', autoPlay);
}, 5000);

// call this every 3 seconds to update according to page load
setInterval(function () {
  deleteAds();
}, 3000);