coomer-optimizer

Improving coomer.party

ของเมื่อวันที่ 18-08-2023 ดู เวอร์ชันล่าสุด

// ==UserScript==
// @name         coomer-optimizer
// @namespace    https://coomer.party/
// @version      2.0
// @description  Improving coomer.party
// @match        https://coomer.party/*
// @grant        GM_addStyle
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Add the margin using CSS
    GM_addStyle('div.card-list__items { margin-right: 500px; }');
    GM_addStyle('.user-card--dislike {border-color: hsl(0deg 100% 50%); border-style: solid; border-width: 2px; }');

    const key = function(_usr) {
        return `copt_${_usr}`;
    }

    const userURLMatch = window.location.pathname.match(/\/user\/([^/]+)$/);
    const pageUser = userURLMatch ? userURLMatch[1] : false;
    if (pageUser) {
        console.debug("User page detected");
    }


    let userCardsPage = document.querySelector('a.user-card') !== null;
    if (userCardsPage) {
        console.debug("User list page detected");
    }


    if (pageUser) {
        GM_addStyle('span.user-header__dislike-icon::before { content: "\uD83D\uDC4E"; }');

        let pageUserKey = key(pageUser);

        let summary = localStorage.getItem(pageUserKey);
        const today = new Date().toISOString().split('T')[0]; // Get the current date in ISO format
        let is_new = false;

        if (!summary) {
            summary = { visits: 0, lastVisit: today, disliked: false };
            is_new = true;
        } else {
            summary = JSON.parse(summary);
        }

        if (is_new || summary.lastVisit !== today) {
            summary.visits += 1;
            summary.lastVisit = today;
            localStorage.setItem(pageUserKey, JSON.stringify(summary));
        }

        console.log(`user ${pageUser}`, summary);

        const summaryDiv = document.createElement('div');
        summaryDiv.className = 'user-header__actions';
        summaryDiv.innerHTML = `<h6>Visited ${summary.visits} times, last visit on ${summary.lastVisit}</h6>`;

        const user_actions = document.querySelector('div.user-header__actions');
        user_actions.parentNode.insertBefore(summaryDiv, user_actions);

        let dislikeButton = document.createElement('button');
        dislikeButton.type = 'button';
        dislikeButton.className = 'user-header__favourite';

        let iconElement = document.createElement('span');
        iconElement.className = 'user-header__fav-icon'
        iconElement.textContent = summary.disliked ? '👍🏻' : '👎';
        dislikeButton.appendChild(iconElement);

        let textElement = document.createElement('span');
        textElement.className = 'user-header__fav-text';
        textElement.textContent = summary.disliked ? 'Un-dislike' : 'Dislike';
        dislikeButton.appendChild(textElement);
        dislikeButton.addEventListener('click', () => {
            summary.disliked = !summary.disliked;
            localStorage.setItem(pageUserKey, JSON.stringify(summary));
            iconElement.textContent = summary.disliked ? '👍🏻' : '👎';
            textElement.textContent = summary.disliked ? 'Un-dislike' : 'Dislike';
        });

        user_actions.appendChild(dislikeButton);
    }

    // bottom header repeater
    let navMenu = document.querySelector('nav.post__nav-links');
    let bottomHeader = document.querySelector('footer.post__footer > h2.site-section__subheading');

    if (navMenu && bottomHeader) {
        bottomHeader.parentNode.insertBefore(navMenu.cloneNode(true), bottomHeader);
    }

    let enrichUserCard = function(c) {
        let m = c.href.match(/user\/([^\/]+)/);
        if (m) {
            let userKey = key(m[1]);
            let summary = JSON.parse(localStorage.getItem(userKey));
            if (summary) {
                c.className += ' co-parsed';

                let serviceLabel = c.querySelector('span.user-card__service');
                let visitedLabel = serviceLabel.cloneNode(true);
                visitedLabel.textContent = `# ${summary.visits}`;
                visitedLabel.style.marginLeft = '4px';
                visitedLabel.style.backgroundColor = 'rgb(240, 140, 207)';
                serviceLabel.insertAdjacentElement('afterend', visitedLabel);

                if (summary.disliked) {
                    c.className += ' user-card--dislike';
                }
            } else {
                console.debug(`No enrichment for user ${m[1]}`);
            }
        }
    }


    // check if there is at least 1 user card --> list pages
    if (document.querySelector('a.user-card')) {
        console.debug('Initializing observer');

        // Callback function for the MutationObserver
        function mutationCallback(mutationsList, observer) {
            for (const mutation of mutationsList) {
                if (mutation.type === 'childList') {
                    // Process newly added user cards
                    mutation.addedNodes.forEach(node => {
                        if (node.tagName === 'A'
                            && node.classList.contains('user-card')
                            && !node.classList.contains('co-parsed')) {
                            enrichUserCard(node);
                        }
                    });
                }
            }
        }

        // Create a MutationObserver to watch for changes in the DOM
        const observer = new MutationObserver(mutationCallback);

        // Define the options for the observer
        const observerOptions = {
            childList: true,
            subtree: true
        };

        // Start observing the document body for changes
        observer.observe(document.body, observerOptions);
    } else {
        console.debug('No user cards page identified');
    }
})();