Greasy Fork is available in English.

See unfollows [neocities.org]

See people who unfollowed you. Also shows when people change their site name.

Zainstaluj skrypt?
Skrypt zaproponowany przez autora

Może Ci się również spodobać. Views/Follow Ratio [neocities.org]

Zainstaluj skrypt
// ==UserScript==
// @name         See unfollows [neocities.org]
// @namespace    http://tampermonkey.net/
// @version      1.8.3
// @description  See people who unfollowed you. Also shows when people change their site name.
// @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
// ==/UserScript==

(async () => {
    let mySite = document.querySelector(".dropdown-menu > li > a[href^='/site/']").href.split('neocities.org/site/')[1];
    if(location.pathname.startsWith('/site/')) {
        let currentLocation = location.pathname.slice(6).split("?")[0].split("#")[0];
        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 ?? '1 second ago') }));
        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';
    }
    async function getCurrentFollowers() {
        const followerPage = await fetch(`https://neocities.org/site/${mySite}/followers`).then(res => res.text());
        try {
            const parser = new DOMParser();
            const doc = parser.parseFromString(followerPage, "text/html");
            return Array.from(doc.querySelectorAll('.username > a')).map(u => u.innerText.replace(/\n/g, '').trim()).filter(u => !u.includes('/'));
        } catch(e) {
            console.error('error getting followers', e);
            console.log(followerPage);
        }
        return [];
    }

    let currentFollowers = await getCurrentFollowers();
    if(currentFollowers.length === 0) return;

    let previousFollowers = localStorage.followings ? JSON.parse(localStorage.followings) : [];
    let newUnfollows = previousFollowers.filter(e => !currentFollowers.includes(e));
    let unfollows = localStorage.unfollows ? JSON.parse(localStorage.unfollows) : [];
    let renamed;
    let notifCount = document.getElementsByClassName("notification-value")[0];
    if(newUnfollows.length === 1 && currentFollowers.length === previousFollowers.length && !notifCount) {
        renamed = currentFollowers.find(f => !previousFollowers.includes(f));
    }

    for (let i in newUnfollows) {
        unfollows.push([newUnfollows[i], Date.now(), !(await fetch(`https://neocities.org/site/${newUnfollows[i]}`, {redirect: 'manual'})).ok, renamed]);
    }
    unfollows = unfollows.filter(u => !currentFollowers.includes(u[0]));

    localStorage.unfollows = JSON.stringify(unfollows);
    localStorage.followings = JSON.stringify(currentFollowers);

    unfollows = unfollows.reverse();
    for (let i in unfollows) {
        let [nick, date, disabledProfile, renamed] = unfollows[i];
        let el = findBetween(date);
        if (el) {
            let unfollowElement = document.createElement('div');
            unfollowElement.className = 'news-item unfollow';
            unfollowElement.innerHTML = /*html*/`
        <div class="title">
            <div class="icon"><a href="/site/${nick}" title="${nick}" class="avatar" style="background-image: url(/site_screenshots/21/90/${nick}/index.html.50x50.jpg);"></a></div>
            <div class="text">
                <a href="/site/${nick}" class="user">${nick}</a> ${renamed ? `renamed to <a href="/site/${renamed}" class="user">${renamed}</a>` : disabledProfile ? 'disabled profile.' : 'unfollowed you!'}
            </div>
            <a class="date" style="color:#aaa" href="https://greasyfork.org/en/scripts/450226-see-unfollows-neocities-org" target="_blank">detected ${relativeTime(new Date(date))}</a>
        </div>`;
            el.before(unfollowElement);
        }
    }
})();