Gmail Sender Icons

Quickly identify the sender of email messages in Gmail without opening the message.

2024-08-21 기준 버전입니다. 최신 버전을 확인하세요.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name           Gmail Sender Icons
// @name:es        Gmail Iconos de Remitente
// @namespace      http://tampermonkey.net/
// @version        1.1
// @description    Quickly identify the sender of email messages in Gmail without opening the message.
// @description:es Identifica rápidamente al remitente de los mensajes de correo en Gmail sin abrir el mensaje.
// @author         IgnaV
// @match          https://mail.google.com/*
// @icon           https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico
// @license        MIT
// @grant          GM_setValue
// @grant          GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    const userId = window.location.href.match(/\/u\/(\d+)\//)[1];

    const addIcon = GM_getValue('addIcon', true);
    const addDomain = GM_getValue('addDomain', true);
    const allowedCommonDomains = GM_getValue('allowedDomains', []);
    const allowedUserDomains = GM_getValue('allowedUserDomains', {});

    const userDomains = allowedUserDomains[userId] || [];
    allowedUserDomains[userId] = userDomains;

    GM_setValue('addIcon', addIcon);
    GM_setValue('addDomain', addDomain);
    GM_setValue('allowedUserDomains', allowedUserDomains);


    const allowedDomains = allowedCommonDomains.concat(userDomains);
    const hasDomains = allowedDomains.length !== 0;


    if (!addIcon && !addDomain && !hasDomains) return;

    const processedElements = new Set();

    function addDomainContainer(element, domain) {
        const domainContainer = document.createElement('div');
        domainContainer.className = 'domain-container';

        addIconToContainer(domainContainer, domain);
        addDomainToContainer(domainContainer, domain);
        element.appendChild(domainContainer);
    }

    function addIconToContainer(domainContainer, domain) {
        const icon = document.createElement('img');
        icon.src = `https://www.google.com/s2/favicons?domain=${domain}`;
        icon.className = 'domain-icon';
        domainContainer.appendChild(icon);
    }

    function addDomainToContainer(domainContainer, domain) {
        const domainSpan = document.createElement('span');
        domainSpan.className = 'domain-text';
        domainSpan.textContent = domain;
        domainContainer.appendChild(domainSpan);
    }

    function markUnknownDomain(emailElement, domain) {
        if (!allowedDomains.includes(domain)) {
            emailElement.classList.add('not-allowed-domain');
        }
    }

    if (!addIcon && !addDomain) {
        addDomainContainer = function() {};
    }

    if (!addIcon) {
        addIconToContainer = function() {};
    }

    if (!addDomain) {
        addDomainToContainer = function() {};
    }

    if (!hasDomains) {
        markUnknownDomain = function() {};
    }

    function addStyles(addIcon, addDomain, hasDomains) {
        const style = document.createElement('style');
        style.type = 'text/css';
        let css = ``;
        if (addIcon || addDomain) {
            css += `
                .bA4 {
                    padding-top: 9px;
                }
                .domain-container {
                    display: flex;
                    align-items: center;
                    margin-top: -4px;
                    font-size: 10px;
                    color: #888;
                    width: fit-content;
                    height: 11px;
                    padding: 1px 2px;
                }
            `;
        }
        if (addIcon) {
            css += `
                .domain-icon {
                    width: 10px;
                    height: 10px;
                    margin-right: 3px;
                }
            `;
        }
        if (addDomain) {
            css += `
                .domain-text {
                    white-space: nowrap;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    font-size: 10px;
                    color: #888;
                }
            `;
        }
        if (hasDomains) {
            css += `
                .not-allowed-domain {
                    background-color: #f8d7da;
                    color: #721c24;
                    border-radius: 3px;
                }
            `;
        }
        style.appendChild(document.createTextNode(css));
        document.head.appendChild(style);
    }

    function addDomainBelowName() {
        const nameElements = document.querySelectorAll('.bA4');

        nameElements.forEach((element) => {
            if (processedElements.has(element)) return;

            const emailElement = element.querySelector('[email]');
            if (!emailElement) return;

            const email = emailElement.getAttribute('email');
            const domain = email.split('@')[1].split('.').slice(-2).join('.');

            addDomainContainer(element, domain);

            markUnknownDomain(emailElement, domain);

            processedElements.add(element);
        });
    }

    addStyles(addIcon, addDomain, hasDomains);

    const observer = new MutationObserver((mutations) => {
        mutations.forEach(() => {
            addDomainBelowName();
        });
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    window.addEventListener('load', addDomainBelowName);
})();