// ==UserScript== // @name See unfollows [neocities.org] // @namespace http://tampermonkey.net/ // @version 1.6 // @description See people who unfollowed you // @author https://neocities.org/site/dimden // @match https://neocities.org/ // @match https://neocities.org/?page=* // @match https://neocities.org/site/* // @icon https://www.google.com/s2/favicons?sz=64&domain=neocities.org // @grant none // @run-at document-end // @license MIT // @downloadURL none // ==/UserScript== (async () => { if(location.pathname.startsWith('/site/')) { let currentLocation = location.pathname.slice(6).split("?")[0].split("#")[0]; let mySite = document.querySelector(".dropdown-menu > li > a[href^='/site/']").href.split('neocities.org/site/')[1]; if(currentLocation !== mySite) return; } function getDateFromTimeAgo(timeString) { const timeAgo = { hours: 0, minutes: 0, seconds: 0, days: 0, weeks: 0, months: 0, years: 0 }; const secondsAgoMatches = timeString.match(/^(\d+) (seconds? ago)/); const minutesAgoMatches = timeString.match(/^(\d+) (minutes? ago)/); const hoursAgoMatches = timeString.match(/^(\d+) (hours? ago)/); const daysAgoMatches = timeString.match(/^(\d+) (days? ago)/); const weeksAgoMatches = timeString.match(/^(\d+) (weeks? ago)/); const monthsAgoMatches = timeString.match(/^(\d+) (months? ago)/); const yearsAgoMatches = timeString.match(/^(\d+) (years? ago)/); if (secondsAgoMatches) { timeAgo.seconds = secondsAgoMatches[1]; } if (minutesAgoMatches) { timeAgo.minutes = minutesAgoMatches[1]; } if (hoursAgoMatches) { timeAgo.hours = hoursAgoMatches[1]; } if (daysAgoMatches) { timeAgo.days = daysAgoMatches[1]; } if (weeksAgoMatches) { timeAgo.weeks = weeksAgoMatches[1]; } if (monthsAgoMatches) { timeAgo.months = monthsAgoMatches[1]; } if (yearsAgoMatches) { timeAgo.years = yearsAgoMatches[1]; } let d = Date.now(); d -= timeAgo.seconds * 1000; d -= timeAgo.minutes * 60 * 1000; d -= timeAgo.hours * 60 * 60 * 1000; d -= timeAgo.days * 24 * 60 * 60 * 1000; d -= timeAgo.weeks * 7 * 24 * 60 * 60 * 1000; d -= timeAgo.months * 30 * 24 * 60 * 60 * 1000; d -= timeAgo.years * 365 * 24 * 60 * 60 * 1000; return d; } function findBetween(date) { let news = Array.from(document.getElementsByClassName('news-item')).map(e => ({ el: e, time: getDateFromTimeAgo(e.getElementsByClassName('date')[0].innerText) })); for (let i = 0; i < news.length; i++) { if (news[i].time < date && Math.abs(news[i].time-date) < 8.82e+7) { return news[i].el; } } } const relativeTimePeriods = [ [31536000, 'year'], [2419200, 'month'], [604800, 'week'], [86400, 'day'], [3600, 'hour'], [60, 'minute'], [1, 'second'] ]; function relativeTime(date) { if (!(date instanceof Date)) date = new Date(date * 1000); const seconds = (new Date() - date) / 1000; for (let [secondsPer, name] of relativeTimePeriods) { if (seconds >= secondsPer) { const amount = Math.floor(seconds / secondsPer); return `${amount} ${name}${amount && amount !== 1 ? 's' : ''} ago`; } } return 'just now'; } let currentFollowings = Array.from(document.getElementsByClassName('follower-list')[0].children).filter(e => e.tagName === "A").map(e => e.href.split('neocities.org/site/')[1]); let previousFollowings = localStorage.followings ? JSON.parse(localStorage.followings) : []; let newUnfollows = previousFollowings.filter(e => !currentFollowings.includes(e)); let unfollows = localStorage.unfollows ? JSON.parse(localStorage.unfollows) : []; for (let i in newUnfollows) { unfollows.push([newUnfollows[i], Date.now(), !(await fetch(`https://neocities.org/site/${newUnfollows[i]}`, {redirect: 'manual'})).ok]); } unfollows = unfollows.filter(u => !currentFollowings.includes(u[0])); localStorage.unfollows = JSON.stringify(unfollows); localStorage.followings = JSON.stringify(currentFollowings); for (let i in unfollows) { let [nick, date, disabledProfile] = unfollows[i]; let el = findBetween(date); if (el) { let unfollowElement = document.createElement('div'); unfollowElement.className = 'news-item unfollow'; unfollowElement.innerHTML = /*html*/`
${nick} ${disabledProfile ? 'disabled profile.' : 'unfollowed you!'}
detected ${relativeTime(new Date(date))}
`; el.before(unfollowElement); } } })();