自用油猴脚本分享:禁止gemini偷偷切为fast

// ==UserScript== // @name Gemini Always Pro // @namespace https://github.com/lzcmian/gemini-always-pro // @version 0.5.1 // @description Keep Gemini ...
自用油猴脚本分享:禁止gemini偷偷切为fast
自用油猴脚本分享:禁止gemini偷偷切为fast
// ==UserScript==
// @name         Gemini Always Pro
// @namespace    https://github.com/lzcmian/gemini-always-pro
// @version      0.5.1
// @description  Keep Gemini locked to the Pro model via structural selectors.
// @author       lzcmian
// @match        https://gemini.google.com/*
// @match        https://bard.google.com/*
// @run-at       document-idle
// @grant        GM_registerMenuCommand
// ==/UserScript==

(() => {
  "use strict";

  const STORAGE_KEY = "gemini-always-pro.lock-enabled";
  const TOGGLE_ID = "gemini-always-pro-toggle";
  const STYLE_ID = "gemini-always-pro-style";
  const WARN_ATTR = "data-gap-warn";
  const MODE_BUTTON = '[data-test-id="bard-mode-menu-button"]';
  const PRO_OPTION = '[data-test-id="bard-mode-option-pro"]';
  const DEBOUNCE_MS = 120;
  const RUN_GAP_MS = 1500;
  const MENU_SETTLE_MS = 300;
  const USER_QUIET_MS = 1200;

  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

  let enabled = localStorage.getItem(STORAGE_KEY) !== "0";
  let busyUntil = 0;
  let pending = 0;
  let lastUserInputAt = 0;
  let syntheticDepth = 0;

  const modeButton = () => document.querySelector(MODE_BUTTON);
  const isProNow = () => modeButton()?.innerText.trim().toLowerCase() === "pro";

  const userBusy = () => {
    const a = document.activeElement;
    if (!a?.matches?.('input, textarea, [contenteditable="true"], [contenteditable="plaintext-only"]')) return false;
    if (Date.now() - lastUserInputAt < USER_QUIET_MS) return true;
    return Boolean(a.value?.trim() || a.textContent?.replace(/​/g, "").trim());
  };

  const renderToggle = () => {
    let btn = document.getElementById(TOGGLE_ID);
    if (!btn) {
      btn = document.createElement("button");
      btn.id = TOGGLE_ID;
      btn.type = "button";
      btn.style.cssText =
        "all:initial;position:fixed;right:14px;bottom:14px;z-index:2147483647;" +
        "min-width:108px;padding:9px 13px;border:0;border-radius:999px;color:#fff;" +
        'font:700 13px/1.2 system-ui,-apple-system,"Segoe UI",sans-serif;cursor:pointer;' +
        "box-shadow:0 6px 22px rgba(0,0,0,.28);user-select:none";
      btn.addEventListener("click", (e) => {
        e.preventDefault();
        e.stopPropagation();
        enabled = !enabled;
        localStorage.setItem(STORAGE_KEY, enabled ? "1" : "0");
        renderToggle();
        if (enabled) schedule();
      });
      (document.body || document.documentElement).append(btn);
    }
    btn.textContent = enabled ? "Pro 锁定:开" : "Pro 锁定:关";
    btn.style.background = enabled ? "#0b57d0" : "#5f6368";
    btn.setAttribute("aria-pressed", String(enabled));
  };

  const ensureWarningStyle = () => {
    if (document.getElementById(STYLE_ID)) return;
    const style = document.createElement("style");
    style.id = STYLE_ID;
    style.textContent = `
      [data-test-id="bard-mode-menu-button"][${WARN_ATTR}="true"] {
        background-color: #d93025 !important;
        color: #fff !important;
        box-shadow: 0 0 0 2px rgba(217,48,37,.55), 0 0 12px rgba(217,48,37,.45) !important;
        border-radius: 999px !important;
        transition: background-color .15s ease, box-shadow .15s ease;
      }
      [data-test-id="bard-mode-menu-button"][${WARN_ATTR}="true"] *,
      [data-test-id="bard-mode-menu-button"][${WARN_ATTR}="true"] mat-icon {
        color: #fff !important;
        fill: #fff !important;
      }
    `;
    (document.head || document.documentElement).append(style);
  };

  const updateWarning = () => {
    const btn = modeButton();
    if (!btn) return;
    if (isProNow()) btn.removeAttribute(WARN_ATTR);
    else btn.setAttribute(WARN_ATTR, "true");
  };

  async function ensurePro() {
    if (!enabled || Date.now() < busyUntil) return;
    if (isProNow()) return;
    if (userBusy()) {
      schedule(USER_QUIET_MS);
      return;
    }
    const btn = modeButton();
    if (!btn) return;

    busyUntil = Date.now() + RUN_GAP_MS;
    syntheticDepth += 1;
    try {
      btn.click();
      await sleep(MENU_SETTLE_MS);
      const pro = document.querySelector(PRO_OPTION);
      if (pro) pro.click();
      else document.body.click();
    } finally {
      syntheticDepth -= 1;
    }
  }

  const schedule = (delay = DEBOUNCE_MS) => {
    clearTimeout(pending);
    pending = setTimeout(ensurePro, delay);
  };

  const markUserInput = (e) => {
    if (syntheticDepth > 0 || e.target?.id === TOGGLE_ID) return;
    lastUserInputAt = Date.now();
  };
  for (const ev of ["pointerdown", "keydown", "input", "compositionstart", "paste"]) {
    document.addEventListener(ev, markUserInput, { capture: true, passive: true });
  }

  new MutationObserver(() => {
    updateWarning();
    if (enabled) schedule();
  }).observe(document.documentElement, {
    subtree: true,
    childList: true,
    characterData: true,
    attributes: true,
    attributeFilter: ["class", "aria-expanded", "data-test-id"],
  });

  if (typeof GM_registerMenuCommand === "function") {
    GM_registerMenuCommand("切换 Gemini Pro 锁定", () => {
      enabled = !enabled;
      localStorage.setItem(STORAGE_KEY, enabled ? "1" : "0");
      renderToggle();
      if (enabled) schedule();
    });
  }

  ensureWarningStyle();
  updateWarning();
  renderToggle();
  schedule();
})();

1 个帖子 - 1 位参与者

阅读完整话题

来源: linux.do查看原文