TabunAva Reborn

Установка своего аватара на Табуне!

目前為 2021-11-18 提交的版本,檢視 最新版本

// ==UserScript==
// @name         TabunAva Reborn
// @namespace    http://tampermonkey.net/
// @version      0.3.1
// @description  Установка своего аватара на Табуне!
// @author       ( IntelRug && ( Kujivunia || Niko_de_Andjelo ) )
// @match        https://tabun.everypony.ru/*
// @grant        none
// @license MIT
// ==/UserScript==
// Я не умею писать скрипты, поэтому "TabunAva" начиная с версии 0.3 была полностью переписана IntelRug
//IDENTICON: https://avatars.dicebear.com/styles/identicon
const avaPostLinkGettingThere = 'https://raw.githubusercontent.com/Kujivunia/TabunAva-Reborn/main/AvaPostLink';
const defaultAvaPostLink = 'https://tabun.everypony.ru/blog/uniblog/203681.html';
const everyponyCdnStorageRegex = /(https?:)?\/\/cdn\.everypony\.ru\/storage\//;
const everyponyCdnStorageLink = '//cdn.everypony.ru/storage/';

let avaDictionary = {};

//Загрузка ссылки на пост с аватарами
function getLinkToAvatarsDocument(){
    return fetch(avaPostLinkGettingThere)
        .then((response) => {
        if (response.ok) {
            return response.text();
        }
        else {
            return defaultAvaPostLink;
        }
    })
        .then((text) => {
        let avaPostLink = text;
        return avaPostLink || defaultAvaPostLink;
    });
}

function getAvatarsDocument() {
    return getLinkToAvatarsDocument()
        .then((link) => {
        return fetch(link)
            .then((response) => {
            return response.text();
        })
            .then((text) => {
            let domParser = new DOMParser();
            return domParser.parseFromString(text, "text/html");
        })});
}

function fillAvatarsDictionary(avaDocument) {
    const commentNodes = avaDocument.querySelectorAll('#comments .comment');

    commentNodes.forEach((commentNode) => {
        const authorNode = commentNode.querySelector('.comment-author');
        const username = authorNode && authorNode.textContent.trim();
        if (!username) return;

        const contentNode = commentNode.querySelector('.comment-content');
        const imageNode = contentNode && contentNode.querySelector('.text > img');

        if (imageNode && imageNode.hasAttribute('src')) {
            avaDictionary[username] = imageNode
                .getAttribute('src')
                .replace(everyponyCdnStorageRegex, ''); // Сокращаем количество сохраняемых символов
        }
    });
}

// Сохранить список аватаров в локальное хранилище браузера
function saveAvatarsDictionary() {
    const jsonString = JSON.stringify(avaDictionary);
    localStorage.setItem('TabunAvaReborn_Avatars', jsonString);
    localStorage.setItem('TabunAvaReborn_LastUpdate', Date.now().toString());
}

function refreshAvatarsStorage() {
    return getAvatarsDocument()
        .then((avaDocument) => {
        fillAvatarsDictionary(avaDocument);
        saveAvatarsDictionary();
    });
}

function shouldUpdateAvatarsStorage() {
    const lastUpdate = +(localStorage.getItem('TabunAvaReborn_LastUpdate') || '0');
    return (Date.now() - lastUpdate) > 1000 * 60 * 10; // прошло больше 10 минут с последнего обновления
}

// Достать список аватаров из локального хранилища браузера или обновить из поста
function loadAvatarsDictionary() {
    if (shouldUpdateAvatarsStorage()) {
        return refreshAvatarsStorage();
    } else {
        const jsonString = localStorage.getItem('TabunAvaReborn_Avatars');
        if (jsonString) {
            try {
                avaDictionary = JSON.parse(jsonString);
                return Promise.resolve();
            } catch(e) {
                return refreshAvatarsStorage();
            }
        }
    }
}

function isDefaultAvatar(link) {
    return /(\/local\/avatar_male_)/.test(link) || /(\/local\/avatar_female)/.test(link);
}

function getIdenticonAvatar(username) {
   return 'https://avatars.dicebear.com/api/identicon/' + username + '.svg?scale=100&size=48';
}

function getNewTabunAvatar(username) {
    if (avaDictionary[username]) {
        return everyponyCdnStorageLink + avaDictionary[username];
    }
    return false;
}

function replaceAvatarInImageNode(imageNode, username) {
    if (getNewTabunAvatar(username)) {
        imageNode.setAttribute('src', getNewTabunAvatar(username));
    } else if (
        !imageNode.getAttribute('src')
        || isDefaultAvatar(imageNode.getAttribute('src'))
    ) {
        imageNode.setAttribute('src', getIdenticonAvatar(username));
    }
}

