E-H Visited

Marks visited galleries.

Устаревшая версия за 23.03.2019. Перейдите к последней версии.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name           E-H Visited
// @description    Marks visited galleries.
// @author         Hen Tie
// @homepage       https://hen-tie.tumblr.com/
// @namespace      https://greasyfork.org/en/users/8336
// @include        /https?:\/\/(e-|ex)hentai\.org\/.*/
// @require        https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// @grant          GM_setValue
// @grant          GM_getValue
// @run-at         document-start
// @icon           https://i.imgur.com/pMMVGRx.png
// @version        2.4
// ==/UserScript==
// 2019 fork of exvisited: sleazyfork.org/en/scripts/22270

/*═════════════════════════╦═════════════════════════════╦════════════════════════╗
║          IMPORT          ║           EXPORT            ║          CSS           ║
╠══════════════════════════╬═════════════════════════════╬════════════════════════╣
║ data format is unchanged ║ localstorage is impermanent ║ you can set custom css ║
║ should import from any   ║ but exporting is simple     ║ for marking viewed     ║
║ old exvisited scripts    ║ one click gives plain text  ║ galleries              ║
╚══════════════════════════╩═════════════════════════════╩═══════════════════════*/

var storageName = "ehVisited"; //name of object, to avoid clash with old installs
var url = document.URL;
var sto = localStorage.getItem(storageName) ? localStorage.getItem(storageName) : '{"data":{}}';
var vis = JSON.parse(sto);
var spl = url.split("/");
var d1 = spl[3]
var d2 = spl[4];
var d3 = spl[5];
var css = GM_getValue("css") ? GM_getValue("css") : "background:rgba(2, 129, 255, .2)"; //default highlight colour
if (css === "initial") {
	css = "background:rgba(2, 129, 255, .2)";
} else if (css === "none") {
	css = "";
}

vis["data"] = !vis["data"] ? Array() : vis["data"];

if (typeof (Storage) == "undefined") {
	alert("E-H Visited:\nYour browser does not support localStorage :(");
}

// date.now shim (probably unnecessary)
if (!Date.now) {
	Date.now = function () {
		return new Date().getTime();
	};
}

Number.prototype.pad0 = function (length) {
	var result = this.toString();
	while (result.length < length) result = "0" + result;
	return result;
}

Object.size = function (obj) {
	var size = 0,
		key;
	for (key in obj) {
		if (obj.hasOwnProperty(key)) size++;
	}
	return size;
};

function ehvStore() {
	var c = d2 + "." + d3;
	vis["data"][c] = Date.now();
	localStorage.setItem(storageName, JSON.stringify(vis));
}

function timeDifference(current, previous) {
	var msPerMinute = 60 * 1000;
	var msPerHour = msPerMinute * 60;
	var msPerDay = msPerHour * 24;
	var msPerMonth = msPerDay * 30;
	var msPerYear = msPerDay * 365;
	var elapsed = current - previous;

	if (elapsed < msPerMinute) {
		return Math.round(elapsed / 1000) + " seconds ago";
	} else if (elapsed < msPerHour) {
		return Math.round(elapsed / msPerMinute) + " minutes ago";
	} else if (elapsed < msPerDay) {
		return Math.round(elapsed / msPerHour) + " hours ago";
	} else if (elapsed < msPerMonth) {
		return Math.round(elapsed / msPerDay) + " days ago";
	} else if (elapsed < msPerYear) {
		return Math.round(elapsed / msPerMonth) + " months ago";
	} else {
		return Math.round(elapsed / msPerYear) + " years ago";
	}
}

