Greasy Fork

Greasy Fork is available in English.

MFGUA

make FlowGPT usable again

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         MFGUA
// @namespace    com.github.brink182
// @version      0.3.1
// @license      GPL3
// @description  make FlowGPT usable again
// @author       brink182
// @match        https://flowgpt.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=flowgpt.com
// @grant        GM_notification
// ==/UserScript==

(function() {
    'use strict';
    const last = {};
    const marker = window.crypto.randomUUID().toLowerCase().replaceAll('-','');
    const state = JSON.parse(localStorage.getItem('7093d631034d4924a69c6148f4577f46') || '{"deviceIds":{}}');
    console.log(last, marker, state);

    function storeState() {
        localStorage.setItem('7093d631034d4924a69c6148f4577f46', JSON.stringify(state));
    }

    function addSendButton(ref) {
        const text = ref.parentNode.firstElementChild;
        for (const old of document.querySelectorAll(`button[data-${marker}='true']`)) {
            old.parentNode.removeChild(old);
        }
        if (text instanceof HTMLTextAreaElement === false) {
            console.log("Textarea expected ", text);
            return;
        }

        const send = document.createElement("button");
        send.ariaLabel = "Send";
        send.innerHTML = '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" aria-hidden="true" focusable="false" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M3 13.0001H9V11.0001H3V1.8457C3 1.56956 3.22386 1.3457 3.5 1.3457C3.58425 1.3457 3.66714 1.36699 3.74096 1.4076L22.2034 11.562C22.4454 11.695 22.5337 11.9991 22.4006 12.241C22.3549 12.3241 22.2865 12.3925 22.2034 12.4382L3.74096 22.5925C3.499 22.7256 3.19497 22.6374 3.06189 22.3954C3.02129 22.3216 3 22.2387 3 22.1544V13.0001Z"></path></svg>';
        send.className = ref.className;
        send.dataset[marker] = 'true';
        send.addEventListener('click', () => text.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter', bubbles: true, cancelable: true, code: 'Enter', keyCode: 13})));

        ref.parentNode.insertBefore(send, ref);
    }

    function getCurrentDeviceId() {
        const result = /(?:^|;\s*)deviceId=([^;]*)(?:;|$)/.exec(document.cookie);
        return result === null ? null : result[1];
    }

    function setCurrentDeviceId(deviceId) {
        document.cookie = "deviceId=" + deviceId;
    }

    async function toggleUiVariant() {
        const classic = (document.getElementsByTagName("aside").length === 0);
        const oldVariant = classic ? "classic" : "modern";
        const oldDeviceId = getCurrentDeviceId();
        state.deviceIds[oldVariant] = oldDeviceId;
        storeState();
        const newVariant = classic ? "modern" : "classic";
        const newDeviceId = state.deviceIds[newVariant];
        if (newDeviceId && newDeviceId !== oldDeviceId) {
            setCurrentDeviceId(newDeviceId);
            window.location.reload(true);
            return;
        }
        var stillClassic = classic;
        for (var i = 0; stillClassic === classic && i < 4; i++) {
            setCurrentDeviceId("");
            const loc = document.location;
            const response = await fetch(loc.protocol + "//" + loc.host, {cache: "no-store"});
            stillClassic = !(await response.text()).includes("</aside>");
            console.log("Got ", stillClassic ? "classic" : "modern", " deviceId: ", getCurrentDeviceId(), response);
        }
        if (stillClassic === classic) {
            setCurrentDeviceId(oldDeviceId);
            GM_notification("MFGUA - Error", "Could not switch to " + newVariant + " UI");
        } else {
            state.deviceIds[newVariant] = getCurrentDeviceId();
            storeState();
            window.location.reload(true);
        }
    }

    function addUserMenuItems() {
        const logout = document.querySelector('button[data-testid="user-menu-logout"]')
        if (logout === null || document.querySelector(`[data-${marker}='toggleUiVariant']`) !== null) {
            //menu closed or processed
            return;
        }
        const toggleUi = logout.previousElementSibling;
        toggleUi.hidden = false;
        toggleUi.addEventListener('click', () => toggleUiVariant());
        toggleUi.ariaLabel = 'Toggle UI';
        toggleUi.dataset[marker] = 'toggleUiVariant';
        toggleUi.lastElementChild.lastElementChild.innerText='Toggle UI';
        const menu = logout.parentNode.insertBefore(toggleUi, logout);
    }

    new MutationObserver(() => {
        const chatMenu = document.querySelector("button[id^='menu-button-:r'].chakra-button.chakra-menu__menu-button");
        if (chatMenu !== null && !Object.is(last.chatMenu, chatMenu)) {
            last.chatMenu = chatMenu;
            addSendButton(chatMenu);
        }
        addUserMenuItems();
    }).observe(document, {childList: true, subtree: true });
})();