Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Improved Control Panel
- // @description Sort threads by date, highlights/alerts you on unread posts, thread links go to newest unread post
- // @namespace E-Hentai
- // @include https://forums.e-hentai.org/index.php?*act=UserCP&CODE=26*
- // @version 2.2.2
- // @author Superlatanium
- // ==/UserScript==
- var ICPUIFatherElement = document.getElementById('ucpcontent').parentElement;
- var ICPUIMainElement = document.createElement("div");
- // This HTML is minified
- ICPUIMainElement.id = "ICPinfo";
- ICPUIMainElement.innerHTML = '<div class="maintitle-like"><span>Threads monitoring: <span id="monitorStatus">ON</span> <button id="toggleMonitor">Stop</button></span></div><div class="maintitle-like"><span>Clear script data if you have modified forum timezone settings: <button id="clearData">Reset</button></span></div>';
- document.styleSheets[0].addRule('.maintitle-like', 'border: 1px solid #F7F7F7; color: #000; font-size: 8pt; font-weight: bold; margin: 0; padding: 8px;');
- ICPUIFatherElement.insertBefore(ICPUIMainElement, ICPUIFatherElement.firstChild);
- var ICPUIElements = {
- monitorStatus: document.getElementById('monitorStatus'),
- toggleMonitor: document.getElementById('toggleMonitor'),
- clearData: document.getElementById('clearData'),
- };
- var clearScriptData = function() {
- localStorage.improvedControlPanel = '';
- alert('Script data is cleared, please refresh to let it take effect.');
- }
- ICPUIElements.clearData.onclick = clearScriptData
- var myForums = [7, 87, 74, 79, 72, 74, 76, 77];
- var interval = 180000; // updates every 5 minutes (but this value is 3 minutes bruh)
- var subforumInterval = 3600000; // an hour
- var timeout = 4000000; // updates stop after a bit more than 1 hour of inactivity
- var otherUnreadThreads = [];
- if (!localStorage.improvedControlPanel){
- getTimeZone();
- return;
- }
- var storage = JSON.parse(localStorage.improvedControlPanel);
- var userId = new RegExp(/showuser=\d+/.exec(document.querySelector('a[href*="showuser"]').href)[0]);
- var lastClicked = Date.now();
- var atLeastOneHighlighted;
- document.getElementById('ucpcontent').style.backgroundColor = '#4286f4';
- var audio = document.createElement('audio');
- audio.muted = true;
- function unmuteOnce() {
- audio.muted = false;
- document.body.removeEventListener("mouseover", unmuteOnce);
- document.body.removeEventListener("click", unmuteOnce);
- }
- document.body.addEventListener("mouseover", unmuteOnce);
- document.body.addEventListener("click", unmuteOnce);
- var source = audio.appendChild(document.createElement('source'));
- source.src = 'https://reasoningtheory.net/ding.mp3';
- source.type = 'audio/mpeg';
- var skin = document.getElementById('gfooter').querySelector('option[selected="selected"]').innerHTML;
- if (skin == 'Fusion')
- var unreadColor = '#73464E';
- else if (skin == 'Ambience')
- var unreadColor = '#E0E0E0';
- function buildCss(){
- document.head.appendChild(document.createElement('style')).innerHTML = `
- #peekButton {padding:5px}
- #peekButton:hover {background-color:yellow}
- #peekdiv {position:fixed; top:50%; left:15%; width:70%; height:40%; border:3px solid green;}
- #peekdiv > img {position:fixed; top:calc(50% + 4px); left:calc(85% - 23px)}
- #ucpcontent .maintitle > div:nth-child(1) {float:left}
- #ucpcontent .maintitle > div:nth-child(3) {float:right}
- #ignoreBtn {margin-left:5px; margin-right:5px}
- iframe {width:100%; height:100%;}
- `;
- }
- buildCss();
- var table = document.getElementsByClassName('borderwrapm')[0].children[0].children[0];
- var peekDiv;
- function cleanContent(){
- //Remove email notification text
- [].forEach.call(document.getElementsByClassName('desc'), function(desc){
- if (desc.childNodes.length > 1){
- desc.removeChild(desc.childNodes[desc.childNodes.length - 1]);
- desc.removeChild(desc.childNodes[desc.childNodes.length - 1]);
- }
- });
- //Sort threads by date
- var trs = [];
- for (var i = table.children.length - 2; i > 0; i--){
- var tr = table.children[i];
- if (tr.children[0].className == 'row1'){
- tr.parentElement.removeChild(tr);
- continue;
- }
- tr.threadDate = dateStringToDate(tr.children[4].childNodes[0].textContent);
- trs.push(tr);
- tr.parentElement.removeChild(tr);
- }
- trs.sort(function(a, b){
- return b.threadDate - a.threadDate;
- });
- atLeastOneHighlighted = false;
- var displayedThreads = [];
- trs.forEach(function(tr){
- if (tr.children[5].textContent != 'Ignore'){
- displayedThreads.push(tr.getElementsByTagName('a')[0].href.match(/(t|showtopic)=(\d+)/)[2]);
- }
- });
- var foundSubforumThread = false;
- trs.forEach(function(tr){
- var a = tr.getElementsByTagName('a')[0];
- var threadNumber = a.href.match(/(t|showtopic)=(\d+)/)[2];
- if (!/showtopic/.test(a.href)){
- //Add &view=getnewpost to the end of each subscribed thread link
- a.parentElement.removeChild(a.nextSibling);
- a.parentElement.removeChild(a.nextSibling);
- a.parentElement.removeChild(a.nextSibling);
- a.target = '_blank';
- a.onclick = function(){ read(a); }; //left click
- a.oncontextmenu = function(){ read(a); }; //right click
- a.onmouseup = function(e) { if (e.which === 2) read(a); }; //middle click
- a.href = a.href + '&view=getnewpost';
- }
- //If you haven't read the latest post, highlight the thread
- if (!/Ignore/.test(tr.children[5].textContent) && ((!storage.latestRead[threadNumber] || storage.latestRead[threadNumber] < tr.threadDate) && !userId.test(tr.children[4].getElementsByTagName('a')[0].href))){
- if (!/auction/i.test(tr.children[1].textContent))
- atLeastOneHighlighted = true;
- [].forEach.call(tr.children, function(td){
- td.style.backgroundColor = unreadColor;
- });
- } else if (/Ignore/.test(tr.children[5].textContent)){
- //add new threads from subscribed forums
- if (displayedThreads.indexOf(threadNumber) != -1) //don't display threads already subscribed to
- return;
- if (storage.seenThreads.indexOf(threadNumber) != -1) //don't display threads Ignored
- return;
- foundSubforumThread = true;
- [].forEach.call(tr.children, function(td){
- td.style.backgroundColor = unreadColor;
- td.style.padding = '12px 5px 12px 5px';
- });
- tr.children[1].children[0].onclick = setThreadRead;
- tr.children[1].children[0].oncontextmenu = setThreadRead;
- tr.children[5].children[0].onclick = function(){
- tr.parentElement.removeChild(tr);
- if (storage.seenThreads.indexOf(threadNumber) == -1)
- storage.seenThreads.push(threadNumber);
- saveStorage();
- };
- }
- function setThreadRead(){
- [].forEach.call(tr.children, function(td){
- td.style.backgroundColor = '';
- });
- if (storage.seenThreads.indexOf(threadNumber) == -1 && displayedThreads.indexOf(threadNumber) == -1){
- storage.seenThreads.push(threadNumber); //new threads gotten from subforums only
- for (var i = otherUnreadThreads.length - 1; i >= 0; i--){
- if (otherUnreadThreads[i].children[1].textContent === tr.children[1].textContent)
- otherUnreadThreads.splice(0, 1);
- }
- } else
- read(a);
- saveStorage();
- }
- var peekButton = document.createElement('img');
- tr.children[0].replaceChild(peekButton, tr.children[0].children[0]);
- peekButton.id = 'peekButton';
- peekButton.src = 'https://reasoningtheory.net/eye.png';
- peekButton.onclick = function(){
- function exitDiv(){
- if (peekDiv)
- document.body.removeChild(peekDiv);
- peekDiv = '';
- }
- if (peekDiv){
- exitDiv();
- return;
- }
- peekDiv = document.body.appendChild(document.createElement('div'));
- peekDiv.id = 'peekdiv';
- var peekIFrame = peekDiv.appendChild(document.createElement('iframe'));
- peekIFrame.src = a.href;
- peekIFrame.onload = function(){
- setThreadRead();
- [].forEach.call(peekIFrame.contentDocument.body.getElementsByClassName('borderwrap'), function(post){
- if (post.children.length != 4)
- return;
- var userProfile = post.getElementsByClassName('postdetails')[1];
- userProfile.hiddenHTML = userProfile.innerHTML;
- userProfile.innerHTML = userProfile.children[0].innerHTML;
- var showProfile = userProfile.appendChild(peekIFrame.contentDocument.createElement('span'));
- showProfile.textContent = ' ?';
- showProfile.style.textDecoration = 'underline';
- showProfile.onclick = function(){
- userProfile.innerHTML = userProfile.hiddenHTML;
- };
- });
- };
- var exitDivButton = peekDiv.appendChild(document.createElement('img'));
- exitDivButton.src = 'https://reasoningtheory.net/x.png';
- exitDivButton.onclick = exitDiv;
- setThreadRead();
- };
- table.insertBefore(tr, table.children[table.children.length - 1]);
- });
- if ((atLeastOneHighlighted && threadMonitor.isRunning) || foundSubforumThread)
- audio.play();
- function dateStringToDate(dateString){
- var nowDate = new Date();
- var threadDate;
- if (/Today/.test(dateString))
- threadDate = new Date(nowDate.getUTCFullYear(), nowDate.getUTCMonth(), nowDate.getUTCDate(), dateString.match(/(\d\d)\:/)[1], dateString.match(/\:(\d\d)/)[1]);
- else if (/Yesterday/.test(dateString))
- threadDate = new Date(nowDate.getUTCFullYear(), nowDate.getUTCMonth(), nowDate.getUTCDate() - 1, dateString.match(/(\d\d)\:/)[1], dateString.match(/\:(\d\d)/)[1]);
- else
- threadDate = new Date(dateString);
- threadDate.setMinutes(threadDate.getMinutes() - threadDate.getTimezoneOffset() - storage.offset);
- return threadDate;
- }
- }
- function read(a){
- storage.latestRead[a.href.match(/&t=(\d+)/)[1]] = Date.now();
- [].forEach.call(a.parentElement.parentElement.children, function(td){
- td.style.backgroundColor = '';
- });
- saveStorage();
- }
- document.body.addEventListener('click', function(){
- lastClicked = Date.now() - 100; //ensure that updates get disabled after a missed thread and resume due to Date.now() - lastClicked < interval test coming out near 0
- if (threadMonitor.isSuspended) { threadMonitor.start(); }
- });
- document.body.addEventListener('contextmenu', function(){
- lastClicked = Date.now() - 100;
- });
- var threadMonitor = {
- isRunning: false,
- isSuspended: false,
- updateSheduler: null,
- update: function() {
- var idleTime = Date.now() - lastClicked;
- if (idleTime > timeout || (atLeastOneHighlighted === true && (idleTime > interval))){
- document.getElementById('ucpcontent').style.backgroundColor = 'red';
- this.stop(); this.isSuspended = true; return;
- }
- document.getElementById('ucpcontent').style.backgroundColor = 'yellow';
- get('https://forums.e-hentai.org/index.php?act=UserCP&CODE=26', function(data){
- document.getElementById('ucpcontent').innerHTML = data.getElementById('ucpcontent').innerHTML; //threads
- var tableHead = document.getElementsByClassName('maintitle')[2];
- if (tableHead.textContent == 'Menu') //new PM
- tableHead = document.getElementsByClassName('maintitle')[3];
- table = document.getElementsByClassName('borderwrapm')[0].children[0].children[0];
- var userlinks = document.getElementById('userlinks');
- userlinks.innerHTML = data.getElementById('userlinks').innerHTML; //PMs
- var msgA = userlinks.children[1].children[3];
- if (msgA.textContent.substring(0, 1) !== '0')
- userlinks.style.backgroundColor = '#3399ff';
- msgA.onclick = function(){
- userlinks.style.backgroundColor = '';
- };
- msgA.oncontextmenu = msgA.onclick;
- document.getElementById('gfooter').innerHTML = data.getElementById('gfooter').innerHTML; //Time is now
- if (tableHead.children.length === 0) {
- // initialize tableHead...
- tableHead.id = 'tableHead';
- tableHead.style.textAlign = 'center';
- tableHead.innerHTML = `<div>Welcome to your control panel</div><div>${data.getElementById('gfooter').textContent.match(/Time\sis.+\d:\d+/)[0]}</div>`;
- }
- if (Date.now() - storage.lastSubforumCheck > subforumInterval) {
- getSubforums(false);
- } else {
- otherUnreadThreads.forEach(function(otherUnreadThread){
- table.insertBefore(otherUnreadThread, table.children[1]);
- });
- document.getElementById('ucpcontent').style.backgroundColor = '#4286f4';
- }
- cleanContent();
- });
- },
- syncUIState: function() {
- ICPUIElements.monitorStatus.textContent = this.isRunning ? 'ON' : 'OFF';
- ICPUIElements.toggleMonitor.textContent = this.isRunning ? 'Stop' : 'Start';
- },
- launchUpdateLoop: function() {
- // 此函数非阻塞
- // this is NOT "blocking"
- this.update();
- this.updateSheduler = setTimeout(this.launchUpdateLoop, interval);
- },
- start: function() {
- lastClicked = Date.now() - 2000;
- this.isRunning = true;
- this.isSuspended = false;
- this.syncUIState();
- this.launchUpdateLoop();
- },
- stop: function() {
- // 此函数不会打断update函数
- // this will not break update function halfway
- document.getElementById('ucpcontent').style.backgroundColor = 'red';
- this.isRunning = false;
- this.syncUIState();
- clearTimeout(this.updateSheduler);
- this.updateSheduler = null;
- },
- toggleState: function() {
- if (this.isRunning) {
- this.stop();
- } else {
- this.start();
- }
- },
- }
- ICPUIElements.toggleMonitor.onclick = function() { threadMonitor.toggleState(); }
- // ICPUIElements.toggleMonitor.onclick = threadMonitor.toggleState
- // this commented line is invalid because "this context" changes
- threadMonitor.start()
- function getSubforums(ignoreAll){
- var subforumIndex = 0;
- storage.lastSubforumCheck = Date.now();
- otherUnreadThreads = [];
- getForum();
- function getForum(){
- get('https://forums.e-hentai.org/index.php?showforum=' + myForums[subforumIndex], function(data){
- var getTable = data.getElementsByClassName('ipbtable')[1].children[0];
- for (var j = getTable.children.length - 1; j > 0; j--){
- var tr = getTable.children[j];
- if (tr.getElementsByTagName('a').length === 0)
- continue;
- var threadTitleTBlock = tr.children[2]
- var threadTitleContainer = threadTitleTBlock.getElementsByTagName('span')[0];
- var threadHrefElement;
- if (threadTitleContainer) {
- // 正常,直接获取链接
- threadHrefElement = threadTitleContainer.getElementsByTagName('a')[0]
- } else {
- // 没有span,fallback到格内第一个a元素的父元素
- threadHrefElement = threadTitleTBlock.getElementsByTagName('a')[0]
- threadTitleContainer = threadHrefElement.parentElement
- }
- var threadTitle = threadTitleContainer.textContent;
- try {
- var threadNumber = threadHrefElement.href.match(/showtopic=(\d+)/)[1];
- } catch(err) {
- continue;
- }
- var desc = tr.children[2].getElementsByClassName('desc');
- if (storage.seenThreads.indexOf(threadNumber) != -1)
- continue;
- if (ignoreAll){
- storage.seenThreads.push(threadNumber);
- continue;
- }
- tr.children[2].innerHTML = '<a href=https://forums.e-hentai.org/index.php?showtopic=' + threadNumber + ' target=_blank>' + threadTitle + '</a>' + (desc ? desc[0].outerHTML : '');
- tr.children[6].innerHTML = tr.children[6].children[0].innerHTML;
- var dateNode = tr.children[6].childNodes[0];
- var dateStr = dateNode.textContent;
- if (!/Today,\s\d/.test(dateStr) && !/Yesterday,\s\d/.test(dateStr))
- dateNode.textContent = dateStr.match(/\s([a-z]{3})/i)[1] + ' ' + dateStr.match(/^\d+/)[0] + ' ' + dateStr.match(/\d\d\d\d/)[0] + ', ' + dateStr.match(/\d+:\d+/)[0];
- tr.removeChild(tr.children[4]);
- tr.removeChild(tr.children[1]);
- tr.appendChild(document.createElement('td'));
- var button = tr.children[5].appendChild(document.createElement('button'));
- button.id = 'ignoreBtn';
- button.textContent = 'Ignore';
- [].forEach.call(tr.children, function(td){
- td.className = 'row2';
- });
- otherUnreadThreads.push(tr);
- table.insertBefore(tr, table.children[1]);
- }
- subforumIndex++;
- if (subforumIndex !== myForums.length){
- getForum();
- return;
- }
- saveStorage();
- document.getElementById('ucpcontent').style.backgroundColor = '#4286f4';
- if (ignoreAll) {
- window.location.href = window.location.href;
- }
- return;
- });
- }
- }
- function saveStorage(){
- localStorage.improvedControlPanel = JSON.stringify(storage);
- }
- function getTimeZone(){
- var s = '';
- if (/https/.exec(window.location.href))
- s = 's';
- get('https://forums.e-hentai.org/index.php?act=UserCP&CODE=04', function(data){
- storage = {'seenThreads': [], 'lastSubforumCheck': 0};
- var timeString = data.getElementsByTagName('fieldset')[0].querySelector('option[selected="selected"]').textContent;
- if (!/\d/.exec(timeString))
- storage.offset = 0;
- else
- storage.offset = parseInt(/[+-]/.exec(timeString) + '1') * (parseInt(/\d\d?(?=\:)/.exec(timeString)) * 60 + parseInt(/\d\d?(?=\s)/.exec(timeString)));
- storage.latestRead = {};
- [].forEach.call(document.querySelectorAll('a[href*="forums.e-hentai.org/index.php?act=ST"]'), function(a){
- var threadNumber = a.href.match(/&t=(\d+)/)[1];
- if (Object.keys(storage.latestRead).indexOf(threadNumber) == -1)
- storage.latestRead[threadNumber] = Date.now();
- });
- getSubforums(true);
- });
- }
- function get(url, done){
- var r = new XMLHttpRequest();
- r.open('GET', url, true);
- r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
- r.responseType = 'document';
- r.onload = function () {
- if (r.status >= 200 && r.status < 400){
- done(r.response);
- }
- };
- r.send();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement