Greasy Fork

Gota.io Skin Gallery

Just a simple script that helps you manage your skins.

目前为 2021-08-16 提交的版本。查看 最新版本

// ==UserScript==
// @name         Gota.io Skin Gallery
// @namespace    http://tampermonkey.net/
// @version      0.32
// @description  Just a simple script that helps you manage your skins.
// @author       Amy
// @match        https://skins.gota.io/skins
// @icon         https://skin-data.gota.io/e6e200b3-5e6d-406f-8ab6-0338f4ba09cf.png
// @resource     IMPORTED_CSS https://raw.githubusercontent.com/Aymayy/css-files/main/style.css
// @grant        GM_getResourceText
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';
    const my_css = GM_getResourceText("IMPORTED_CSS");
    GM_addStyle(my_css);
    const local__storage = window.localStorage;

    const defaultSkinSize = 250;
    const defaultCols = 5;
    const container = document.querySelector('.grid.grid-cols-4.gap-4');
    const containerOfContainer = document.querySelector('.px-8.py-3.border-t.border-gray-700');
    const nrCols = document.querySelector('.grid.grid-cols-4.gap-4');
    const names = container.querySelectorAll('.text-lg.font-bold');
    const skins = container.querySelectorAll('.flex.flex-col');
    const submit__button = document.querySelector('.button.is-primary');
    const computedNames = [];
    let gallery__skins = {};
    let gallery__skins__data = {};
    let searched__gallery__skins = {};
    let skinElements = {};
    let searchedSkins = {};
    let galleryState = false;
    let skin__code = '';


    //Create and Add and Remove DOM elements
    const containerHeader = document.querySelector('.flex.justify-between')
    const navbar = document.querySelector('nav');


    const removeElement = containerHeader.querySelector('.flex.items-center');
    removeElement.remove();

    const submit__button__parent = submit__button.parentElement;
    submit__button__parent.classList.add('submit__button__parent');


    const skinSliderString = `<div class="slider-container" style="display: flex; justify-content: space-between; align-items: center; width: 15rem;"><label>Size</label><input type="range" min="50" max="1000" value="${defaultSkinSize}" class="slider skinSlider" id="myRange"><span class="skinSpan">${defaultSkinSize}</span></div>`;
    const columsSliderString = `<div class="slider-container" style="display: flex; justify-content: space-between; align-items: center; width: 15rem;"><label>Cols</label><input type="range" min="1" max="25" value="${defaultCols}" class="slider colSlider" id="myRange"><span class="colSpan">${defaultCols}</span></div>`;
    const searchInputString = `<div class="form__group field"><input type="input" class="search__input form__field" autocapitalize="off" spellcheck="false" placeholder="Search" name="name" id='name' required /><label for="name" class="form__label">Search</label></div>`;
    const sortButtonString = `<button class="corner-button"><span>Sort</span></button>`;
    const galleryString = `<a class="gallery__icon__container flex items-center"><svg class="gallery__icon" height="30pt" viewBox="1 -47 511.999 511" width="30pt" xmlns="http://www.w3.org/2000/svg"><path d="m469.488281 84.417969h-4.390625c-2.570312-22.023438-20.292968-39.484375-42.441406-41.621094-2.542969-23.742187-22.683594-42.296875-47.085938-42.296875h-302.21875c-40.445312 0-73.351562 32.90625-73.351562 73.347656v211.902344c0 24.574219 18.804688 44.828125 42.773438 47.144531 2.515624 23.488281 22.261718 41.886719 46.3125 42.273438.0625 4.167969.714843 8.191406 1.898437 11.988281 5.386719 17.292969 21.550781 29.882812 40.59375 29.882812h337.910156c23.441407 0 42.511719-19.070312 42.511719-42.507812v-247.601562c0-23.441407-19.070312-42.511719-42.511719-42.511719zm22.511719 42.511719v163.738281l-43.5-32.859375c-11.886719-8.976563-27.960938-9.117188-40-.347656l-55.027344 40.09375-104.9375-108.1875c-12.5-12.890626-32.839844-13.683594-46.304687-1.800782l-93.160157 82.191406v-142.828124c0-12.414063 10.097657-22.511719 22.507813-22.511719h337.910156c12.414063 0 22.511719 10.097656 22.511719 22.511719zm0 247.597656c0 12.414062-10.097656 22.511718-22.507812 22.511718h-337.914063c-10.082031 0-18.640625-6.667968-21.492187-15.824218-.660157-2.113282-1.015626-4.359375-1.015626-6.683594v-78.105469l106.394532-93.863281c5.441406-4.804688 13.660156-4.484375 18.714844.726562l47.359374 48.828126c0 .003906 0 .003906.003907.003906l94.261719 97.183594c1.960937 2.023437 4.566406 3.039062 7.179687 3.039062 2.507813 0 5.019531-.9375 6.960937-2.820312 3.960938-3.847657 4.058594-10.175782.214844-14.140626l-22.625-23.328124 52.742188-38.425782c4.867187-3.546875 11.363281-3.492187 16.167968.136719l55.554688 41.964844zm-429.5-46.707032v-236.109374c0-1.003907.050781-2 .152344-2.976563 1.492187-14.675781 13.925781-26.164063 28.988281-26.164063h122.320313c5.523437 0 10-4.476562 10-10 0-5.523437-4.476563-10-10-10h-122.320313c-27.097656 0-49.140625 22.042969-49.140625 49.140626v220.976562c-12.777344-2.300781-22.5-13.503906-22.5-26.9375v-211.902344c0-29.414062 23.933594-53.347656 53.351562-53.347656h302.21875c13.273438 0 24.371094 9.503906 26.84375 22.070312h-108.453124c-5.523438 0-10 4.476563-10 10 0 5.523438 4.476562 10 10 10h118.96875.011718 5.128906c13.195313 0 24.242188 9.394532 26.800782 21.847657h-313.292969c-23.4375 0-42.507813 19.070312-42.507813 42.511719v164.976562.007812 63.253907c-14.722656-.417969-26.570312-12.523438-26.570312-27.347657zm0 0"></path><path d="m388.515625 145.117188c-23.601563 0-42.796875 19.199218-42.796875 42.792968 0 23.597656 19.199219 42.796875 42.796875 42.796875 23.59375 0 42.792969-19.199219 42.792969-42.796875 0-23.59375-19.199219-42.792968-42.792969-42.792968zm0 65.589843c-12.570313 0-22.796875-10.226562-22.796875-22.792969 0-12.570312 10.226562-22.796874 22.796875-22.796874 12.566406 0 22.792969 10.226562 22.792969 22.796874 0 12.566407-10.226563 22.792969-22.792969 22.792969zm0 0"></path><path d="m244.730469 56.398438c.25.601562.558593 1.179687.917969 1.722656.363281.546875.78125 1.058594 1.242187 1.519531.460937.457031.96875.878906 1.519531 1.25.539063.359375 1.128906.667969 1.730469.917969.597656.25 1.230469.441406 1.871094.570312.636719.128906 1.296875.191406 1.949219.191406.660156 0 1.308593-.0625 1.960937-.191406.636719-.128906 1.257813-.320312 1.867187-.570312.601563-.25 1.179688-.558594 1.722657-.917969.546875-.371094 1.058593-.792969 1.519531-1.25.46875-.460937.878906-.972656 1.25-1.519531.359375-.542969.667969-1.121094.917969-1.722656.25-.609376.441406-1.238282.570312-1.867188.128907-.652344.191407-1.3125.191407-1.960938 0-.652343-.0625-1.3125-.191407-1.949218-.128906-.640625-.320312-1.273438-.570312-1.871094-.25-.609375-.558594-1.191406-.917969-1.730469-.371094-.550781-.78125-1.058593-1.25-1.519531-.460938-.460938-.972656-.878906-1.519531-1.242188-.542969-.359374-1.121094-.667968-1.722657-.917968-.609374-.25-1.230468-.441406-1.867187-.570313-1.292969-.261719-2.621094-.261719-3.910156 0-.640625.128907-1.273438.320313-1.871094.570313-.601563.25-1.191406.558594-1.730469.917968-.550781.363282-1.058594.78125-1.519531 1.242188s-.878906.96875-1.242187 1.519531c-.359376.539063-.667969 1.121094-.917969 1.730469-.25.597656-.441407 1.230469-.570313 1.871094-.128906.636718-.199218 1.296875-.199218 1.949218 0 .648438.070312 1.308594.199218 1.960938.128906.628906.320313 1.257812.570313 1.867188zm0 0"></path></svg><h3 class="gallery__label text-lg leading-6 font-medium text-gray-200">Gallery</h3></a>`;
    const empty__container__string = `<div class="gallery__container grid grid-cols-4 gap-4"></div>`;
    const gallery__navbar__string = `<div class="gallery__navbar__container px-4 py-5 sm:px-6 flex justify-between "></div>`;
    const add__skin__button__string = `<div class="add__skin__button__container"><a class="add__skin__button button is-primary">Add Skin By Code</a></div>`;

    const skinSlider = document.createRange().createContextualFragment(skinSliderString);
    const columnSlider = document.createRange().createContextualFragment(columsSliderString);
    const searchInput = document.createRange().createContextualFragment(searchInputString);
    const sortButton = document.createRange().createContextualFragment(sortButtonString);
    const gallery = document.createRange().createContextualFragment(galleryString);

    const slidersContainer = document.createElement('div');
    slidersContainer.classList.add('sliders-container');
    slidersContainer.style = 'display: flex; justify-content: space-around; align-items: center; width: 40%';
    slidersContainer.appendChild(skinSlider);
    slidersContainer.appendChild(columnSlider);


    containerHeader.insertBefore(slidersContainer, containerHeader.children[0]);
    containerHeader.insertBefore(searchInput, containerHeader.children[0]);
    containerHeader.insertBefore(sortButton, containerHeader.children[0]);
    containerHeader.insertBefore(gallery, containerHeader.children[0]);

    //Initialize defaults
    (function() {
        const slider1 = document.querySelector('.skinSlider');
        const slider2 = document.querySelector('.colSlider');
        const searchInput = document.querySelector('.search__input');

        updateSkins();

        slider1.value = defaultSkinSize;
        slider2.value = defaultCols;
        const grid = document.querySelector('.grid.grid-cols-4.gap-4');
        grid.style.gridTemplateColumns = `repeat(${defaultCols},minmax(0,1fr))`;
        //Fix/custom some styling
        skins.forEach(skin => {
            const img = skin.querySelector('img');
            img.style.maxWidth = 'none';
            img.style.width = `${defaultSkinSize}px`;
            skin.style.justifyContent = 'center'
            skin.style.alignItems = 'center';
        });
    })();


    //Event Listeners
    document.querySelector('.gallery__icon__container').addEventListener('click', function (e) {
        galleryState = !galleryState;

        if(galleryState) {
            const empty__container = document.createRange().createContextualFragment(empty__container__string);
            //const gallery__navbar = document.createRange().createContextualFragment(gallery__navbar__string);
            const add__skin__button = document.createRange().createContextualFragment(add__skin__button__string);
            const gallery__text = document.querySelector('.gallery__label');
            gallery__text.innerText = 'My Skins';

            container.remove();

            //containerOfContainer.parentElement.insertBefore(gallery__navbar, containerOfContainer.parentElement.children[1]);
            containerOfContainer.appendChild(empty__container);
            submit__button__parent.remove();
            containerHeader.appendChild(add__skin__button);

            const grid = document.querySelector('.gallery__container');
            grid.style.gridTemplateColumns = `repeat(${defaultCols},minmax(0,1fr))`;

            //Add skins here
            update__gallery();

            document.querySelector('.add__skin__button').addEventListener('click', handle__click);
        }else {
            const gallery__text = document.querySelector('.gallery__label');
            gallery__text.innerText = 'Gallery';

            document.querySelector('.add__skin__button').removeEventListener("click", handle__click, false);
            document.querySelector('.add__skin__button__container').remove();
            containerHeader.appendChild(submit__button__parent);
            document.querySelector('.gallery__container').remove();
            containerOfContainer.appendChild(container);
        }
    });

    document.querySelector('.search__input').addEventListener('input', function (e) {
        if(galleryState === false) {
            updateSkins();
            searchedSkins = {};
            for(const element in skinElements) {
                if(element.includes(e.srcElement.value)) {
                    searchedSkins[element] = skinElements[element];
                }
            }
            removeSkins();
            insertSkins(container, searchedSkins);
        }else {
            const gallery__cont = document.querySelector('.gallery__container');
            searched__gallery__skins = {};
            for(const element in gallery__skins__data) {
                if(element.includes(e.srcElement.value)) {
                    searched__gallery__skins[element] = gallery__skins__data[element];
                }
            }
            removeSkins(true);
            insertSkins(gallery__cont, searched__gallery__skins, true);
        }
    }, false);

    document.querySelector('.corner-button').addEventListener('click', function (e) {
        const gallery__cont = document.querySelector('.gallery__container');
        if(galleryState && !isEmpty(searched__gallery__skins)){
            sortSkins(gallery__cont, searched__gallery__skins, true);
            //update__gallery();
        }else if(galleryState && isEmpty(searched__gallery__skins)){;
            sortSkins(gallery__cont, gallery__skins__data, true);
            //update__gallery();
        }else if(isEmpty(searchedSkins)) {
            sortSkins(container, skinElements);
        }else {
            sortSkins(container, searchedSkins);
        }
    });

    document.querySelector('.skinSlider').addEventListener('input', function (e) {
        const span = document.querySelector('.skinSpan');
        span.innerText = e.srcElement.value;
        if(galleryState === false) {
            skins.forEach(skin => {
                const img = skin.querySelector('img');
                img.style.width = `${e.srcElement.value}px`;
            });
        }else {
            const gallery__skins = document.querySelectorAll('.gallery__skin');
            gallery__skins.forEach(skin => {
                const img = skin.querySelector('img');
                img.style.width = `${e.srcElement.value}px`;
            });
        }
    }, false);

    document.querySelector('.colSlider').addEventListener('input', function (e) {
        const span = document.querySelector('.colSpan');
        span.innerText = e.srcElement.value;
        const grid = document.querySelector('.grid.grid-cols-4.gap-4');
        grid.style.gridTemplateColumns = `repeat(${e.srcElement.value},minmax(0,1fr))`;
    }, false);


    //Remove the annoying logo
    const containerSize = document.querySelector('.container.flex.flex-col.items-center.justify-center.mx-auto');
    containerSize.firstElementChild.remove();

    containerSize.firstElementChild.style.width = '100%';




    //                        ⬇------⬇ Functions ⬇------⬇

    function sortSkins(cont, elem, gal = false) {
        updateSkins(gal);
        elem = sortSkinElements(elem);
        removeSkins(gal);
        insertSkins(cont, elem, gal);
    };
    //Sort object
    function sortSkinElements(elems) {
        elems = sortObject(elems);
        return elems;
    }
    //Update skins object
    function updateSkins(gal = false) {
        if(gal) {
            return 0;
        }else{
            skinElements = {};
            for(let i = 0; i < names.length; i++) {
                skinElements[names[i].outerText] = skins[i];
            }
        }
    };
    //Remove skins from DOM
    function removeSkins(gal = false) {
        if(gal) {
            const gal__container = document.querySelector('.gallery__container');
            gal__container.innerHTML = '';
        }else {
            for(let i = 0; i < names.length; i++) {
                skins[i].remove();
            }
        }
    };
    //Insert skins in DOM
    function insertSkins(cont, elements, gal = false) {
        if(gal === false) {
            for(const element in elements) {
                cont.appendChild(elements[element]);
            }
        }else {
            for(const element in elements) {
                const skin__template__string = `<div class="gallery__skin flex flex-col" style="justify-content: center; align-items: center;"><a href="/skins/${elements[element]}"><img class="rounded-full" src="https://skin-data.gota.io/${elements[element]}.png" style="max-width: none; width: 250px;"></a><div class="inline-flex justify-center items-center"><span class="text-lg font-bold">${element}</span></div></div>`;
                const skin__template = document.createRange().createContextualFragment(skin__template__string);
                cont.appendChild(skin__template);
            }
        }
    }

    function sortObject(o) {
        var sorted = {},
            key, a = [];

        for (key in o) {
            if (o.hasOwnProperty(key)) {
                a.push(key);
            }
        }

        a.sort();

        for (key = 0; key < a.length; key++) {
            sorted[a[key]] = o[a[key]];
        }
        return sorted;
    }
    function isEmpty(obj) {
        for(var prop in obj) {
            if(obj.hasOwnProperty(prop)) {
                return false;
            }
        }

        return true;
    }
    function handle__click(e) {
        skin__code = prompt("Enter skin code:\nHere you find how to get code for a skin:\nhttps://github.com/Aymayy/css-files", "");
        if(skin__code === null || skin__code === '') {
            console.log("Cancelled");
            return 0;
        }else {
            handle__request(skin__code);
        }
    }

    async function handle__request(code) {
        const url = `https://skins.gota.io/skins/${code.toString()}`;

        let is__valid = false;
        is__valid = await fetch(url, {method: "GET"}).then(data => {if(data.status === 200) {return true;}else if(data.status === 400) {return false}} ).catch(err => {return false;})

        if(is__valid) {
            const requet__string = httpGetAsync(url, getHtml);
        } else {
            alert("Invalid Skin Code!");
        }


    }
    function httpGetAsync(theUrl, callback) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                callback(xmlHttp.responseText);
            }
        }
        xmlHttp.open("GET", theUrl, true); // true for asynchronous
        xmlHttp.send(null);
    }
    function getHtml(dom){
        const DOM = dom.toString();
        const request = document.createRange().createContextualFragment(DOM);
        const skin__name = request.querySelector('dd.mt-1.text-sm.text-gray-300').innerText;
        add__skin__to__gallery({
            name: skin__name.trim(),
            code: skin__code
        })
    }

     function add__skin__to__gallery(skin) {
         if(local__storage.getItem('__skins')) {
             gallery__skins__data = JSON.parse(local__storage.getItem('__skins'));
         }
         if(gallery__skins__data.hasOwnProperty(skin.name)) {
             alert('Skin already saved!');
             return 0;
         }
         gallery__skins__data[skin.name] = skin.code;
         update__local__storage();
         update__gallery();
     }
    function update__gallery() {
         if(local__storage.getItem('__skins')) {
             gallery__skins__data = JSON.parse(local__storage.getItem('__skins'));
         }
        const gal__container = document.querySelector('.gallery__container');
        gal__container.innerHTML = '';
        for(const skin in gallery__skins__data) {
            const skin__template__string = `<div class="gallery__skin flex flex-col" style="justify-content: center; align-items: center;"><a href="/skins/${gallery__skins__data[skin]}"><img class="rounded-full" src="https://skin-data.gota.io/${gallery__skins__data[skin]}.png" style="max-width: none; width: 250px;"></a><div class="inline-flex justify-center items-center"><span class="text-lg font-bold">${skin}</span></div></div>`;
            const skin__template = document.createRange().createContextualFragment(skin__template__string);
            document.querySelector('.gallery__container').appendChild(skin__template);
        }

    }
    function update__local__storage() {
         local__storage.setItem('__skins', JSON.stringify(gallery__skins__data));
    }
    function get__gallery__skins__DOMElement() {
        skins
    }

})();