IP.Chat Logs

Keep and manage IRC-like logs for IP.Chat clients.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name	IP.Chat Logs
// @namespace	Makaze
// @include	*
// @grant	none
// @version	1.3.2
// @description Keep and manage IRC-like logs for IP.Chat clients.
// ==/UserScript==

var IPChatMenuItems,
menuButton,
logs,
CAPACITY = 5242880,
filled = 0,
occupied = 0,
i = 0;

// Classes constructor

function ClassHandler() {
	var self = this;

	this.classList = function(elem) {
		return elem.className.trim().split(/[\b\s]/);
	};

	this.hasClass = function(elem, className) {
		var classes = self.classList(elem),
		has = false,
		i = 0;

		for (i = 0; i < classes.length; i++) {
			if (classes[i] === className) {
				has = true;
				break;
			}
		}

		return (has);
	};

	this.addClass = function(elem, className) {
		var classes;

		if (!self.hasClass(elem, className)) {
			classes = self.classList(elem);
			classes.push(className);
			elem.className = classes.join(' ').trim();
		}

		return self;
	};

	this.removeClass = function(elem, className) {
		var classes = self.classList(elem),
		i = 0;

		for (i = 0; i < classes.length; i++) {
			if (classes[i] === className) {
				classes.splice(i, 1);
			}
		}

		elem.className = classes.join(' ').trim();

		return self;
	};

	this.toggleClass = function(elem, className) {
		var classes;

		if (self.hasClass(elem, className)) {
			self.removeClass(elem, className);
		} else {
			classes = self.classList(elem);
			classes.push(className);
			elem.className = classes.join(' ').trim();
		}

		return self;
	};
}

// Initialize

var Classes = new ClassHandler();

// End Classes constructor

function dateAndTime(which) {
	var currentdate = new Date(),
	output;

	which = which || 'default';
	
	switch (which) {
		case 'time':
			output = ((currentdate.getHours() < 10) ? '0' + currentdate.getHours() : currentdate.getHours()) + ":"
				+ ((currentdate.getMinutes() < 10) ? '0' + currentdate.getMinutes() : currentdate.getMinutes()) + ":"
				+ ((currentdate.getSeconds() < 10) ? '0' + currentdate.getSeconds() : currentdate.getSeconds());
		break;
		case 'date':
			output = (((currentdate.getMonth() + 1) < 10) ? '0' + (currentdate.getMonth() + 1)  : (currentdate.getMonth() + 1)) + "/"
				+ ((currentdate.getDate() < 10) ? '0' + currentdate.getDate() : currentdate.getDate()) + "/"
				+ currentdate.getFullYear();
		break;
		default:
			output = ((currentdate.getHours() < 10) ? '0' + currentdate.getHours() : currentdate.getHours()) + ":"
				+ ((currentdate.getMinutes() < 10) ? '0' + currentdate.getMinutes() : currentdate.getMinutes()) + ":"
				+ ((currentdate.getSeconds() < 10) ? '0' + currentdate.getSeconds() : currentdate.getSeconds())
				+ ' on '
				+ (((currentdate.getMonth() + 1) < 10) ? '0' + (currentdate.getMonth() + 1)  : (currentdate.getMonth() + 1)) + "/"
				+ ((currentdate.getDate() < 10) ? '0' + currentdate.getDate() : currentdate.getDate()) + "/"
				+ currentdate.getFullYear();
	}
	return output;
}

function empty(elem) {
	while (elem.hasChildNodes()) {
		elem.removeChild(elem.lastChild);
	}
}

function createElement(type, callback) {
	var element = document.createElement(type);

	callback(element);

	return element;
}

function roundToNthDecimal(d, n) {
	return Math.round(d * Math.pow(10, n)) / Math.pow(10, n);
}

