AI Conversation Navigator

Floating navigator for your prompts in ChatGPT and Gemini conversations (no storage)

目前為 2025-08-15 提交的版本,檢視 最新版本

// ==UserScript==
// @name         AI Conversation Navigator
// @namespace    https://gf.qytechs.cn
// @version      1.3
// @description  Floating navigator for your prompts in ChatGPT and Gemini conversations (no storage)
// @author       Bui Quoc Dung
// @match        https://chatgpt.com/*
// @match        https://gemini.google.com/*
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function () {
  'use strict';

  const COMMON_TITLE = 'Your Prompts';

  const COMMON_CONTAINER_STYLE = `
    right: 20px; width: 250px; max-height: 90vh; overflow-y: auto;
    z-index: 9999; border-radius: 2px; box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.3);
    transition: width 0.3s, padding 0.3s, opacity 0.3s, transform 0.3s;
    font-family: Calibri, sans-serif; font-size: 15px;
  `;

  const SITE_CONFIG = {
    chatgpt: {
      match: /chatgpt\.com/,
      msgSelector: 'div[data-message-author-role="user"]',
      moveLeftStyle: `
        body.navigator-expanded .mx-auto,
        body.navigator-expanded .md\\:max-w-3xl,
        body.navigator-expanded .xl\\:max-w-\\[48rem\\],
        body.navigator-expanded .max-w-2xl,
        body.navigator-expanded .lg\\:px-2 {
          margin-left: 0 !important;
          margin-right: 130px !important;
        }
        body.navigator-expanded main,
        body.navigator-expanded main > div,
        body.navigator-expanded main article > div,
        body.navigator-expanded div.flex.flex-col.items-center.text-sm {
          margin-left: 0 !important;
          margin-right: auto !important;
          max-width: 100% !important;
        }
        body.navigator-expanded div.ProseMirror {
          margin-left: 0 !important;
          margin-right: auto !important;
        }
        body.navigator-expanded .xl\\:max-w-\\[48rem\\] {
          width: 800px !important;
          max-width: 100% !important;
        }
      `,
      containerStyle: `position: fixed; top: 35px; ${COMMON_CONTAINER_STYLE}`,
      bgClass: "text-token-text-primary bg-token-main-surface-primary rounded-lg shadow-lg"
    },
    gemini: {
      match: /gemini\.google\.com/,
      msgSelector: '.user-query-bubble-with-background',
      moveLeftStyle: `
        body.navigator-expanded .chat-history-scroll-container {
          margin-left: 0 !important;
          margin-right: 300px !important;
          max-width: calc(100% - 300px) !important;
          transition: margin-right 0.3s ease;
        }
      `,
      containerStyle: `position: fixed; top: 55px; ${COMMON_CONTAINER_STYLE}`,
      bgClass: ""
    }
  };

  const site = Object.values(SITE_CONFIG).find(s => s.match.test(location.hostname));
  if (!site) return;

  GM_addStyle(site.moveLeftStyle);

  let userMsgCounter = 0;
  let conversationObserver = null;
  let isCollapsed = false;

  function updateBodyClassForLayout() {
    const container = document.getElementById('message-nav');
    const content = document.getElementById('message-nav-content');
    if (container && content && content.style.display !== 'none') {
      document.body.classList.add('navigator-expanded');
    } else {
      document.body.classList.remove('navigator-expanded');
    }
  }

  function createContainer() {
    let container = document.getElementById('message-nav');
    if (!container) {
      container = document.createElement('div');
      container.id = 'message-nav';
      container.className = site.bgClass;
      container.style.cssText = site.containerStyle;

      const header = document.createElement('div');
      header.style.display = 'flex';
      header.style.alignItems = 'center';
      header.style.justifyContent = 'space-between';
      header.style.padding = '5px';
      header.style.cursor = 'pointer';
      header.style.fontWeight = 'bold';
      header.textContent = COMMON_TITLE;

      const toggleBtn = document.createElement('button');
      toggleBtn.style.background = 'none';
      toggleBtn.style.border = 'none';
      toggleBtn.style.cursor = 'pointer';
      toggleBtn.style.fontSize = '16px';
      toggleBtn.textContent = '⯈';
      header.appendChild(toggleBtn);

      const content = document.createElement('div');
      content.id = 'message-nav-content';
      content.style.padding = '5px';

      container.appendChild(header);
      container.appendChild(content);
      document.body.appendChild(container);

      if (isCollapsed) {
        content.style.display = 'none';
        container.style.width = '130px';
        toggleBtn.textContent = '⯆';
      }

      toggleBtn.addEventListener('click', (e) => {
        e.stopPropagation();
        isCollapsed = !isCollapsed;
        if (!isCollapsed) {
          content.style.display = 'block';
          container.style.width = '250px';
          toggleBtn.textContent = '⯈';
        } else {
          content.style.display = 'none';
          container.style.width = '130px';
          toggleBtn.textContent = '⯆';
        }
        updateBodyClassForLayout();
      });

      updateBodyClassForLayout();
    }
    return container;
  }

  function assignIdToMessage(msgElem) {
    if (!msgElem.id) {
      userMsgCounter++;
      msgElem.id = 'user-msg-' + userMsgCounter;
      msgElem.dataset.index = userMsgCounter;
    }
  }

  function createListItem(msgElem) {
    const index = msgElem.dataset.index || '?';
    const text = msgElem.innerText.trim();
    const preview = text.length > 80 ? text.slice(0, 80) + '...' : text;

    const listItem = document.createElement('li');
    listItem.textContent = `${index}. ${preview}`;
    listItem.style.cursor = 'pointer';
    listItem.style.padding = '5px 5px';

    listItem.addEventListener('click', () => {
      const allItems = listItem.parentElement.querySelectorAll('li');
      allItems.forEach(li => li.style.fontWeight = 'normal');
      listItem.style.fontWeight = 'bold';
      msgElem.scrollIntoView({ behavior: 'smooth', block: 'start' });
    });

    return listItem;
  }

  function updateMessageList() {
    const container = createContainer();
    const content = document.getElementById('message-nav-content');
    if (!content) return;

    let list = content.querySelector('ul');
    if (!list) {
      list = document.createElement('ul');
      list.style.padding = '0';
      list.style.margin = '0';
      list.style.listStyle = 'none';
      content.appendChild(list);
    }

    const userMessages = document.querySelectorAll(site.msgSelector);
    const existingListItems = list.querySelectorAll('li');

    if (userMessages.length < existingListItems.length) {
      list.innerHTML = '';
    }

    if (userMessages.length > existingListItems.length) {
      for (let i = existingListItems.length; i < userMessages.length; i++) {
        const msgElem = userMessages[i];
        assignIdToMessage(msgElem);
        const listItem = createListItem(msgElem);
        list.appendChild(listItem);
      }
    }
  }

  function observeConversation() {
    if (conversationObserver) conversationObserver.disconnect();
    const mainElem = document.querySelector('main');
    if (!mainElem) return;
    conversationObserver = new MutationObserver(() => updateMessageList());
    conversationObserver.observe(mainElem, { childList: true, subtree: true });
  }

  function waitForChatToLoad() {
    const interval = setInterval(() => {
      const mainElem = document.querySelector('main');
      if (mainElem && document.querySelector(site.msgSelector)) {
        clearInterval(interval);
        userMsgCounter = 0;
        const content = document.getElementById('message-nav-content');
        if (content) {
          const list = content.querySelector('ul');
          if (list) list.innerHTML = '';
        }
        updateMessageList();
        observeConversation();
      }
    }, 500);
  }

  waitForChatToLoad();

  let lastUrl = location.href;
  new MutationObserver(() => {
    if (location.href !== lastUrl) {
      lastUrl = location.href;
      waitForChatToLoad();
    }
  }).observe(document.body, { childList: true, subtree: true });

})();

QingJ © 2025

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