☰

Gemini ðŸ›Ąïļ Enter Fix Pro

āļ›āđ‰āļ­āļ‡āļāļąāļ™ Enter āļŠāđˆāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ, āļĢāļ­āļ‡āļĢāļąāļš Enter āļ„āđ‰āļēāļ‡, āđāļĨāļ°āđ€āļ›āļĨāļĩāđˆāļĒāļ™āļŦāđ‰āļ­āļ‡/āđāļ—āđ‡āļšāđƒāļ™ Gemini āļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļī (Android āļĄāļ·āļ­āļ–āļ·āļ­)

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Gemini ðŸ›Ąïļ Enter Fix Pro
// @namespace    https://tampermonkey.local/gemini-enter-fix
// @version      1.4.0
// @description  āļ›āđ‰āļ­āļ‡āļāļąāļ™ Enter āļŠāđˆāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ, āļĢāļ­āļ‡āļĢāļąāļš Enter āļ„āđ‰āļēāļ‡, āđāļĨāļ°āđ€āļ›āļĨāļĩāđˆāļĒāļ™āļŦāđ‰āļ­āļ‡/āđāļ—āđ‡āļšāđƒāļ™ Gemini āļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļī (Android āļĄāļ·āļ­āļ–āļ·āļ­)
// @match        https://gemini.google.com/*
// @grant        none
// @license      MIT
// ==/UserScript==
(function () {
    'use strict';
    /** ================= CONFIG ================= **/
    const CONFIG = {
        DEBUG: true,
        NS: 'gemini-enterfix',
        RECHECK_INTERVAL: 2000, // ms, āļ•āļĢāļ§āļˆāļŠāļ­āļšāļŠāđˆāļ­āļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāđƒāļŦāļĄāđˆāļ—āļļāļ 2 āļ§āļīāļ™āļēāļ—āļĩ
    };
    /* ================== LOGGER ================== */
    function log(msg, type = "info") {
        try {
            if (!CONFIG.DEBUG) return;

            // āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ‚āđ‰āļ­āļ„āļ§āļēāļĄāđƒāļŦāđ‰āđāļ™āđˆāđƒāļˆāļ§āđˆāļēāđ€āļ›āđ‡āļ™ string āđ€āļŠāļĄāļ­
            const safeMsg = typeof msg === "string" ? msg : JSON.stringify(msg, null, 2);

            // āđ€āļ•āļĢāļĩāļĒāļĄ payload āļ—āļĩāđˆāļ›āļĨāļ­āļ”āļ āļąāļĒ
            const payload = {
                namespace: "LogCenter", // ✅ āļ•āđ‰āļ­āļ‡āļ•āļĢāļ‡āļāļąāļš CONFIG.NAMESPACE āđƒāļ™ Logs Center
                from: (typeof GM_info !== "undefined" && GM_info.script && GM_info.script.name) 
                ? GM_info.script.name 
                : "UnknownScript",
                type,
                time: new Date().toLocaleTimeString("th-TH", { hour12: false }),
                stack: new Error().stack,
                message: safeMsg
            };

            // ✅ āļŠāđˆāļ‡ log āđ„āļ›āļĒāļąāļ‡ Logs Center
            window.postMessage(payload, "*");
        } catch (err) {
            console.error("Logger error:", err);
        }
    }
    /** ================= UTILITIES ================= **/
    function insertNewLine(el) {
        try {
            // āđƒāļŠāđ‰ execCommand āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰ Quill āļĢāļ­āļ‡āļĢāļąāļš
            el.focus();
            const ok = document.execCommand('insertLineBreak', false);
            if (!ok) {
                const sel = el.ownerDocument.getSelection();
                if (!sel || !sel.rangeCount) return;
                const range = sel.getRangeAt(0);
                const br = el.ownerDocument.createElement('br');
                range.deleteContents();
                range.insertNode(br);
                range.setStartAfter(br);
                range.setEndAfter(br);
                sel.removeAllRanges();
                sel.addRange(range);
            }
            el.dispatchEvent(new InputEvent('input', { bubbles: true }));
        } catch (err) {
            log(`insertNewLine error: ${err.message}`, 'error');
        }
    }
    /** ================= KEY HANDLER ================= **/
    function handleKey(e) {
        try {
            const el = document.activeElement;
            if (!el || !el.isContentEditable) return;
            // Enter āļ˜āļĢāļĢāļĄāļ”āļē = āļ‚āļķāđ‰āļ™āļšāļĢāļĢāļ—āļąāļ”āđƒāļŦāļĄāđˆ
            if (e.key === 'Enter' && !e.ctrlKey && !e.shiftKey) {
                e.preventDefault();
                e.stopImmediatePropagation();
                insertNewLine(el);
            }
            // Ctrl/Shift + Enter = āļŠāđˆāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ
            else if (e.key === 'Enter' && (e.ctrlKey || e.shiftKey)) {
                log('ðŸ“Ļ āļŠāđˆāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ (Ctrl/Shift+Enter)');
            }
        } catch (err) {
            log(`handleKey error: ${err.message}`, 'error');
        }
    }
    /** ================= EVENT ATTACH ================= **/
    function attachEditor(el) {
        if (!el || el.dataset[`${CONFIG.NS}-active`] === '1') return;
        el.dataset[`${CONFIG.NS}-active`] = '1';
        // āđƒāļŠāđ‰ keydown (āđ„āļĄāđˆāđƒāļŠāđ‰ keypress āđ€āļžāļĢāļēāļ° Quill intercept)
        el.addEventListener('keydown', handleKey, { capture: true, passive: false });
        log('✅ āļœāļđāļ Event Keydown āļŠāļģāđ€āļĢāđ‡āļˆ');
    }
    function scanEditors(root = document) {
        const boxes = root.querySelectorAll('.ql-editor,[contenteditable="true"],div[role="textbox"]');
        boxes.forEach(attachEditor);
    }
    /** ================= AUTO RE-ATTACH ================= **/
    // debounce āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āđ€āļ›āļĨāļĩāđˆāļĒāļ™āļŦāđ‰āļ­āļ‡āđāļĨāđ‰āļ§ reattach āđ„āļ”āđ‰āđ€āļĢāđ‡āļ§āđāļ•āđˆāđ„āļĄāđˆāļ–āļĩāđˆāđ€āļāļīāļ™
    let reattachTimer = null;
    function scheduleReattach() {
        if (reattachTimer) return;
        reattachTimer = setTimeout(() => {
            reattachTimer = null;
            scanEditors(document);
        }, 300);
    }
    // āļŠāļąāļ‡āđ€āļāļ• DOM āđ€āļ›āļĨāļĩāđˆāļĒāļ™ (āđ€āļ›āļĨāļĩāđˆāļĒāļ™āđāļ—āđ‡āļš/āļŦāđ‰āļ­āļ‡)
    const observer = new MutationObserver(scheduleReattach);
    observer.observe(document, { childList: true, subtree: true });
    // āļ•āļĢāļ§āļˆāļ‹āđ‰āļģāļ—āļļāļāđ† N āļ§āļīāļ™āļēāļ—āļĩ (āļ›āđ‰āļ­āļ‡āļāļąāļ™āļāļĢāļ“āļĩ Shadow DOM āđ‚āļŦāļĨāļ”āļŠāđ‰āļē)
    setInterval(() => {
        scanEditors(document);
    }, CONFIG.RECHECK_INTERVAL);
    /** ================= INIT ================= **/
    window.addEventListener('keydown', handleKey, { capture: true, passive: false });
    scanEditors(document);
    log('ðŸ§Đ Gemini Enter Fix Pro āļžāļĢāđ‰āļ­āļĄāđƒāļŠāđ‰āļ‡āļēāļ™āđāļĨāđ‰āļ§');
})();