function fade(elem, type, speed) {
	var defaultOpacity,
	currentDisplay = elem.style.display || window.getComputedStyle(elem).display;

	elem.style.opacity = '';
	defaultOpacity = window.getComputedStyle(elem).opacity;
	elem.style.opacity = 0;

	// Default values:

	switch (arguments.length) {
		case 1:
			type = 'toggle';
		case 2:
			speed = 300;
		break;
	}

	switch (type) {
		case 'in':
			elem.style.display = '';
			setTimeout(function() {
				elem.style.transition = 'all ' + speed + 'ms ease-in-out';
				elem.style.opacity = defaultOpacity;
				setTimeout(function() {
					elem.style.transition = '';
					elem.style.opacity = '';
				}, speed + 10);
			}, 1);
		break;
		case 'out':
			elem.style.transition = '';
			elem.style.opacity = defaultOpacity;
			elem.style.transition = 'all ' + speed + 'ms ease-in-out';
			elem.style.opacity = 0;
			setTimeout(function() {
				elem.style.display = 'none';
				elem.style.transition = '';
				elem.style.opacity = '';
			}, speed + 10);
		break;
		case 'toggle':
		default:
			if (currentDisplay === 'none') {
				elem.style.display = '';
				setTimeout(function() {
					elem.style.transition = 'all ' + speed + 'ms ease-in-out';
					elem.style.opacity = defaultOpacity;
					setTimeout(function() {
						elem.style.transition = '';
						elem.style.opacity = '';
					}, speed + 10);
				}, 1);
			} else {
				elem.style.transition = '';
				elem.style.opacity = defaultOpacity;
				elem.style.transition = 'all ' + speed + 'ms ease-in-out';
				elem.style.opacity = 0;
				setTimeout(function() {
					elem.style.display = 'none';
					elem.style.transition = '';
					elem.style.opacity = '';
				}, speed + 10);
			}
	}
}

function createLog(logs, i) {
	return createElement('div', function(el) {
		el.className = 'log';

		el.appendChild(createElement('div', function(del) {
			del.className = 'delete';
			del.appendChild(document.createTextNode('Delete'));
			del.onclick = function() {
				deleteLog(this.parentNode, logs[i].initiated);
			};
		}));

		el.appendChild(document.createTextNode('-----\nLog started at [' + logs[i].initiated + ']\n-----\n'));

		el.appendChild(createElement('span', function(content) {
			content.innerHTML = logs[i].log;
		}));
	});
}

function deleteLog(logElement, date) {
	var logs = JSON.parse(localStorage.getItem('IP.Chat Logs')),
	CAPACITY = 5242880,
	filled = 0;

	var confirmContent = createElement('span', function(cont) {
		cont.appendChild(document.createTextNode('Are you sure? '));

		cont.appendChild(createElement('a', function(yes) {
			yes.id = 'yes';
			yes.href = 'javascript:void(0)';
			yes.appendChild(document.createTextNode('[Yes]'));
			yes.onclick = function() {
				var i = 0;

				document.getElementById('confirm').style.opacity = 0;
				document.getElementById('screen').style.opacity = 0;
				setTimeout(function() {
					document.getElementById('confirm').style.display = 'none';
					document.getElementById('screen').style.display = 'none';
				}, 300);

				for (i = 0; i < logs.length; i++) {
					if (logs[i].initiated === date) {
						logs.splice(i, 1);
						localStorage.setItem('IP.Chat Logs', JSON.stringify(logs));
						break;
					}
				}

				for (i = 0; i < localStorage.length; i++) {
					filled += localStorage.getItem(localStorage.key(i)).length;
				}
				occupied = roundToNthDecimal((filled / CAPACITY) * 100, 1);
				document.getElementById('space').childNodes[0].nodeValue = occupied + '% full';

				logElement.className = logElement.className + ' deleted';
				if (logElement.nextSibling) {
					logElement.nextSibling.remove();
				} else {
					logElement.previousSibling.remove();
				}
				setTimeout(function() {
					logElement.remove();
				}, 500);
			};
		}));

		cont.appendChild(document.createTextNode(' '));

		cont.appendChild(createElement('a', function(no) {
			no.id = 'no';
			no.href = 'javascript:void(0)';
			no.appendChild(document.createTextNode('[Cancel]'));
			no.onclick = function() {
				document.getElementById('confirm').style.opacity = 0;
				document.getElementById('screen').style.opacity = 0;
				setTimeout(function() {
					document.getElementById('confirm').style.display = 'none';
					document.getElementById('screen').style.display = 'none';
				}, 300);
			};
		}));
	});

	empty(document.getElementById('confirm'));

	document.getElementById('confirm').appendChild(confirmContent);

	document.getElementById('screen').style.display = 'block';
	document.getElementById('confirm').style.display = 'block';
	setTimeout(function() {
		document.getElementById('screen').style.opacity = 1;
		document.getElementById('confirm').style.opacity = 1;
	}, 1);
}