// Замена собственного аватара пользователя в шапке страницы
function replaceHeaderAvatar() {
    const imageNode = document.querySelector('#dropdown-user img');
    if (!imageNode) return;

    const usernameNode = document.querySelector("#dropdown-user .username");
    const username = usernameNode && usernameNode.textContent.trim();
    if (!username) return;

    replaceAvatarInImageNode(imageNode, username);
}

// Замена аватара пользователя в профиле
function replaceProfileAvatar() {
    const imageNode = document.querySelector('.profile-info-about img');
    if (!imageNode) return;

    const usernameNode = document.querySelector(".profile [itemprop=nickname]");
    const username = usernameNode && usernameNode.textContent.trim();
    if (!username) return;

    replaceAvatarInImageNode(imageNode, username);
}

// Замена аватара друзей в профиле
function replaceProfileFriendAvatars() {
    const userNodes = document.querySelectorAll('.user-list-avatar > *');
    userNodes.forEach((userNode) => {
        const imageNode = userNode.querySelector('img');
        if (!imageNode) return;

        const username = userNode.textContent.trim();
        if (!username) return;

        imageNode.width = 48;
        imageNode.height = 48;

        replaceAvatarInImageNode(imageNode, username);
    });
}

// Замена аватара автора поста
function replaceTopicAuthorAvatars() {
    const topicNodes = document.querySelectorAll('.topic');
    topicNodes.forEach((topicNode) => {
        const imageNode = topicNode.querySelector('.avatar');
        if (!imageNode) return;

        const usernameNode = document.querySelector("[rel=author]");
        const username = usernameNode && usernameNode.textContent.trim();
        if (!username) return;

        replaceAvatarInImageNode(imageNode, username);
    });
}

// Замена аватаров в комментариях
function replaceCommentAvatars() {
    const commentNodes = document.querySelectorAll('#comments .comment');
    commentNodes.forEach((commentNode) => {
        const authorNode = commentNode.querySelector('.comment-author');
        const username = authorNode && authorNode.textContent.trim();
        if (!username) return;

        const imageNode = authorNode && authorNode.querySelector('img');
        if (!imageNode) return;

        replaceAvatarInImageNode(imageNode, username);
    });
}

// Замена аватаров в ленте активности
function replaceStreamAvatars() {
    const streamNodes = document.querySelectorAll('.stream-item');
    streamNodes.forEach((streamNode) => {
        const authorNode = streamNode.querySelector('.info a');
        const username = authorNode && authorNode.textContent.trim();
        if (!username) return;

        const imageNode = streamNode.querySelector('img');
        if (!imageNode) return;

        replaceAvatarInImageNode(imageNode, username);
    });
}

// Замена аватаров в разделе "Брони"
function replacePeopleAvatars() {
    const userNodes = document.querySelectorAll('.table-users .cell-name');
    userNodes.forEach((userNode) => {
        const authorNode = userNode.querySelector('.username');
        const username = authorNode && authorNode.textContent.trim();
        if (!username) return;

        const imageNode = userNode.querySelector('img');
        if (!imageNode) return;

        imageNode.width = 48;
        imageNode.height = 48;

        replaceAvatarInImageNode(imageNode, username);
    });
}

// Замена аватаров в блоке "Пожертвования"
function replaceDonationAvatars() {
    const userNodes = document.querySelectorAll('.donation-list > *');
    userNodes.forEach((userNode) => {
        const username = userNode.textContent.trim();
        if (!username) return;

        const imageNode = userNode.querySelector('img');
        if (!imageNode) return;

        imageNode.width = 24;
        imageNode.height = 24;

        replaceAvatarInImageNode(imageNode, username);
    });
}

function replaceAvatarsOnCommentsRefresh() {
    const countCommentsNode = document.querySelector('#count-comments');
    if (!countCommentsNode) return;

    countCommentsNode.addEventListener('DOMSubtreeModified', () => {
        replaceCommentAvatars();
    });
}


loadAvatarsDictionary()
    .then(() => {
    replaceAvatarsOnCommentsRefresh();

    replaceHeaderAvatar();
    replaceCommentAvatars();
    replaceTopicAuthorAvatars();
    replaceProfileAvatar();
    replaceProfileFriendAvatars();
    replaceStreamAvatars();
    replacePeopleAvatars();
    replaceDonationAvatars();
});