BestSubscriber

Organiza tus suscripciones por juego y da like automáticamente a los vídeos que veas

// ==UserScript==
// @name         BestSubscriber
// @namespace    https://gf.qytechs.cn/es/scripts/15251-bestsubscriber
// @version      0.2
// @description  Organiza tus suscripciones por juego y da like automáticamente a los vídeos que veas
// @author       DonNadie
// @match        https://*.youtube.com/feed/subscriptions
// @match        https://*.youtube.com/*
// @match        https://*.youtube.com/watch?v=*
// @grant        none
// @require 	 https://code.jquery.com/jquery-latest.js
// @require 	 https://cdn.jsdelivr.net/sortable/1.4.2/Sortable.min.js
// @require 	 https://gf.qytechs.cn/scripts/15246-micro-templating/code/Micro%20templating.js?version=95830
// @require 	 https://gf.qytechs.cn/scripts/1003-wait-for-key-elements/code/Wait%20for%20key%20elements.js?
version=49342
// @noframes
// ==/UserScript==
/* jshint -W097 */
'use strict';

var BestSubscriber = function ()
{
	var gameList,
		debugMode = false,
		skipWords = [
			'gameplay',
			'episode',
			'episodio',
			'ps4',
			'xbox 360',
			'xbox one',
			'xbox',
			'directo',
		];

	String.prototype.capitalizeFirstLetter = function() {
		return this.charAt(0).toUpperCase() + this.slice(1);
	};
	String.prototype.friendly = function () {
		var str = this;
		if (typeof max == "undefined") max = 32;
		var a_chars = new Array(
			new Array("a",/[áàâãªÁÀÂÃ]/g),
			new Array("e",/[éèêÉÈÊ]/g),
			new Array("i",/[íìîÍÌÎ]/g),
			new Array("o",/[òóôõºÓÒÔÕ]/g),
			new Array("u",/[úùûÚÙÛ]/g),
			new Array("c",/[çÇ]/g),
			new Array("n",/[Ññ]/g)
		);
		// Replace vowel with accent without them
		for(var i=0;i<a_chars.length;i++)
		str = str.replace(a_chars[i][1],a_chars[i][0]);
		// first replace whitespace by -, second remove repeated - by just one, third turn in low case the chars,
		// fourth delete all chars which are not between a-z or 0-9, fifth trim the string and
		// the last step truncate the string to 32 chars
		return str.replace(/\s+/g,'-').toLowerCase().replace(/[^a-z0-9\-]/g, '').replace(/\-{2,}/g,'-').replace(/(^\s*)|(\s*$)/g, '').substr(0, max);
	};

	var init = function ()
	{
		var k,
			game;

		gameList = getConfig();
		setupPanel();

		// detect AJAX navigation
		var observer = new MutationObserver(function(mutations) {
			// We observe the title, so our key elements in body may not be loaded yet
			setTimeout(function () {
				firePageActions();
			}, 100);
		});

		observer.observe(document.querySelector('title'), { childList: true});

		firePageActions();
	}

	var firePageActions = function ()
	{
		if (location.pathname.indexOf("feed/subscriptions") !== -1 && $('.best-subscriber-section').length == 0) {
			setupSubscriptionFeed();
		}
		else if (location.pathname.indexOf("watch") !== -1)
		{
			log("Inside a video");
			if ($(".video-stream.html5-main-video").length == 0) {
				waitForKeyElements (".video-stream.html5-main-video", function () {
					setTimeout(autoLike, 750);
				});
			} else {
				setTimeout(autoLike, 750);
			}
		}
	}

	var getConfig = function ()
	{
		var config = localStorage.bestSubscriber;

		if (config === undefined) {
			// default config
			return [{
				name: 'gta',
				display: false,
			},
			{
				name: 'hurtworld',
				display: true,
			},
			{
				name: 'h1z1',
				display: true,
			},
			{
				name: 'rust',
				display: true,
			}];
		}

		return JSON.parse(config);
	}

	var setConfig = function (config)
	{
		if (config === undefined || !Array.isArray(config)) {
			return;
		}

		localStorage.bestSubscriber = JSON.stringify(config);
	}

	var updateGame = function (name, key, val)
	{
		var k,
			list = getConfig();

		for (k in list) {
			if (list[k].name.friendly() == name) {
				list[k][key] = val;
				setConfig(list);
				break;
			}
		}
	}

	var setupPanel = function ()
	{
		$('#yt-masthead-user').append('<button class="yt-uix-button yt-uix-button-default" data-action="toggle-config-panel" style="margin-left: 20px">BestSubcriber</button>');

		$('#masthead-positioner').prepend(parseTemplate(function () {/*
			<div id="best-subscriber-config">
				<h3>Orden:</h3>
				<ul>
					<%for (var i=0; i<list.length; i++){ %>
						<li><span data-name><%=list[i].name%></span> <span class="bs-delete-button" data-action="delete-game" title="Quitar de la lista">x</span></li>
					<% } %>
				</ul>
				<div>
					<label>
						<input type="text" name="new-game-name" placeholder="GTA 5">
					</label>
					<button data-action="add-game" class="add-button" title="Añadir a la lista">+</button>
				</div>
				<button data-action="save-config" class="yt-uix-button yt-uix-button-default bs-save-button">Guardar cambios</button>
			</div>
			<style>
				#best-subscriber-config {
					display: none;
					position: fixed;
					background: white;
					padding: 10px;
					border: 1px solid;
					left: 89%;
					top: 44%;
					z-index: 1999999999; // set by Youtube..
				}
				#best-subscriber-config li {
					cursor: all-scroll;
					border: 1px dashed;
					padding: 5px;
				}
				#best-subscriber-config li:hover {
					background: #F8F8F8;
				}
				#best-subscriber-config .bs-save-button {
					margin-top: 10px;
					float: right;
				}
				#best-subscriber-config .bs-delete-button {
					font-weight: bold;
					float: right;
					cursor: pointer;
					color: red;
				}
				#best-subscriber-config input {
					margin-top: 5px;
				}
				#best-subscriber-config .add-button {
					color: green;
					font-weight: bold;
					cursor: pointer;
				}
			</style>
		*/}, {list: gameList.slice().reverse()})); // revert the arary to display it in the right order in config panel

		 //$("#best-subscriber-config ul").sortable();
		 Sortable.create($("#best-subscriber-config ul")[0]);

		 $('[data-action="toggle-config-panel"]').on("click", function () {
			 $("#best-subscriber-config").toggle();
		 });

		 $('input[name="new-game-name"]').on("keydown", function(e) {
 			if (e.keyCode == 13) {
 			    e.preventDefault();

 				addGame();
 			}
 		});

 		$('[data-action="add-game"]').on("click", addGame);

 		$('[data-action="delete-game"]').on("click", function () {
 			var game = $(this).closest("[data-name]").text();

 			deleteGame(game);
 			$(this).closest("li").remove();
 		});

 		$('[data-action="save-config"]').on("click", function () {
 			var k,
 				list = [],
 				tmpList = {},
 				oldList = getConfig();

 			for (k in oldList) {
 				tmpList[oldList[k].name] = oldList[k];
 			}

 			$('#best-subscriber-config li span[data-name]').each(function () {
 				var name = $(this).text();
 				list.push(tmpList[name]);
 			});
 			list.reverse();

 			setConfig(list);
 			location.reload();
 		});
	}
	var setupSubscriptionFeed = function () {
		// create the categories (games)
		for (k in gameList)
		{
			game = gameList[k];
			$('#browse-items-primary ol.section-list').prepend(parseTemplate(function () {
				/*
				<li id="game-<%=game.name.friendly() %>" class="best-subscriber-section">
					<ol class="item-section">
						<li>
							<div class="feed-item-container browse-list-item-container yt-section-hover-container compact-shelf shelf-item branded-page-box clearfix">
								<div class="feed-item-dismissable">
									<div class="shelf-title-table">
										<div class="shelf-title-row">
											<h2 class="branded-page-module-title shelf-title-cell"><span class="branded-page-module-title-text"><%=game.name.capitalizeFirstLetter()%></span></h2>
											<div class="menu-container shelf-title-cell">
												<div class="yt-uix-menu-container feed-item-action-menu">
													<ul class="yt-uix-menu-top-level-button-container">
														<li class="yt-uix-menu-top-level-button yt-uix-menu-top-level-flow-button">
															<button data-action="toggle" data-game="<%=game.name.friendly()%>" class="yt-uix-button yt-uix-button-size-default yt-uix-button-opacity yt-uix-button-empty yt-uix-button-has-icon yt-uix-tooltip" onclick=";return false;" title="Mostrar/Ocultar">
																<span class="yt-uix-button-icon-wrapper">
																  <span class="yt-uix-button-icon yt-sprite yt-uix-expander-arrow" <% if (game.display){ %>style="transform: rotate(180deg);"<% } %>>
																	</span>
																</span>
															</button>
														</li>
													</ul>
												</div>
											</div>
										</div>
									</div>
									<div class="multirow-shelf">
										<ul class="shelf-content" data-section="videos" <% if (!game.display){ %>style="display:none"<% } %>>

										</ul>
									</div>
								</div>
								<div class="feed-item-dismissal-notices"></div>
							</div>
						</li>
					</ol>
				</li>
			*/}, { game : game }));
		}


		// move the videos
		$('.yt-shelf-grid-item').each(function () {
				var regex,
					title = $(".yt-lockup-title a", this).text();

			for (k in gameList)
			{
				game = gameList[k];
				regex = new RegExp(game.name, "i");


				if (title.search(regex) !== -1) {
					$('#game-' + game.name.friendly() + ' [data-section="videos"]').append($(this));
				}
			}
		});

		// show/hide categories
		$('[data-action="toggle"]').on("click", function () {
			var game = $(this).data("game"),
				isVisible = false,
				list = getConfig(),
				$videosContainer = $('#game-' + game + ' [data-section="videos"]');

			$videosContainer.toggle();
			isVisible = $videosContainer.is(":visible")

			if (isVisible) {
				$('.yt-uix-expander-arrow', this).css("transform", "rotate(180deg)");
			} else {
				$('.yt-uix-expander-arrow', this).css("transform", "");
			}

			updateGame(game, "display", isVisible);
		});
	}

    var autoLike = function ()
	{
		log("Liking");
		var $likeButton = $('.like-button-renderer-like-button-unclicked'),
			eventObject;

		// is already liked or user is not subscribed
		if (!$likeButton.is(":visible") || !$('.yt-uix-button-subscribed-branded').is(":visible")) {
			log("not clicking");
			return;
		}

        eventObject = document.createEvent('MouseEvents');

        eventObject.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        $likeButton[0].dispatchEvent(eventObject);
    }

	var deleteGame = function (name)
	{
		var k,
			list = getConfig();

		for (k in list) {
			if (list[k].name == name) {
				list = list.splice(k, 1);
				break;
			}
		}
		setConfig(list);
	}

	var addGame = function ()
	{
		var game = $('input[name="new-game-name"]').val(),
			list = getConfig();

		if (game.length < 2) {
			return;
		}

		$('input[name="new-game-name"]').val("");
		$('#best-subscriber-config ul').append('<li><span data-name>' + game + '</span> <span class="bs-delete-button" data-action="delete-game" title="Quitar de la lista">x</span></li>');

		list.push({
			name: game,
			display: true
		});

		setConfig(list);
	}

	var parseTemplate = function(f, data)
	{
		var html = f.toString().replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, '');

		if (typeof data != 'undefined') {
			return _tmpl(html, data);
		} else {
			return html;
		}
	}

	// Not finished, suggests game names for the list for the first time
	var suggestGameNames = function ()
	{
		$('.yt-shelf-grid-item').each(function () {
				var title = $(".yt-lockup-title a", this).text(),
					publisher = $(".yt-lockup-byline a", this).text();

			console.log(title.replace(publisher, ''));
		});
	}

	var log = function () {
		if (debugMode) {
			console.log.apply(console, arguments);
		}
	}

	return {
		init : init,
	};
}();


$(document).ready(function() {
	BestSubscriber.init();
});

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址