function deleteAllLogs() {
	var CAPACITY = 5242880,
	filled = 0,
	logElement;

	var confirmContent = createElement('span', function(cont) {
		cont.appendChild(document.createTextNode('Are you sure? '));

		cont.appendChild(createElement('a', function(yes) {
			yes.id = 'yes';
			yes.href = 'javascript:void(0)';
			yes.appendChild(document.createTextNode('[Yes]'));
			yes.onclick = function() {
				var i = 0;
				document.getElementById('confirm').style.opacity = 0;
				document.getElementById('screen').style.opacity = 0;
				setTimeout(function() {
					document.getElementById('confirm').style.display = 'none';
					document.getElementById('screen').style.display = 'none';
				}, 300);

				localStorage.removeItem('IP.Chat Logs');

				for (i = 0; i < localStorage.length; i++) {
					filled += localStorage.getItem(localStorage.key(i)).length;
				}
				occupied = roundToNthDecimal((filled / CAPACITY) * 100, 1);
				document.getElementById('space').childNodes[0].nodeValue = occupied + '% full';

				var waitHandler = function() {
					logElement.remove();
				};

				for (i = 0; i < document.getElementsByClassName('log').length; i++) {
					logElement = document.getElementsByClassName('log')[i];
					logElement.className = logElement.className + ' deleted';
					if (logElement.nextSibling) {
						logElement.nextSibling.remove();
					} else {
						logElement.previousSibling.remove();
					}
					setTimeout(waitHandler, 500);
				}
			};
		}));

		cont.appendChild(document.createTextNode(' '));

		cont.appendChild(createElement('a', function(no) {
			no.id = 'no';
			no.href = 'javascript:void(0)';
			no.appendChild(document.createTextNode('[Cancel]'));
			no.onclick = function() {
				document.getElementById('confirm').style.opacity = 0;
				document.getElementById('screen').style.opacity = 0;
				setTimeout(function() {
					document.getElementById('confirm').style.display = 'none';
					document.getElementById('screen').style.display = 'none';
				}, 300);
			};
		}));
	});

	empty(document.getElementById('confirm'));

	document.getElementById('confirm').appendChild(confirmContent);

	document.getElementById('screen').style.display = 'block';
	document.getElementById('confirm').style.display = 'block';
	setTimeout(function() {
		document.getElementById('screen').style.opacity = 1;
		document.getElementById('confirm').style.opacity = 1;
	}, 1);
}

