Greasy Fork is available in English.

Bilibili Comment UID Reader

Read UIDs from Bilibili comments

// ==UserScript==
// @name         Bilibili Comment UID Reader
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Read UIDs from Bilibili comments
// @author       You
// @match        *https://www.bilibili.com/video*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
const sidebarCss = `
#customSidebar {
    position: fixed;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    z-index: 1000;
    background-color: white;
    padding: 10px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    display: flex;
    flex-direction: column;
}
`;

const styleElement = document.createElement('style');
styleElement.type = 'text/css';
styleElement.appendChild(document.createTextNode(sidebarCss));
document.head.appendChild(styleElement);

const sidebar = document.createElement('div');
sidebar.id = 'customSidebar';
document.body.appendChild(sidebar);

const displayUsersBtn = document.createElement('button');
displayUsersBtn.innerText = '显示所有用户及其组别';
displayUsersBtn.onclick = displayAllUsersAndGroups;
sidebar.appendChild(displayUsersBtn);
sidebar.appendChild(document.createElement('br')); 

const clearGroupsBtn = document.createElement('button');
clearGroupsBtn.innerText = '清除所有组';
clearGroupsBtn.onclick = function() { clearSpecificGroup(null); };
sidebar.appendChild(clearGroupsBtn);
sidebar.appendChild(document.createElement('br'));

const clearAllBtn = document.createElement('button');
clearAllBtn.innerText = '完全清除';
clearAllBtn.onclick = clearAllData;
sidebar.appendChild(clearAllBtn);
    const observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        mutation.addedNodes.forEach(function(node) {
            if (node.nodeType === 1 && node.classList.contains('user-info')) {
                addSpecialAttentionButton(node.querySelector('.user-name'));
            }
            else if (node.nodeType === 1) {
const userInfoElements = node.querySelectorAll('.user-info .user-name');
userInfoElements.forEach(userInfoElement => {
    const userId = userInfoElement.getAttribute('data-user-id');
    const userName = userInfoElement.textContent;
    addSpecialAttentionButton(userInfoElement, userId, userName);
});
            }
        });
    });
});

observer.observe(document.body, { childList: true, subtree: true });
    function addSpecialAttentionButton(userInfoElement, userId, userName) {
    const { currentGroupName } = getUserCurrentGroup(userId);

    let groupIndicator;
    if (currentGroupName) {
        groupIndicator = document.createElement('span');
        groupIndicator.textContent = `组别: ${currentGroupName}`;
        groupIndicator.style.border = '1px solid black';
        groupIndicator.style.padding = '2px';
        userInfoElement.parentNode.insertBefore(groupIndicator, userInfoElement.nextSibling);
    }
    const buttonText = currentGroupName ? '更改关注组' : '特别关注';
    const specialAttentionButton = document.createElement('button');
    specialAttentionButton.textContent = buttonText;
    userInfoElement.parentNode.appendChild(specialAttentionButton);

    specialAttentionButton.addEventListener('click', function() {
const groupSelect = document.getElementById('group-select-' + userId);
        if (groupSelect && groupSelect.style.display !== 'none') {
            const groupName = groupSelect.value;
            if (groupName) {
                addUserToGroup(userId, userName, groupName);
                groupSelect.style.display = 'none';
                document.getElementById('new-group-input-' + userId).style.display = 'none';
                document.getElementById('add-group-btn-' + userId).style.display = 'none';
            } else {
                alert('请选择一个组,或创建一个新组!');
            }
        } else {
            showGroupSelect(userInfoElement, userId, userName);
        }
        if (groupIndicator) {
            groupIndicator.textContent = `组别: ${groupSelect.value}`;
        }
    });
}
function getUserCurrentGroup(userId) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    for (const [groupName, users] of Object.entries(groups)) {
        const userInGroup = users.find(user => user.userId === userId);
        if (userInGroup) {
            return { currentGroupName: groupName };
        }
    }
    return { currentGroupName: null };
}

function updateGroupSelect(select) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    select.innerHTML = '<option value="">请选择一个组...</option>';
    select.innerHTML += '<option value="无组别">无组别</option>';

    Object.keys(groups).forEach(groupName => {
        const option = document.createElement('option');
        option.value = groupName;
        option.textContent = groupName;
        select.appendChild(option);
    });
}

