Linux.do 可折叠侧边栏

为 Linux.do 论坛添加可折叠的侧边栏功能

// ==UserScript==
// @name         Linux.do 可折叠侧边栏
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  为 Linux.do 论坛添加可折叠的侧边栏功能
// @author       yueliusu
// @match        https://linux.do/*
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

/* MIT License
 * 
 * Copyright (c) 2025 yueliusu
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

(function() {
    'use strict';

    // 添加必要的样式
    GM_addStyle(`
        /* 确保样式应用到整个侧边栏容器及其子元素 */
        body .sidebar-wrapper {
            overflow: hidden;
        }

        .sidebar-wrapper {
            position: relative;
            transition: width 0.3s ease;
        }

        .sidebar-collapsed {
            width: 50px !important;
            overflow: hidden;
        }

        .sidebar-collapsed .sidebar-section-wrapper,
        .sidebar-collapsed .sidebar-footer-wrapper,
        .sidebar-collapsed .chat-footer-item {
            opacity: 0;
            pointer-events: none;
        }

        /* 隐藏底部聊天按钮 */
        .sidebar-collapsed .sidebar-footer-wrapper {
            transform: translateX(-100%);
        }

        .toggle-sidebar {
            position: absolute;
            top: 10px;
            right: 10px;
            width: 20px;
            height: 20px;
            background-color: #e9e9e9;
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
            z-index: 1000;
            border: 1px solid #ccc;
        }

        .toggle-sidebar:hover {
            background-color: #d9d9d9;
        }

        .toggle-sidebar svg {
            width: 12px;
            height: 12px;
        }

        .main-content {
            transition: margin-left 0.3s ease;
        }

        .main-content-expanded {
            margin-left: 50px !important;
        }
    `);

    // 等待DOM完全加载
    function waitForElement(selector, callback, maxTries = 20, interval = 500) {
        let tries = 0;

        function check() {
            const element = document.querySelector(selector);
            if (element) {
                callback(element);
                return;
            } else if (tries < maxTries) {
                tries++;
                setTimeout(check, interval);
            }
        }

        check();
    }

    // 创建折叠/展开按钮
    function createToggleButton() {
        const toggleButton = document.createElement('div');
        toggleButton.className = 'toggle-sidebar';
        toggleButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>';
        toggleButton.title = '折叠/展开侧边栏';
        return toggleButton;
    }

    // 主函数
    function initCollapsibleSidebar() {
        waitForElement('.sidebar-wrapper', (sidebar) => {
            // 添加折叠按钮
            const toggleButton = createToggleButton();
            sidebar.appendChild(toggleButton);

            // 获取主内容区域
            const mainContent = document.querySelector('.main-content');

            // 折叠状态(从localStorage读取状态,默认为展开)
            let isCollapsed = localStorage.getItem('linux_do_sidebar_collapsed') === 'true';

            // 初始化侧边栏状态
            if (isCollapsed) {
                sidebar.classList.add('sidebar-collapsed');
                if (mainContent) {
                    mainContent.classList.add('main-content-expanded');
                }
                toggleButton.style.transform = 'rotate(180deg)';
            }

            // 点击事件处理
            toggleButton.addEventListener('click', () => {
                isCollapsed = !isCollapsed;

                // 保存状态到localStorage
                localStorage.setItem('linux_do_sidebar_collapsed', isCollapsed);

                // 切换侧边栏类
                sidebar.classList.toggle('sidebar-collapsed', isCollapsed);

                // 调整主内容区域
                if (mainContent) {
                    mainContent.classList.toggle('main-content-expanded', isCollapsed);
                }

                // 处理底部聊天按钮
                const chatFooter = document.querySelector('.sidebar-footer-wrapper');
                if (chatFooter) {
                    if (isCollapsed) {
                        chatFooter.style.visibility = 'hidden';
                    } else {
                        setTimeout(() => {
                            chatFooter.style.visibility = 'visible';
                        }, 300); // 等待折叠动画完成
                    }
                }

                // 旋转图标
                toggleButton.style.transform = isCollapsed ? 'rotate(180deg)' : '';
            });
        });
    }

    // 初始化脚本
    initCollapsibleSidebar();

    // 监听页面变化,处理SPA导航
    const observer = new MutationObserver((mutations) => {
        for (const mutation of mutations) {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                // 检查是否需要重新初始化
                if (!document.querySelector('.toggle-sidebar')) {
                    initCollapsibleSidebar();
                }
            }
        }
    });

    // 监听body元素变化
    observer.observe(document.body, { childList: true, subtree: true });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址