if (document.body.id === 'ipboard_body' && document.getElementById('chat-form') != null) {
	var nick,
	curr,
	append = '';

	logs = (localStorage.getItem('IP.Chat Logs')) ? JSON.parse(localStorage.getItem('IP.Chat Logs')) : [];

	for (i = 0; i < localStorage.length; i++) {
		filled += localStorage.getItem(localStorage.key(i)).length;
	}

	if (filled + JSON.stringify({'initiated': dateAndTime(), 'log': ''}).length >= CAPACITY) {
		logs.splice(0, 1);
	}

	logs.push({'initiated': dateAndTime(), 'log': ''});

	localStorage.setItem('IP.Chat Logs', JSON.stringify(logs));

	document.addEventListener('DOMNodeInserted', function(event) {
		if (event.target.nodeType !== 1 || event.target.id !== 'storage_chatroom') {
			return false;
		}

		var latestMessage,
		latestMessageText,
		logs = JSON.parse(localStorage.getItem('IP.Chat Logs')),
		CAPACITY = 5242880,
		filled = 0,
		i = 0;

		latestMessage = event.target.parentNode.getElementsByTagName('div')[event.target.parentNode.getElementsByTagName('div').length - 1];

		if (!Classes.hasClass(latestMessage.parentNode, 'post')) {
			return false;
		}

		latestMessageText = latestMessage.innerHTML.replace(/<br>/gi, '<br>\t');

		if (!latestMessageText.length) {
			return false;
		}

		nick = null;

		if (Classes.hasClass(latestMessage.parentNode, 'chat-moderator')) {
			if (latestMessage.parentNode.getElementsByTagName('label')[0] != null) {
				nick = latestMessage.parentNode.getElementsByTagName('label')[0].innerHTML;
			} else {
				nick = '';
			}
		}

		curr = latestMessage.parentNode;

		while (nick === null) {
			if (curr.getElementsByTagName('label').length) {
				nick = curr.getElementsByTagName('label')[0].innerHTML;
			} else {
				curr = curr.previousSibling;
			}
		}

		for (i = 0; i < localStorage.length; i++) {
			filled += localStorage.getItem(localStorage.key(i)).length;
		}

		if (Classes.hasClass(latestMessage.parentNode, 'chat-me')) {
			append = '\n[' + dateAndTime('time') + '] **' + nick + ' ' + latestMessageText.substr(2, latestMessageText.length - 4) + '**';
		} else if (Classes.hasClass(latestMessage.parentNode, 'chat-notice')) {
			append = '\n[' + dateAndTime('time') + '] ' + nick + ' ' + latestMessageText.substr(2, latestMessageText.length - 2);
		} else if (Classes.hasClass(latestMessage.parentNode, 'chat-message')) {
			append = '\n[' + dateAndTime('time') + '] ' + nick + ': ' + latestMessageText;
		} else {
			if (nick.length) {
				append = '\n[' + dateAndTime('time') + '] ' + nick + ' ' + latestMessageText;
			} else {
				append = '\n[' + dateAndTime('time') + '] ' + latestMessageText;
			}
		}

		logs[logs.length - 1].log += append;

		if (filled + append.length >= CAPACITY) {
			logs.splice(0, 1);
		}
		localStorage.setItem('IP.Chat Logs', JSON.stringify(logs));
	});

	if (document.getElementById('IPChatMenuItems') == null) {
		IPChatMenuItems = createElement('div', function(menu) {
			menu.id = 'IPChatMenuItems';
			menu.style.textAlign = 'right';
		});
		document.getElementById('chatters-online-wrap').nextSibling.nextSibling.getElementsByTagName('ul')[0].appendChild(IPChatMenuItems);
	}

	if (document.getElementById('IPChatMenuItems').hasChildNodes()) {
		document.getElementById('IPChatMenuItems').appendChild(document.createElement('br'));
	}

	menuButton = createElement('a', function(button) {
		button.id = 'viewIPChatLogs';
		button.className = 'ipsButton_secondary';
		button.href = window.location.origin + '/IP.Chat_Logs';
		button.target = '_blank';
		button.style.marginTop = '10px';
		button.appendChild(document.createTextNode('View Logs'));
	});

	document.getElementById('IPChatMenuItems').appendChild(menuButton);
}

