ChatGPT: Fix Enter Key on Small Sizes

Userscript changes the mobile interface by restoring Ctrl+Enter or Enter as Submit, even when opening small, thin windows in the desktop environment.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         ChatGPT: Fix Enter Key on Small Sizes
// @namespace    cvladan.com
// @version      1.1
// @description  Userscript changes the mobile interface by restoring Ctrl+Enter or Enter as Submit, even when opening small, thin windows in the desktop environment.
// @author       Vladan Colovic
// @match        *://chat.openai.com/*
// @run-at       document-end
// @require      https://cdn.jsdelivr.net/gh/chatgptjs/chatgpt.js@bdc3e03cc0b1fbcfcc886022d5690880aa40442c/dist/chatgpt-1.7.6.min.js
// @grant        none
// @license      MIT
// @created      2023-06-03
// @updated      2023-06-03
// ==/UserScript==

const selSubmit = 'form > div > div > button';
const selNewChat = 'nav > div > a, div.sticky > button:last-of-type';
const enableDefaultModeOnMobile = false;

// I need to ensure that ChatGPT is fully loaded to check selector validity
//
(async () => {
    await chatgpt.isLoaded()

    btnSubmit = document.querySelector(selSubmit);
    btnNewChat = document.querySelector(selNewChat);

    inputArea = chatgpt.getTextarea();
    inputArea.addEventListener('keydown', handleKeydown, true);
})();

// Ensure that ChatGPT is fully loaded to check selector validity
//
function clickMouseOn(button) {
  rect = button?.getBoundingClientRect();
  if (!rect) {
    console.info("Nothing currently at: " + cssSelector);
    return;
  }

  var event = new MouseEvent('click', {
    view: window, bubbles: true, cancelable: true,
      clientX: rect.left + (rect.width / 2),
      clientY: rect.top + (rect.height / 2) });

  button.dispatchEvent(event);
}

// Ensure that ChatGPT is fully loaded to check selector validity
//
function skipActions(event) {
  event.preventDefault();
  event.stopPropagation();
  event.stopImmediatePropagation();
  return false;
}

// Handler for all key events
//
// Attention is paid to:
// - does not interfere with possibly other Enter-key combinations
// - so that, for example Alt-Enter will still do what it does now
// - if a selector is incorrectly specified, the key is not occupied
//
function handleKeydown(event) {

  var ignoreOtherListeners = false;

  const isEnter = (event.key === 'Enter');
  const modKey = event.ctrlKey | (event.shiftKey << 1) | (event.altKey << 2) | (event.metaKey << 3);


  if (enableDefaultModeOnMobile) {

    if (isEnter && modKey === 0) { // force enter, even on mobile
      clickMouseOn(btnSubmit);
      skipActions(event);
      return false;
    }

    return true;
  }

  if (isEnter && modKey === 0) {
    ignoreOtherListeners = true;
  }

  if (btnNewChat && isEnter && modKey === 3) { // console.log('New Chat');
    clickMouseOn(btnNewChat);
    ignoreOtherListeners = true;
  }

  if (btnSubmit && isEnter && modKey === 1) { // console.log('Send');
    clickMouseOn(btnSubmit);
    ignoreOtherListeners = true;
  }

  if (ignoreOtherListeners) {
    skipActions(event);
    return false;
  }

  return true;
};