20240801.0 [油猴脚本] GPT "时间管理" 😎大师!适配:ChatGPT官网 + 第三方镜像站(sharedchat等)

这是一个方便查看每个ChatGPT回复状态的油猴脚本,
助你成为"时间管理"大师 :rofl:

脚本功能:
通过查看每个ChatGPT网页的 favicon,直观了解当前回复的状态;
目前有5种状态:

适配:
官网 ChatGPT官网
第三方镜像站:
oaifree,
sharedchat ,

点击查看 脚本
// ==UserScript==
// @name        [Chat] State Favicons (20240801.0)
// @description States: 1. Response start: 🔄; 2. Response stop: ✔️; 3. Ready( to send): 👍; 4. Wait(other): original favicon; 5. Error: 🚫;
// @version     20240801.0
//
// @match       https://chatgpt.com/*
// @match       https://chat.rawchat.cc/*
// @match       https://chat.sharedchat.*/*
// @match       https://shared.oaifree.com/?*
//
// @icon        https://upload.wikimedia.org/wikipedia/commons/0/04/ChatGPT_logo.svg
// @grant       GM_getValue
// @grant       GM_setValue
// ==/UserScript==

(function() {
    'use strict';

    let stopButtonDetected = false;
    let responseEnded = false;
    let originalFaviconHref = document.querySelector("link[rel~='icon']")?.href || 'https://upload.wikimedia.org/wikipedia/commons/0/04/ChatGPT_logo.svg';
    let favicon = document.querySelector("link[rel~='icon']") || document.createElement('link');
    favicon.rel = 'icon';
    favicon.type = 'image/x-icon';

    let rotationInterval;

    function startFaviconRotation() {
        let degree = 0;
        rotationInterval = setInterval(() => {
            degree = (degree + 10) % 360;
            favicon.href = `data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🔄</text></svg>`;
            document.head.appendChild(favicon);
        }, 100);
    }

    function stopFaviconRotation() {
        clearInterval(rotationInterval);
        favicon.href = `data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>✔️</text></svg>`;
        document.head.appendChild(favicon);
        responseEnded = true;
    }

    function setReadyFavicon() {
        favicon.href = `data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>👍</text></svg>`;
        document.head.appendChild(favicon);
    }

    function setWaitFavicon() {
        favicon.href = originalFaviconHref;
        document.head.appendChild(favicon);
    }

    function setErrorFavicon() {
        favicon.href = `data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🚫</text></svg>`;
        document.head.appendChild(favicon);
    }

    function checkButtonState() {
        const stopButton = document.querySelector('button[data-testid="stop-button"]');
        const sendButton = document.querySelector('button[data-testid="send-button"]');
        const errorIcon = document.querySelector('svg.icon-lg path[d="M13 12a1 1 0 1 0-2 0v4a1 1 0 1 0 2 0zM12 9.5A1.25 1.25 0 1 0 12 7a1.25 1.25 0 0 0 0 2.5"]');

        if (stopButton) {
            if (!stopButtonDetected) {
                stopButtonDetected = true;
                startFaviconRotation();
                responseEnded = false;
            }
        } else if (stopButtonDetected) {
            stopFaviconRotation();
            stopButtonDetected = false;
        }

        if (responseEnded) {
            if (errorIcon) {
                setErrorFavicon();
            } else if (sendButton) {
                if (!sendButton.disabled) {
                    setReadyFavicon();
                    responseEnded = false;
                }
            }
        } else {
            if (sendButton) {
                if (!sendButton.disabled) {
                    setReadyFavicon();
                } else if (!stopButtonDetected) {
                    setWaitFavicon();
                }
            }
        }
    }

    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            if (mutation.type === 'childList' || mutation.type === 'attributes') {
                checkButtonState();
            }
        });
    });

    const config = { attributes: true, childList: true, subtree: true, attributeFilter: ['disabled', 'hidden'] };

    observer.observe(document.body, config);

    checkButtonState();

})();

点击查看 效果图
图1 (等待|Wait original favicon)

图2 (准备就绪|Ready to send): 👍)

图3 (回答中...|Response start: 🔄)

图4 (回答完毕|Response stop: ✔️)

图5 (出错了|Error: 🚫)

图6 (出错了|Error: 🚫)

—分割线—

其他:
Claude现在回复的贼快,就没搞;

感兴趣的佬们,欢迎一起交流;:innocent:

----20240801

13 个赞

前排帮顶

4 个赞

你小子

3 个赞

试用了没?:thinking:

3 个赞

啥玩意

1 个赞

省流版:在标签页显示状态图标

功能说明

  1. 响应开始时(Response start):显示旋转的:arrows_counterclockwise:图标。
  2. 响应结束时(Response stop):显示:heavy_check_mark:图标。
  3. 准备发送时(Ready to send):显示:+1:图标。
  4. 等待时(Wait):显示原始 favicon。
  5. 发生错误时(Error):显示:no_entry_sign:图标。
3 个赞

给我骗进来了

2 个赞

好家伙,我还心动了一下

1 个赞

骗进来的

1 个赞

标题现在改正经点了:joy:

1 个赞

已用

1 个赞

假东西……

1 个赞

哪里假了 :tieba_087:


请问标签页上面这个彩色条带和地址栏右边这个是怎么做到的呀,浏览器特色吗

image

火狐 + Multi-Account Containers(插件)

谢谢,原来如此!

calaude普号限制也太快了,还没问几个问题就不能问题了