function showGroupSelect(userNameDiv, userId, userName) {
    let existingSelect = document.getElementById('group-select-' + userId);
    if (existingSelect) {

        return;
    }

    let select = document.getElementById('group-select-' + userId) || document.createElement('select');
    select.id = 'group-select-' + userId;
    select.style.display = ''; 

    let newGroupInput = document.getElementById('new-group-input-' + userId) || document.createElement('input');
    newGroupInput.id = 'new-group-input-' + userId;
    newGroupInput.style.display = '';

    let addGroupBtn = document.getElementById('add-group-btn-' + userId);
if (!addGroupBtn) {
    addGroupBtn = document.createElement('button');
    addGroupBtn.id = 'add-group-btn-' + userId;
    addGroupBtn.textContent = '新增组类别'; 
    userNameDiv.parentNode.appendChild(addGroupBtn); 
}
addGroupBtn.style.display = ''; 
    updateGroupSelect(select);
    userNameDiv.parentNode.appendChild(select);
    userNameDiv.parentNode.appendChild(newGroupInput);
    userNameDiv.parentNode.appendChild(addGroupBtn);
    addGroupBtn.addEventListener('click', function() {
        const newGroupName = newGroupInput.value.trim();
        if (newGroupName) {
            addNewGroup(newGroupName);
            newGroupInput.value = '';
            updateGroupSelect(select);
        } else {
            alert('组名不能为空!');
        }
    });
}

function addNewGroup(groupName) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    if (groups[groupName]) {
        alert('该组已存在!');
        return;
    }
    groups[groupName] = [];
    localStorage.setItem('userGroups', JSON.stringify(groups));
    alert(`新组 "${groupName}" 已成功创建。`);
}
function displayAllUsersAndGroups() {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    let message = '所有用户及其组别:\n';

    for (const [groupName, users] of Object.entries(groups)) {
        users.forEach(({ userId, userName }) => { 
            message += `用户名: ${userName}, 用户ID: ${userId}, 组别: ${groupName}\n`;
        });
    }

    alert(message);
}

    function clearAllData() {
    const isConfirmed = confirm("确定要完全清除所有数据吗?这将包括所有用户的特别关注组信息。");

    if (isConfirmed) {
        localStorage.removeItem('userGroups');
        alert("所有数据已被成功清除。");
    }
}
function addUserToGroup(userId, userName, groupName) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    Object.keys(groups).forEach(group => {
        groups[group] = groups[group].filter(user => user.userId !== userId);
    });
    if (groupName !== "无组别") {
        if (!groups[groupName]) {
            groups[groupName] = [];
        }
        const isUserInGroup = groups[groupName].some(user => user.userId === userId);
        if (!isUserInGroup) {
            groups[groupName].push({ userId, userName });
        }
    }
    localStorage.setItem('userGroups', JSON.stringify(groups));
    alert(`用户 ${userName} (${userId}) 的组别已更新。`);
}

    function clearSpecificGroup(groupNameToClear) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    if (groupNameToClear && groups[groupNameToClear]) {
        if (!groups['臨時組']) groups['臨時組'] = [];
        groups['臨時組'] = groups['臨時組'].concat(groups[groupNameToClear]);
        delete groups[groupNameToClear];
    } else if (!groupNameToClear) {
        groups['臨時組'] = [];
        for (const groupName in groups) {
            if (groupName !== '臨時組') {
                groups['臨時組'] = groups['臨時組'].concat(groups[groupName]);
                delete groups[groupName];
            }
        }
    }

    localStorage.setItem('userGroups', JSON.stringify(groups));
    displayAllUsersAndGroups();
}
document.getElementById('add-group-btn').addEventListener('click', function() {
    const groupName = document.getElementById('new-group-name').value.trim();
    if (!groupName) {
        alert('關注組名稱不能為空!');
        return;
    }
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    if (groups[groupName]) {
        alert('該關注組已存在!');
        return;
    }
    groups[groupName] = [];
    localStorage.setItem('userGroups', JSON.stringify(groups));
    document.getElementById('new-group-name').value = '';
    updateGroupSelect();
});
    document.getElementById('assign-group-btn').addEventListener('click', function() {
        const uid = document.getElementById('user-uid').value;
        const groupName = document.getElementById('group-select').value;
    });
    updateGroupSelect();
})();