关于AI总结按钮的位置

早上看帖子才发现底下有一个新增的AI总结按钮,非常实用,在看一些长贴的时候免了爬楼,就可以把大致内容总结一下。就是默认是放在帖子底下的,想要总结需要把帖子拉到最底下,这样右边的时间轴就会把当前浏览的位置也记录到了最底下。建议可以把总结的窗口放到右侧的位置,类似图上这样

3 个赞

赞同+1,不过,此举也许会导致一些精品评论被错过

主话题下侧第一行也有,不用专门划到最下端

1 个赞

才看到,完美!

1 个赞

不说不知道,谢谢大佬

在什么位置啊, 没瞅见呢? 只看到了 优化插件的

2 个赞

我一直点的都是这个 :rofl: 没注意下边还有一个

我都是划到最下面的。。

我用claude写了一个移动按钮的脚本,你看看

script
// ==UserScript==
// @name         悬浮可拖拽总结按钮-优化版
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  创建悬浮的可拖拽总结按钮,优化拖拽体验
// @author       Your name
// @match        https://linux.do/*
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    // 防止重复创建
    if (document.querySelector('#floating-summary-btn')) {
        return;
    }

    function createFloatingButton() {
        const originalButton = document.querySelector('.ai-summarization-button');
        const titleElement = document.querySelector('.fancy-title');

        if (originalButton && titleElement) {
            // 创建悬浮容器
            const floatingContainer = document.createElement('div');
            floatingContainer.id = 'floating-summary-btn';

            const defaultX = window.innerWidth - 100;
            const defaultY = window.innerHeight / 3;

            const lastPos = {
                x: GM_getValue('summaryBtnX', defaultX),
                y: GM_getValue('summaryBtnY', defaultY)
            };

            floatingContainer.style.cssText = `
                position: fixed;
                left: ${lastPos.x}px;
                top: ${lastPos.y}px;
                z-index: 9999;
                background-color: white;
                width: 80px;
                height: 40px;
                border-radius: 20px;
                box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                transition: box-shadow 0.3s, transform 0.3s;
                cursor: pointer;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                touch-action: none;
            `;

            // 克隆原始按钮
            const newButton = originalButton.cloneNode(true);
            newButton.style.cssText = `
                width: 100%;
                height: 100%;
                border-radius: 20px;
                padding: 5px 10px;
                display: flex;
                flex-direction: row;
                align-items: center;
                justify-content: center;
                background: transparent;
                border: none;
                font-size: 12px;
                gap: 5px;
                color: #333 !important;
            `;

            // 调整SVG图标大小和样式
            const svg = newButton.querySelector('svg');
            if (svg) {
                svg.style.cssText = `
                    width: 14px;
                    height: 14px;
                    margin: 0;
                    fill: currentColor;
                    color: #333 !important;
                `;
            }

            // 调整文字样式
            const buttonLabel = newButton.querySelector('.d-button-label');
            if (buttonLabel) {
                buttonLabel.style.cssText = `
                    display: inline;
                    font-size: 12px;
                    margin: 0;
                    line-height: 1;
                    color: #333 !important;
                    -webkit-text-fill-color: #333 !important;
                `;
            }

            floatingContainer.addEventListener('mouseover', () => {
                if (!isDragging) {
                    floatingContainer.style.transform = 'scale(1.1)';
                    floatingContainer.style.boxShadow = '0 4px 15px rgba(0,0,0,0.2)';
                }
            });

            floatingContainer.addEventListener('mouseout', () => {
                if (!isDragging) {
                    floatingContainer.style.transform = 'scale(1)';
                    floatingContainer.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)';
                }
            });

            let pressStartTime = 0;
            let isDragging = false;
            let hasMoved = false;
            let initialX;
            let initialY;
            let currentX;
            let currentY;

            function dragStart(e) {
                pressStartTime = Date.now();
                hasMoved = false;

                if (e.type === "touchstart") {
                    initialX = e.touches[0].clientX - floatingContainer.offsetLeft;
                    initialY = e.touches[0].clientY - floatingContainer.offsetTop;
                } else {
                    initialX = e.clientX - floatingContainer.offsetLeft;
                    initialY = e.clientY - floatingContainer.offsetTop;
                }
            }

            function drag(e) {
                if (!pressStartTime) return;

                e.preventDefault();

                let currentPosX, currentPosY;
                if (e.type === "touchmove") {
                    currentPosX = e.touches[0].clientX - initialX;
                    currentPosY = e.touches[0].clientY - initialY;
                } else {
                    currentPosX = e.clientX - initialX;
                    currentPosY = e.clientY - initialY;
                }

                // 检查是否移动超过阈值
                const moveThreshold = 5;
                if (Math.abs(currentPosX - floatingContainer.offsetLeft) > moveThreshold ||
                    Math.abs(currentPosY - floatingContainer.offsetTop) > moveThreshold) {
                    hasMoved = true;
                    isDragging = true;
                    floatingContainer.style.transition = 'none';

                    // 更新位置
                    currentX = Math.min(Math.max(0, currentPosX), window.innerWidth - 80);
                    currentY = Math.min(Math.max(0, currentPosY), window.innerHeight - 40);
                    floatingContainer.style.left = currentX + "px";
                    floatingContainer.style.top = currentY + "px";
                }
            }

            function dragEnd(e) {
                const pressDuration = Date.now() - pressStartTime;

                // 如果按压时间小于200ms且没有明显移动,视为点击
                if (pressDuration < 200 && !hasMoved) {
                    originalButton.click();
                }

                // 重置状态
                pressStartTime = 0;
                isDragging = false;
                hasMoved = false;
                floatingContainer.style.transition = 'box-shadow 0.3s, transform 0.3s';

                // 保存位置
                if (currentX !== undefined && currentY !== undefined) {
                    GM_setValue('summaryBtnX', currentX);
                    GM_setValue('summaryBtnY', currentY);
                }
            }

            floatingContainer.addEventListener('mousedown', dragStart, { passive: false });
            floatingContainer.addEventListener('touchstart', dragStart, { passive: false });

            document.addEventListener('mousemove', drag, { passive: false });
            document.addEventListener('touchmove', drag, { passive: false });

            document.addEventListener('mouseup', dragEnd);
            document.addEventListener('touchend', dragEnd);

            floatingContainer.appendChild(newButton);
            document.body.appendChild(floatingContainer);

            // 隐藏原始按钮
            originalButton.style.display = 'none';
        }
    }

    // 移除可能存在的旧实例
    function removeOldInstances() {
        const oldButton = document.querySelector('#floating-summary-btn');
        if (oldButton) {
            oldButton.remove();
        }
    }

    // 页面加载完成后执行
    function init() {
        removeOldInstances();
        createFloatingButton();
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

    // 为了确保动态加载的元素也能被处理
    setTimeout(init, 2000);
})();

才看到,这个总结功能确实大大方便