if (window.location.href === window.location.origin + '/IP.Chat_Logs' && localStorage.getItem('IP.Chat Logs')) {
	var style,
	funcs;

	logs = JSON.parse(localStorage.getItem('IP.Chat Logs'));

	style = createElement('style', function(el) {
		el.type = 'text/css';
		el.appendChild(document.createTextNode(
			'#screen {\n' +
				'position: fixed;\n' +
				'height: 100%;\n' +
				'width: 100%;\n' +
				'background-color: rgba(0, 0, 0, .7);\n' +
				'top: 0px;\n' +
				'left: 0px;\n' +
				'transition: all .3s ease-in-out;\n' +
				'opacity: 0;\n' +
				'display: none;\n' +
			'}\n\n' +

			'#confirm {\n' +
				'position: fixed;\n' +
				'font-size: 3em;\n' +
				'background-color: rgba(255, 255, 255, .9);\n' +
				'box-shadow: 0px 0px 3px;\n' +
				'height: 40px;\n' +
				'line-height: 40px;\n' +
				'width: 620px;\n' +
				'text-align: center;\n' +
				'top: 50%;\n' +
				'left: 50%;\n' +
				'margin-top: -32px;\n' +
				'margin-left: -350px;\n' +
				'padding: 10px 20px;\n' +
				'border-radius: 5px;\n' +
				'transition: all .3s ease-in-out;\n' +
				'opacity: 0;\n' +
				'display: none;\n' +
			'}\n\n' +

			'#space {\n' +
				'font-size: 20px;\n' +
			'}\n\n' +

			'#logs {\n' +
				'margin: 8px 0;\n' +
				'padding: 10px;\n' +
				'background-color: #fcfcfc;\n' +
			'}\n\n' +

			'#logs img.bbc {\n' +
				'vertical-align: middle;\n' +
			'}\n\n' +

			'#logs > .log {\n' +
				'transition: all .3s ease-in-out;\n' +
				'overflow: hidden;\n' +
			'}\n\n' +

			'#logs > .log:hover {\n' +
			//	'background-color: #f5f5f5;\n' +
			'}\n\n' +

			'.delete {\n' +
			//	'display: none;\n' +
				'float: right;\n' +
				'background-color: #444;\n' +
				'padding: 3px 5px;\n' +
				'color: #eee;\n' +
				'font-size: 15px;\n' +
				'letter-spacing: 2px;\n' +
				'text-transform: uppercase;\n' +
				'cursor: pointer;\n' +
			'}\n\n' +

			'.delete:hover {\n' +
				'background-color: #222;\n' +
			'}\n\n' +

			'.deleted {\n' +
				'background-color: #222 ! important;\n' +
				'color: #eee ! important;\n' +
				'font-size: 0px ! important;\n' +
			'}\n\n' +

			'.deleted > * {\n' +
				'display: none;\n' +
			'}'
		));
	});

	document.title = 'IP.Chat Logs';
	document.body.style.fontFamily = 'monospace';
	document.head.appendChild(style);

	// Body creation

	empty(document.body);

	document.body.appendChild(createElement('div', function(filter) {
		filter.id = 'screen';
	}));

	document.body.appendChild(createElement('div', function(confirm) {
		confirm.id = 'confirm';
	}));

	document.body.appendChild(createElement('div', function(space) {
		space.id = 'space';

		space.appendChild(document.createTextNode('0% full'));

		space.appendChild(createElement('span', function(delete_all) {
			delete_all.id = 'delete_all';
			delete_all.className = 'delete';
			delete_all.appendChild(document.createTextNode('Delete All'));
			delete_all.onclick = deleteAllLogs;
		}));

		space.appendChild(createElement('span', function(hide) {
			hide.id = 'hide_non-logs';
			hide.className = 'delete';
			hide.style.marginRight = '10px';
			hide.appendChild(document.createTextNode('Hide Non-Logs'));
			hide.onclick = function() {
				var i = 0,
				deletes;

				fade(document.getElementById('space'), 'out');
				for (i = 0, deletes = document.getElementsByClassName('delete'); i < deletes.length; i++) {
					fade(deletes[i], 'out');
				}
			};
		}));
	}));

	document.body.appendChild(createElement('pre', function(pre) {
		pre.id = 'logs';
	}));

	for (i = 0; i < localStorage.length; i++) {
		filled += localStorage.getItem(localStorage.key(i)).length;
	}
	occupied = roundToNthDecimal((filled / CAPACITY) * 100, 1);
	document.getElementById('space').childNodes[0].nodeValue = occupied + '% full';

	for (i = 0; i < logs.length; i++) {
		if (document.getElementById('logs').hasChildNodes()) {
			document.getElementById('logs').appendChild(document.createTextNode('\n'));
		}

		document.getElementById('logs').appendChild(createLog(logs, i));
	}
}