function ehvHide() {
	var list = $("table.itg>tbody>tr"); //present only in list views
	var thumb = $(".itg .gl1t"); //present only in thumbnail view
	var gid;
	var d;
	var galleryId;

	// check current view
	if (list.length > 0) {
		if ($('.gl1e').length) { //extended
			for (i = 0; i < list.length; i++) {
				gid = $(list[i]).find(".glname a").attr("href").split("/");
				galleryId = gid[4] + "." + gid[5];
				if (vis["data"][galleryId] != undefined) {
					d = new Date(vis["data"][galleryId]);
					$(list[i]).addClass("ehv-visited");
					$(list[i]).find('.gldown').prepend("<ehv class='ehv-extended'>" + timeDifference(Date.now(), vis["data"][galleryId]) + "<br>(" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth() + 1) + ")</div>")
				}
			}
		} else if ($('.gl1c').length) { //compact
			var borderColour = $('.gl1c').first().css('border-top-color'); //border colour different between domains
			$('table.itg tbody>tr:first-child').append('<th>Visited</th>');
			for (i = 1; i < list.length; i++) {
				gid = $(list[i]).find(".glname a").attr("href").split("/");
				galleryId = gid[4] + "." + gid[5];
				if (vis["data"][galleryId] != undefined) {
					d = new Date(vis["data"][galleryId]);
					$(list[i]).addClass("ehv-visited");
					$(list[i]).append('<td class="ehv-compact" style="border-color:' + borderColour + ';"><ehv title="' + timeDifference(Date.now(), vis["data"][galleryId]) + "\n" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth() + 1) + '">&#128065Yes</ehv></td>');
				} else {
					$(list[i]).append('<td class="ehv-compact" style="border-color:' + borderColour + ';"></td>');
				}
			}
		} else { //minimal
			for (i = 1; i < list.length; i++) {
				gid = $(list[i]).find(".glname a").attr("href").split("/");
				galleryId = gid[4] + "." + gid[5];
				if (vis["data"][galleryId] != undefined) {
					d = new Date(vis["data"][galleryId]);
					$(list[i]).addClass("ehv-visited");
					$(list[i]).find('.gl2m').append('<ehv class="ehv-minimal" title="' + timeDifference(Date.now(), vis["data"][galleryId]) + "\n" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth() + 1) + '">&#128065</ehv>')
				}
			}
		}
	} else if (thumb.length > 0) { //thumbnail
		for (var i = 0; i < thumb.length; i++) {
			gid = $(thumb[i]).find(".glname a").attr("href").split("/");
			var c = gid[4] + "." + gid[5];
			if (vis["data"][c] != undefined) {
				d = new Date(vis["data"][c]);
				$(thumb[i]).addClass("ehv-visited");
				$(thumb[i]).children('.gl5t').after("<ehv class='ehv-thumbnail'>" + timeDifference(Date.now(), vis["data"][c]) + " (" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth() + 1) + ")</div>")
			}
		}
	} else {
		console.log("E-H Visited\nI don't know what view mode this is!");
	}
}

//script body
$("<style>.gl3e>div:nth-child(6){left:unset;width:100%;text-align:center;} .gl2m{width:144px;} .gl2m>div:nth-child(3){left:unset;right:4px;top:7px;}" + //overrides
	".ehv-minimal{position:absolute;top:7px;right:23px;width:1em;line-height:1;font-size:15px;}" + //icon only
	".ehv-compact{border-style:solid;border-width:1px 0;}" + //td with icon
	".ehv-extended,.ehv-thumbnail{display:block;text-align:center;margin-bottom:1em;}" + //full text timestamp
	"table.itg>tbody>tr.ehv-visited, .gl1t.ehv-visited{" + css + "}" + //style visited galleries
	".ehv-controls{text-align:center;display:block;}" +
	"</style>").appendTo("head");

if (d1 == "g") {
	ehvStore();
}

if (d1.substr(0, 1) == "?" || d1.substr(0, 1) == "#" || d1.substr(0, 1) == "f" || d1.substr(0, 1) == "t" || !d1) {
	var len = Object.size(vis["data"]);
	$("#toppane").append("<ehv class='ehv-controls'>Galleries visited: " + len + " (<a href='javascript:;' class='ehv-import'>Import</a> / <a href='javascript:;' class='ehv-export'>Export</a> / <a href='javascript:;' class='ehv-css'>CSS</a>)</ehv>");

	$(".ehv-export").click(function () {
		var e = "";
		for (var d in vis["data"]) {
			e += d + ":" + vis["data"][d] + ";";
		}
		prompt("E-H Visited:\nYour data has been exported.", e);
	});


	$(".ehv-import").click(function () {
		var c = prompt("E-H Visited:\nPaste here to import, and overwrite current data.");
		if (c) {
			var d = JSON.parse('{"data":{}}');
			var sp = c.split(";");
			for (var k in sp) {
				var s = sp[k].split(":");
				d["data"][s[0]] = parseInt(s[1]);
			}

			alert("Imported " + Object.size(d["data"]) + " entries.");
			localStorage.setItem(storageName, JSON.stringify(d))
			location.reload();

		}
	});

	$(".ehv-css").click(function () {
		var c = prompt("E-H Visited:\nThis CSS is applied to visited galleries.\n('initial' to reset, or 'none' for no styling)", css);
		if (c) {
			GM_setValue("css", c);
			location.reload();
		}
	});

	ehvHide();
}