Chaturbate Enhancer

Enhances Chaturbate by adding multiple new features.

Versione datata 28/07/2022. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name             Chaturbate Enhancer
// @description      Enhances Chaturbate by adding multiple new features.
// @version          1.1.0
// @author           MoonDivision
// @license          CC-BY-ND-4.0
// @namespace        https://sleazyfork.org/en/users/884016-moondivision
// @contributionURL  https://chaturbate.com/in/?tour=JpRf&campaign=Nb8Yz&track=enh-contrib&next=/tipping/purchase_tokens/
// @icon             https://www.google.com/s2/favicons?sz=32&domain=chaturbate.com
// @icon64           https://www.google.com/s2/favicons?sz=64&domain=chaturbate.com
// @match            https://chaturbate.com/*
// @match            https://*.chaturbate.com/*
// @connect          camschedule.com
// @grant            GM_addElement
// @grant            GM_xmlhttpRequest
// @grant            GM_addStyle
// @require          https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @run-at           document-body
// @noframes
// ==/UserScript==

(function() {
'use strict';

let style = `
/* Hide media overlays */
.photoVideoDetailSection img {
	filter: unset !important;
}

.userUpload div {
	background: none !important;
}

.psContainer .lockOverlayBg, .smContainer .lockOverlayBg {
	display: none !important;
}

.userUpload img[src$="lock.svg"] {
	display: none !important;
}

/* Hide ads */
.ad, .vote-banner {
	display: none !important;
}

.cb-enh-avatar {
	margin-left: 10px;
	border: 1px solid #bfbfbf;
	width: 150px;
	height: 150px;
	background-color: #ebebeb;
	margin-bottom: 5px;
	background-size: 100% 100%;
	position: relative;
}

.darkmode .cb-enh-avatar {
	border-color: #2d3e50;
	background-color: #202c39;
}

.cb-enh-avatar, .cb-enh-avatar img {
	border-radius: 150px;
}

.cb-enh-avatar img {
	width: 100%;
	height: 100%;
	opacity: 0;

	position: absolute;
	left: 0;
	top: 0;

	-webkit-user-drag: none;
	-webkit-app-region: no-drag;
	user-drag: none;
	app-region: no-drag;

	pointer-events: none;

	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

.cb-enh-footer {
	font-size: 14px;
	color: #341b00;
	font-weight: bold;
}

.darkmode .cb-enh-footer {
	color: #efefef;
}

.cb-enh-footer a {
	color: inherit !important;
	text-decoration: underline;
}

/* Enlarge media in bio */
tr:not(.smContainer) .contentText .previewBorder {
	width: 190px;
	height: 135px;
}

tr:not(.smContainer) .contentText .tokenText {
	top: 118px !important;
	right: 5px !important;
}

/* Detach floaters in "about" */
tr:not(.smContainer):not(.psContainer) .contentText img, tr:not(.smContainer):not(.psContainer) .contentText li, tr:not(.smContainer):not(.psContainer) .contentText a, tr:not(.smContainer):not(.psContainer) .contentText p {
	position: unset !important;
}
`;

GM_addStyle(style);

$(document).ready(function() {
	if('initialRoomDossier' in unsafeWindow) {
		enhanceRoom();
	}

	if(!$('#id_animate_thumbnails').is(':checked')) {
		$(document).on('mouseenter', '.room_list_room img, .roomElement img, .roomCard img', function() {
			if(window.currentHoverInterval) {
				clearInterval(window.currentHoverInterval);
				window.currentHoverInterval = null;
			}

			updateRoomThumb($(this));
			window.currentHoverInterval = setInterval(() => {
				updateRoomThumb($(this));
			}, 100);
		});

		$(document).on('mouseleave', '.room_list_room img, .roomElement img, .roomCard img', function() {
			if(window.currentHoverInterval) {
				clearInterval(window.currentHoverInterval);
				window.currentHoverInterval = null;
			}
		});
	}
});

function updateRoomThumb($el) {
	let uname = $el.parent().data('room');
	$el.attr('src', 'https://roomimg.stream.highwebmedia.com/minifwap/' + uname + '.jpg?' + Math.random());
}

document.cookie = 'noads=1; expires=Sun, 1 Jan 9999 00:00:00 UTC; path=/';
document.cookie = 'agreeterms=1; expires=Sun, 1 Jan 9999 00:00:00 UTC; path=/';
document.cookie = 'fromaffiliate=1; expires=Sun, 1 Jan 9999 00:00:00 UTC; path=/';
document.cookie = 'affkey="eJyrViopylayUlBKzctQ0lFQSkxLA/HMiwsM03KTQCIFIL6RIYhZBGKCGCUgRnpRoQGIk5wLVuKXZBFZpVQLAEdlFCg="; expires=Sun, 1 Jan 9999 00:00:00 UTC; path=/';

document.cookie = 'noads=1; expires=Sun, 1 Jan 9999 00:00:00 UTC; path=/; domain=.chaturbate.com';
document.cookie = 'agreeterms=1; expires=Sun, 1 Jan 9999 00:00:00 UTC; path=/; domain=.chaturbate.com';
document.cookie = 'fromaffiliate=1; expires=Sun, 1 Jan 9999 00:00:00 UTC; path=/; domain=.chaturbate.com';
document.cookie = 'affkey="eJyrViopylayUlBKzctQ0lFQSkxLA/HMiwsM03KTQCIFIL6RIYhZBGKCGCUgRnpRoQGIk5wLVuKXZBFZpVQLAEdlFCg="; expires=Sun, 1 Jan 9999 00:00:00 UTC; path=/; domain=.chaturbate.com';

function enhanceRoom(ajaxTransition=false) {
	$('.cb-enh-row').remove();

	if(unsafeWindow.initialRoomDossier === '') {
		// initialRoomDossier is set but is empty
		// room might be banned or blocked for user

		// Display video preview of non accessible room
		let $baseRoomContentDiv =  $("div.BaseRoomContents div")
		if($baseRoomContentDiv.length > 0) {
			if($baseRoomContentDiv.text().indexOf("Access denied") === 0) {
				$baseRoomContentDiv.append("<br>Chaturbate Enhancer displays video preview of this room.<br><br>");

				let $langForm = $("form[action='/set_language/'] input[name='next']");
				if($langForm.length > 0) {
					let username = $("form[action='/set_language/'] input[name='next']")[0].value.slice(1, -1);
					$baseRoomContentDiv.append($("<img id='cb-enh-room-preview' src='https://cbjpeg.stream.highwebmedia.com/stream?room=" + username + "&f=" + Math.random() + "'>"));
				
					setInterval(function() {
						let $img = $("#cb-enh-room-preview");
						if($img.length > 0) {
							$img.attr("src", "https://cbjpeg.stream.highwebmedia.com/stream?room=" + username + "&f=" + Math.random());
						}
					}, 100);
				}
			}
		}
		return;
	}

	let intv = setInterval(function() {
		if($('video.vjs-tech').length > 0) {
			// Make clicking on live video feed don't pause it anymore
			$('video.vjs-tech').on('pause', function() {
				try {
					$('video.vjs-tech')[0].play();
				} catch(err) {}
			});
			clearInterval(intv);

			// Watch for AJAX page transition
			let currentUsername = $("a.nextCamBgColor")[0].getAttribute('href').slice(6, -1);
			let pageTransitionIntv = setInterval(function() {
				let uname = $("a.nextCamBgColor")[0].getAttribute('href').slice(6, -1);
				if(currentUsername != uname) {
					clearInterval(pageTransitionIntv);
					enhanceRoom(true);
					currentUsername = uname;
				}	
			}, 25);
		}
	}, 25);

	let userData;
	let broadcasterName;
	if(!ajaxTransition) {
		userData = JSON.parse(unsafeWindow.initialRoomDossier);
		broadcasterName = userData.broadcaster_username;
	}
	else {
		broadcasterName = $("a.nextCamBgColor")[0].getAttribute('href').slice(6, -1);
	}

	let intervalId = setInterval(() => {
		let $table = $('.BioContents > div > table');
		if($table.length === 0) {
			return;
		}
		clearInterval(intervalId);

		// Add offline avatar
		let $offlineNotice = $('.offlineRoomNotice');
		if($offlineNotice.length > 0) {
			$offlineNotice.prepend('<div class="cb-enh-avatar"></div>');
			GM_addElement($('.cb-enh-avatar')[0], 'img', {
				src: 'https://camschedule.com/assets/img/avatar.png',
				alt: '',
				onload: 'this.style.opacity=1'
			});

			GM_addElement($('.cb-enh-avatar')[0], 'img', {
				src: 'https://thumbv.camschedule.com/av/' + broadcasterName + '.jpg',
				alt: '',
				onload: 'this.style.opacity=1'
			});
		}

		let $divSchedule = addBioRow('Schedule', false, '<div id="cb-enh-iframe"></div>');
		if(userData && userData.room_status === 'offline') {
			addBioRow('Last Subject', true, userData.room_title);
		}
		let $divRegion = addBioRow('Region', false, '<a href=""></a>');
		let $divOnlineFor = addBioRow('Online For', false);

		let lang = $('html').attr('lang');

		GM_xmlhttpRequest({
			method: 'GET',
			url: 'https://camschedule.com/api/room/' + broadcasterName + '?lang=' + lang,
			timeout: 60*2*1000,
			onload: function(responseDetails) {
				let data;
				try {
					data = JSON.parse(responseDetails.responseText);
				}
				catch(SyntaxError) {
					return;
				}

				// Populate "region" row
				if(data['region'] !== '') {
					let href = '#';
					if(data['region_id'] == 0) {
						href = '/asian-cams/';
					}
					else if(data['region_id'] == 1) {
						href = '/euro-russian-cams/';
					}
					else if(data['region_id'] == 2) {
						href = '/north-american-cams/';
					}
					else if(data['region_id'] == 3) {
						href = '/south-american-cams/';
					}
					else if(data['region_id'] == 4) {
						href = '/other-region-cams/';
					}

					let elA = $divRegion.children('.cb-enh-row-value').children('a')[0];
					elA.innerHTML = data['region'];
					elA.href = href;
					$divRegion.show();
				}

				// Populate "online for" row
				if(data['online_for'] !== '') {
					$divOnlineFor.children('.cb-enh-row-value')[0].innerHTML = data['online_for'];
					$divOnlineFor.show();
				}

				// Add schedule
				if(data['has_schedule']) {
					let darkMode = $('body').hasClass('darkmode') ? 1 : 0;
					let iframeWrapper = document.getElementById('cb-enh-iframe');
					GM_addElement(iframeWrapper, 'iframe', {
						src: 'https://camschedule.com/embed/schedule/' + broadcasterName + '?dark=' + darkMode + '&lang=' + lang,
						style: 'width: 100%; height: 350px; border: 0;',
					});
					$divSchedule.show();
				}
			}
		});

	}, 500);
}

function addBioRow(name, visible = true, value = '') {
	let $el = $('<tr class="cb-enh-row" style="' + (visible ? '' : 'display: none; ') + 'font-size: 14px; font-weight: normal; line-height: 15px; vertical-align: top; text-align: left;"><td class="label" style="padding-bottom: 9px; font-family: UbuntuMedium, Arial, Helvetica, sans-serif; height: 16px;"><span>' + name + ':</span></td><td class="contentText cb-enh-row-value" style="font-size: 14px; line-height: 16px; font-family: UbuntuRegular, Arial, Helvetica, sans-serif;">' + value + '</td></tr>');
	
	let $psContainers = $('.BioContents > div > table > .psContainer');
	let $smContainers = $('.BioContents > div > table > .smContainer');
	
	if($psContainers.length > 0) {
		$psContainers.last().after($el);
	}
	else if($smContainers.length > 0) {
		$smContainers.last().after($el);
	}
	else {
		$('.BioContents > div > table > tr').slice(-2).first().after($el);
	}

	return $el;
}

})();