// ==UserScript==
// @name YouTube Color Subcription Tiles By Author
// @description Color tiles on the subscription fee by author name
// @include https://www.youtube.com/feed/subscriptions
// @grant none
// @license MIT
// @version 0.0.4
// @namespace https://greasyfork.org/users/8233
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// ==/UserScript==
// color list
const colors = [
"Aqua", "BurlyWood", "CadetBlue", "Chartreuse", "Chocolate", "DarkCyan",
"DarkGoldenRod", "DarkKhaki", "Darkorange", "DarkSalmon",
"DodgerBlue", "Gold", "Grey", "IndianRed", "Khaki", "LimeGreen", "MediumSeaGreen", "MediumSpringGreen",
"Olive", "Orchid", "PowderBlue", "Silver", "SteelBlue",
];
// color assigned to given names
colorAssignments = {};
function colorSubTiles(x)
{
var tile = x[0];
// set verified icon and title and channel name colors to black
tile.querySelector('yt-icon').style.color = 'black';
tile.querySelector('#channel-name').querySelector('a').style.color = 'black';
Array.from(tile.querySelector('#metadata-line').querySelectorAll('span')).map(x => x.style.color = 'black');
// grab channel name and make sure it has color assigned from the list
var channelname = tile.querySelector('#channel-name').innerText;
if(colorAssignments[channelname] === undefined) {
colorAssignments[channelname] = colors[Object.keys(colorAssignments).length % colors.length];
}
tile.style.backgroundColor = colorAssignments[channelname];
}
window.setTimeout(function(){Array.from(document.querySelectorAll('ytd-grid-video-renderer')).map(x => colorSubTiles([x]));}, 5000);
waitForKeyElements('ytd-grid-video-renderer', colorSubTiles); //as of November 2022
//waitForKeyElements('h1.title > yt-formatted-string.ytd-video-primary-info-renderer', addPicLinks);
/*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
that detects and handles AJAXed content. From: https://git.io/vMmuf
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, /* Required: The jQuery selector string that
specifies the desired element(s).
*/
actionFunction, /* Required: The code to run when elements are
found. It is passed a jNode to the matched
element.
*/
bWaitOnce, /* Optional: If false, will continue to scan for
new elements even after the first match is
found.
*/
iframeSelector /* Optional: If set, identifies the iframe to
search.
*/
) {
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;
}