Greasy Fork is available in English.

Bilibili 动态美化

动态粉粉嫩嫩,功能:1. 美化页面;2. 隐藏个人动态发布框;3. 隐藏右侧热门话题;4. 隐藏up发布的广告动态。希望大家多提意见,谢谢大家。

// ==UserScript==
// @name         Bilibili 动态美化
// @namespace    http://tampermonkey.net/
// @version      0.6
// @description  动态粉粉嫩嫩,功能:1. 美化页面;2. 隐藏个人动态发布框;3. 隐藏右侧热门话题;4. 隐藏up发布的广告动态。希望大家多提意见,谢谢大家。
// @author       Water WHNI
// @match        https://t.bilibili.com/*
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    // 获取自定义字段
    const defaultSettings = {
        customBackgroundURL: 'https://i0.hdslb.com/bfs/article/bfecb9a12cb9708d8d79bb9c17532e347747aeaf.jpg@1256w_708h_!web-article-pic.avif',
        hideElementsEnabled: true,
        hideRightSidebar: true,
        hidePostBar: true,
        autoFrash: true,
        autoClickInterval: 5,
        enableAutoClick: true,
        backgroundTransparency: 61,
        backgroundTransparency2: 81,
        backgroundTransparencyFloat: 91
    };

    const settings = {};
    for (const key in defaultSettings) {
        settings[key] = GM_getValue(key, defaultSettings[key]);
    }

    // 修改样式
    const styles = `
        .bili-dyn-card-video__body, .bili-dyn-card-live__body, .bili-dyn-card-pgc__body, .adblock-tips {border: none !important;}
        .adblock-tips {display: none !important;}
        .bili-dyn-sidebar {right: 5vw !important;}
        .bili-header__channel {background: none !important;}
        .bili-dyn-up-list__item__name.bili-ellipsis, .bili-dyn-time.fs-small, .item-desc, .bili-dyn-action, .bili-dyn-more__btn, .bili-dyn-card-video__stat__item, #bili-header-container span, svg {color: rgb(251, 114, 153) !important;}
        .bili-dyn-interaction__item__desc .bili-rich-text__content {color: #2f3238e0 !important;}
        .header-upload-entry {background-color: #fc8bab6b !important;}
        .bili-dyn-more__btn:hover {background-color: #fa5a5742 !important; border-radius: 50% !important;}
        .bili-dyn-card-video__desc, .bili-dyn-publishing__hint {color: #424549 !important;}
        .bili-dyn-list-notification.fs-small {color: rgb(251, 114, 153) !important;}
        .bili-dyn-content {
            border: 2px solid transparent !important;
            border-radius: 10px !important;;
            box-shadow: 0 0 0 rgb(251, 114, 153) !important;
            transition: box-shadow 0.3s ease-in-out !important;
        }
        .bili-dyn-content:hover {
            box-shadow: 0 0 15px rgb(251, 114, 153), 0 0 15px rgb(251, 114, 153) !important;
            background-color: #ffffff80 !important;
        }
        .bili-dyn-up-list__item__face {
            border: 1px solid transparent !important;;
            box-shadow: 0 0 0 rgb(251, 114, 153) !important;
            transition: box-shadow 0.3s ease-in-out !important;
        }
        .bili-dyn-up-list__item__face:hover {
            box-shadow: 0 0 5px rgb(251, 114, 153), 0 0 5px rgb(251, 114, 153) !important;;
        }
        .bili-dyn-up-list__nav.next .bili-dyn-up-list__nav__shadow {
            background: linear-gradient(90deg, hsla(0, 0%, 100%, 0), rgb(251 114 153 / 60%) !important;
        }
        .bili-dyn-up-list__nav__shim {
            background: rgb(251 114 153 / 60%) !important;
        }
        .bili-dyn-up-list__nav.prev .bili-dyn-up-list__nav__shadow {
            background: linear-gradient(270deg, hsla(0, 0%, 100%, 0), rgb(251 114 153 / 60%) !important;
        }
        .bili-album__watch__content {height: 30vw !important;}
        .bili-album__watch__content img {height: 30vw !important; max-width: 60% !important;}
        :root {
            --bg1: rgba(255, 255, 255, ${settings.backgroundTransparency / 100}) !important;
            --bg2: rgba(255, 255, 255, ${settings.backgroundTransparency2 / 100}) !important;
            --bg1_float: rgba(255, 255, 255, ${settings.backgroundTransparencyFloat / 100}) !important;
        }
    `;
    GM_addStyle(styles);

    // 菜单功能函数
    const applyBackgroundImage = (url) => {
        GM_addStyle(`
            .bg {
                background-image: url("${url}") !important;
                background-size: cover !important;
                background-attachment: fixed !important;
                background-position: center center !important;
                background-repeat: no-repeat !important;
                height: 100% !important;
            }
        `);
    };

    const hideSpecificElements = () => {
        document.querySelectorAll('.bili-dyn-list__item').forEach(item => {
            if (item.querySelector('.bili-rich-text-module.goods')) {
                item.style.display = 'none';
            }
        });
    };

    const setupHideElements = () => {
        if (settings.hideElementsEnabled) {
            hideSpecificElements();
            new MutationObserver(hideSpecificElements).observe(document.body, {childList: true, subtree: true});
        }
    };

    const applyBackgroundTransparency = (transparency, tB2, bg1F) => {
        GM_addStyle(`
            :root {
                --bg1: rgba(255, 255, 255, ${transparency / 100}) !important;
                --bg2: rgba(255, 255, 255, ${tB2 / 100}) !important;
                --bg1_float: rgba(255, 255, 255, ${bg1F / 100}) !important;
            }
        `);
    };

    // 菜单功能实现
    setupHideElements();
    applyBackgroundImage(settings.customBackgroundURL);

    if (settings.hideRightSidebar) {
        GM_addStyle('.right { display: none !important; }');
        GM_addStyle('#app > div.bili-dyn-home--member > main { width: 70vw !important; }');
    }

    if (settings.hidePostBar) {
        GM_addStyle('.bili-dyn-publishing { display: none !important; }');
        GM_addStyle('#app > div.bili-dyn-home--member > main > section:nth-child(1) {display : none !important;}');
        GM_addStyle('.bili-dyn-up-list__window {padding: 20px 0 20px !important;}');
        GM_addStyle('.bili-dyn-up-list__window {margin-top: 2px !important;}');
    }

    applyBackgroundTransparency(settings.backgroundTransparency, settings.backgroundTransparency2, settings.backgroundTransparencyFloat);

    // 定时检查并点击元素
    const checkAndClick = () => {
        const selector = '#app > div.bili-dyn-home--member > main > section:nth-child(3) > div.bili-dyn-list > div.bili-dyn-list__notification > div';
        const element = document.querySelector(selector);
        if (element) {
            try {
                element.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true}));
            } catch (e) {
                const event = document.createEvent('Event');
                event.initEvent('click', true, true);
                element.dispatchEvent(event);
            }
        }
    };

    // 修改定时检查并点击功能实现
    let autoClickIntervalId;
    const setupAutoClick = () => {
        if (settings.enableAutoClick) {
            autoClickIntervalId = setInterval(checkAndClick, settings.autoClickInterval * 1000);
        }
    };

    setupAutoClick();

    // 创建隐藏开关
    const createToggle = (label, key) => {
        const container = document.createElement('div');
        container.style.cssText = `
        margin-bottom: 10px;
        display: flex;
        align-items: center;
        justify-content: space-between;
    `;
        const toggleLabel = document.createElement('label');
        toggleLabel.innerText = label;
        toggleLabel.style.cssText = `
        margin: 0;
    `;
        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = settings[key];
        checkbox.style.cssText = `
        margin-left: 10px;
    `;
        checkbox.onchange = () => settings[key] = checkbox.checked;
        container.append(toggleLabel, checkbox);
        return {container, checkbox};
    };

    // 注册菜单
    // 注册菜单
    GM_registerMenuCommand('设置', () => {
        // 创建悬浮框
        const modal = document.createElement('div');
        modal.style.cssText = `
        position: fixed;
        top: 8vh;
        right: 1vw;
        padding: 20px;
        background-color: #fff;
        box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
        border-radius: 10px;
        z-index: 9999;
        width: 320px;
        font-family: Arial, sans-serif;
        overflow: auto;
    `;

        // 标题
        const modalHeader = document.createElement('div');
        modalHeader.style.cssText = `
        font-size: 20px;
        font-weight: bold;
        margin-bottom: 15px;
        text-align: center;
    `;
        modalHeader.innerText = '设置';

        // 创建自定义背景图片输入框及应用按钮
        const bgInputContainer = document.createElement('div');
        bgInputContainer.style.cssText = `
        display: flex;
        align-items: center;
        margin-bottom: 10px;
        width: 100%;
    `;
        const bgInputLabel = document.createElement('label');
        bgInputLabel.innerText = '背景图片URL: ';
        bgInputLabel.style.cssText = `
        flex: 0 0 35%;
    `;
        const bgInput = document.createElement('input');
        bgInput.type = 'text';
        bgInput.value = settings.customBackgroundURL;
        bgInput.style.cssText = `
        flex: 1;
        padding: 5px;
        border: 1px solid #ccc;
        border-radius: 5px;
        margin-left: 10px;
        overflow: hidden;
        text-overflow: ellipsis;
    `;
        const applyBgButton = document.createElement('button');
        applyBgButton.innerText = '应用';
        applyBgButton.style.cssText = `
        width: 100%;
        padding: 5px 10px;
        background-color: #12a9df;
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        margin-bottom: 5px;
    `;
        applyBgButton.onclick = () => {
            const newURL = bgInput.value;
            GM_setValue('customBackgroundURL', newURL);
            applyBackgroundImage(newURL);
        };
        bgInputContainer.append(bgInputLabel, bgInput);

        // 创建隐藏开关
        const {
            container: hideUpAdContainer,
            checkbox: hideUpAdCheckbox
        } = createToggle('隐藏UP广告动态', 'hideElementsEnabled');
        const {
            container: hideSidebarContainer,
            checkbox: hideSidebarCheckbox
        } = createToggle('隐藏右边栏', 'hideRightSidebar');
        const {
            container: hidePostBarContainer,
            checkbox: hidePostBarCheckbox
        } = createToggle('隐藏动态发布', 'hidePostBar');
        const {
            container: timerToggleContainer,
            checkbox: timerToggleCheckbox
        } = createToggle('自动加载新动态', 'enableAutoClick');

        // 点击间隔输入框
        const intervalContainer = document.createElement('div');
        intervalContainer.style.cssText = `
        display: flex;
        align-items: center;
        margin-bottom: 10px;
        width 100%;
    `;
        const intervalLabel = document.createElement('label');
        intervalLabel.innerText = '点击间隔 (秒): ';
        intervalLabel.style.cssText = `
        flex: 0 0 35%;
    `;
        const intervalInput = document.createElement('input');
        intervalInput.type = 'number';
        intervalInput.min = '1';
        intervalInput.value = settings.autoClickInterval || 5;
        intervalInput.style.cssText = `
        flex: 1;
        padding: 5px;
        margin-left: 10px;
        border: 1px solid #ccc;
        border-radius: 5px;
    `;
        intervalInput.oninput = () => {
            const interval = Math.max(1, parseInt(intervalInput.value));
            settings.autoClickInterval = interval;
            GM_setValue('autoClickInterval', interval);
            if (settings.enableAutoClick) {
                clearInterval(autoClickIntervalId);
                autoClickIntervalId = setInterval(checkAndClick, interval * 1000);
            }
        };
        intervalContainer.append(intervalLabel, intervalInput);

        // 背景透明度滑块
        const sliderContainer = document.createElement('div');
        sliderContainer.style.cssText = `
        display: flex;
        align-items: center;
        margin-bottom: 10px;
        width: 100%;
    `;
        const sliderLabel = document.createElement('label');
        sliderLabel.innerText = '背景透明度: ';
        sliderLabel.style.cssText = `
        flex: 0 0 35%;
    `;
        const slider = document.createElement('input');
        slider.type = 'range';
        slider.min = '0';
        slider.max = '100';
        slider.value = settings.backgroundTransparency;
        slider.style.cssText = `
        flex: 1;
        margin-left: 5px;
    `;

        slider.oninput = () => {
            const transparency = parseInt(slider.value);
            settings.backgroundTransparency2 = Math.min(transparency + 20, 100);
            settings.backgroundTransparencyFloat = Math.min(transparency + 50, 100);
            GM_setValue('backgroundTransparency', transparency);
            GM_setValue('backgroundTransparency2', settings.backgroundTransparency2);
            GM_setValue('backgroundTransparencyFloat', settings.backgroundTransparencyFloat);
            applyBackgroundTransparency(transparency, settings.backgroundTransparency2, settings.backgroundTransparencyFloat);
        };
        sliderContainer.append(sliderLabel, slider);

        // 创建按钮容器
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = `
        display: flex;
        justify-content: space-between;
        margin-top: 15px;
    `;
        const closeButton = document.createElement('button');
        closeButton.innerText = '关闭';
        closeButton.style.cssText = `
        padding: 5px 10px;
        background-color: #f44336;
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
    `;
        closeButton.onclick = () => document.body.removeChild(modal);

        const saveButton = document.createElement('button');
        saveButton.innerText = '保存';
        saveButton.style.cssText = `
        padding: 5px 10px;
        background-color: #4CAF50;
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
    `;
        saveButton.onclick = () => {
            GM_setValue('hideElementsEnabled', hideUpAdCheckbox.checked);
            GM_setValue('hideRightSidebar', hideSidebarCheckbox.checked);
            GM_setValue('hidePostBar', hidePostBarCheckbox.checked);
            GM_setValue('enableAutoClick', timerToggleCheckbox.checked);
            GM_setValue('autoClickInterval', Math.max(1, parseInt(intervalInput.value)));
            location.reload();
        };

        buttonContainer.append(saveButton, closeButton);

        // 添加元素到悬浮框
        modal.append(
            modalHeader,
            bgInputContainer, applyBgButton,
            hideUpAdContainer,
            hideSidebarContainer,
            hidePostBarContainer,
            timerToggleContainer,
            intervalContainer,
            sliderContainer,
            buttonContainer
        );

        document.body.appendChild(modal);
    });

})();