Better LMSYS Chat

make chat lmsys chat better and clean

目前为 2024-03-16 提交的版本。查看 最新版本

// ==UserScript==
// @name Better LMSYS Chat
// @namespace https://github.com/insign/better-lmsys-chat
// @version 202403152308
// @description make chat lmsys chat better and clean
// @match https://chat.lmsys.org
// @icon https://www.google.com/s2/favicons?sz=64&domain=lmsys.org
// @author Hélio <[email protected]>
// @copyright Hélio <[email protected]>
// @license WTFPL
// ==/UserScript==

(function() {
  'use strict'

  const $      = document.querySelector.bind(document)
  const $$     = document.querySelectorAll.bind(document)
  const hide   = el => el.style.display = 'none'
  const remove = el => el.remove()
  const click  = el => el.click()

  const rename = (el, text) => el.textContent = text

  const perma = (selector, check, fn, interval = 50) => {
    let intervalId = null

    const checkAndExecute = () => {
      const elements = $$(selector)
      elements.forEach((element) => {
        if (check(element)) {
          fn(element)
        }
      })
    }

    const startInterval = () => {
      if (!intervalId) {
        intervalId = setInterval(checkAndExecute, interval)
      }
    }

    const stopInterval = () => {
      if (intervalId) {
        clearInterval(intervalId)
        intervalId = null
      }
    }

    document.addEventListener('visibilitychange', function() {
      if (document.hidden) {
        stopInterval()
      }
      else {
        startInterval()
      }
    })

    startInterval() // Start initially
  }

  function when(selectors = [ 'html' ], callback = null, slow = 0) {
    if (!Array.isArray(selectors)) {
      selectors = [ selectors ]
    }
    return new Promise((resolve) => {
      const executeCallback = (element) => {
        if (callback) {
          if (slow > 0) {
            setTimeout(() => {
              callback(element)
              resolve()
            }, slow)
          }
          else {
            callback(element)
            resolve()
          }
        }
        else {
          resolve()
        }
      }

      const checkSelectors = () => {
        for (const selector of selectors) {
          const element = $(selector)
          if (element) {
            executeCallback(element)
            return true
          }
        }
        return false
      }

      if (checkSelectors()) {
        return
      }

      const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
          Array.from(mutation.addedNodes).forEach((node) => {
            if (node.nodeType === Node.ELEMENT_NODE) {
              if (checkSelectors()) {
                observer.disconnect()
              }
            }
          })
        })
      })

      observer.observe(document.body, { childList: true, subtree: true })
    })
  }

  perma('#component-6-button', el => el.textContent !== 'Battle', el => rename(el, 'Battle'))
  perma('#component-44-button', el => el.textContent !== 'Side-by-Side', el => rename(el, 'Side-by-Side'))
  perma('#component-81-button', el => el.textContent !== 'Chat', el => rename(el, 'Chat'))
  perma('#component-108-button', el => el.textContent !== 'Vision Chat', el => rename(el, 'Vision Chat'))
  perma('#component-140-button', el => el.textContent !== 'Ranking', el => rename(el, 'Ranking'))


  when([
    '.svelte-1ed2p3z', '#component-151-button', '#component-54', '#component-87', '#component-114', '#component-11',
  ], remove).then(() => { // all texts and about button :(
    when('#component-81-button', click, 1000)

    perma('.tab-nav button', el => el.style.padding !== 'var(--size-1) var(--size-3)', el => {
      el.style.padding = 'var(--size-1) var(--size-3)'
    })

    perma('.tabitem', el => el.style.padding !== '0px', el => {
      console.info(el.style.padding)

      el.style.padding = 0
      el.style.border  = 0
    })
  })

  when('.app', el => {
    el.style.margin   = '0 auto'
    el.style.maxWidth = '100%'
    el.style.padding  = 0
  })

  when('.tab-nav', el => {
    el.style.display   = 'flow'
    el.style.textAlign = 'center'
  })

  perma('#chatbot', el => el.style.height !== '80vh', el => {
    el.style.height = '80vh'
  }, 2000)

  perma('.gap', el => el.style.gap !== '6px', el => {
    console.info('gap', el.style.gap)
    el.style.gap = '6px'
  }, 2000)


})()