Gemini Model & Brain Switcher

Yeni arayüzdeki data-active (hover) tuzağı düzeltildi. 1. element dahil tüm modellere sorunsuz geçer.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

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

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

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

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

Advertisement:

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.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

Advertisement:

// ==UserScript==
// @name         Gemini Model & Brain Switcher
// @namespace    https://github.com/FrknKoseoglu
// @version      4.3
// @description  Yeni arayüzdeki data-active (hover) tuzağı düzeltildi. 1. element dahil tüm modellere sorunsuz geçer.
// @author       frknkoseoglu
// @match        https://gemini.google.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    let isProcessing = false;

    // Ana tetikleyici
    const MAIN_MENU_SELECTORS = `
        .model-picker-container,
        [data-test-id*="mode-switch"],
        [data-test-id*="model-switch"],
        [data-test-id*="chat-model"],
        [data-test-id="bard-mode-menu-button"],
        .gds-mode-switch-button
    `;

    const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

    const hideUpgradeButton = () => {
        const style = document.createElement('style');
        style.type = 'text/css';
        style.textContent = `
            .upgrade-container, .g1-upsell-container, gem-menu-item[value="upgrade"] {
                display: none !important;
            }
        `;
        document.head.appendChild(style);
    };

    hideUpgradeButton();

    const waitForElements = async (selector, timeout = 1500) => {
        let elapsed = 0;
        const interval = 20;
        while (elapsed < timeout) {
            const elements = Array.from(document.querySelectorAll(selector)).filter(el => {
                return el.offsetParent !== null || el.getBoundingClientRect().width > 0;
            });
            if (elements.length > 0) return elements;
            await delay(interval);
            elapsed += interval;
        }
        throw new Error(`Element bulunamadı: ${selector}`);
    };

    const simulateClick = (element) => {
        if (!element) return;
        element.focus();
        element.click();
    };

    const closeMenu = () => {
        document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true, cancelable: true }));
        document.body.click();
    };

    // --------------------------------------------------------
    // 1. İŞLEM: TEKERLEK KAYDIRMA (Model Değişimi - Kesin Çözüm)
    // --------------------------------------------------------
    document.addEventListener('wheel', async function(e) {
        if (isProcessing) return;

        const modelContainer = e.target.closest(MAIN_MENU_SELECTORS);
        if (!modelContainer) return;

        e.preventDefault();
        e.stopPropagation();

        isProcessing = true;
        const direction = e.deltaY > 0 ? 1 : -1;

        try {
            const triggerButton = modelContainer.querySelector('button') || modelContainer;
            
            if (triggerButton.getAttribute('aria-expanded') !== 'true') {
                simulateClick(triggerButton);
                await delay(150); 
            }
            
            const buttons = await waitForElements('gem-menu-item[data-mode-id]');
            
            // KRİTİK DÜZELTME: data-active kontrolü kaldırıldı! 
            // Sadece gerçek seçili (selected) sınıflara ve check ikonuna bakılıyor.
            let currentIndex = buttons.findIndex(btn => 
                btn.classList.contains('selected') || 
                btn.querySelector('.selected') || 
                btn.querySelector('mat-icon[fonticon="check"]')
            );
            
            // Eğer hiçbir şey bulunamazsa varsayılan olarak 0 (ilk element) kabul et
            if (currentIndex === -1) currentIndex = 0;
            
            let nextIndex = currentIndex + direction;
            if (nextIndex >= buttons.length) nextIndex = 0;
            if (nextIndex < 0) nextIndex = buttons.length - 1;

            simulateClick(buttons[nextIndex]);

        } catch (err) {
            console.warn("Gemini Switcher Hatası (Model Scroll):", err);
            closeMenu();
        } finally {
            // Artçı scroll sinyallerini sönümlemek için 450ms soğuma
            await delay(450);
            isProcessing = false;
        }
    }, { passive: false, capture: true });

    // --------------------------------------------------------
    // 2. İŞLEM: BUTON RENGİNİ DÜZENLEME
    // --------------------------------------------------------
    const updateBrainButtonState = () => {
        const brainBtn = document.getElementById('gemini-brain-btn');
        const modelContainer = document.querySelector(MAIN_MENU_SELECTORS);
        
        if (brainBtn && modelContainer) {
            if (modelContainer.textContent.includes('Uzatılmış')) {
                brainBtn.style.filter = 'none';
                brainBtn.style.opacity = '1';
            } else {
                brainBtn.style.filter = 'grayscale(100%)';
                brainBtn.style.opacity = '0.7';
            }
        }
    };

    // --------------------------------------------------------
    // 3. İŞLEM: "🧠" BUTONU ENJEKSİYONU
    // --------------------------------------------------------
    const injectBrainButton = () => {
        let brainBtn = document.getElementById('gemini-brain-btn');
        const targetWrapper = document.querySelector('.trailing-actions-wrapper.with-model-picker');
        const modelContainer = document.querySelector('.model-picker-container'); 
        
        if (!brainBtn && targetWrapper && modelContainer) {
            brainBtn = document.createElement('button');
            brainBtn.id = 'gemini-brain-btn';
            brainBtn.textContent = '🧠';
            brainBtn.title = 'Düşünme Düzeyini Değiştir (Standart / Uzatılmış)';
            
            brainBtn.style.cssText = `
                background: transparent !important;
                border: none !important;
                font-size: 1.4rem !important;
                cursor: pointer !important;
                margin: 0 !important; 
                padding: 6px 10px !important;
                border-radius: 50% !important;
                display: flex !important;
                align-items: center !important;
                justify-content: center !important;
                transition: all 0.2s !important;
                user-select: none !important;
                flex-shrink: 0 !important;
                z-index: 9999 !important;
            `;

            brainBtn.onmouseenter = () => { brainBtn.style.backgroundColor = 'rgba(128, 128, 128, 0.1)'; };
            brainBtn.onmouseleave = () => { brainBtn.style.backgroundColor = 'transparent'; };
            brainBtn.onmousedown = () => { brainBtn.style.transform = 'scale(0.9)'; };
            brainBtn.onmouseup = () => { brainBtn.style.transform = 'scale(1)'; };

            brainBtn.onclick = async (e) => {
                e.preventDefault();
                e.stopPropagation();

                if (isProcessing) return;
                isProcessing = true;

                try {
                    const clickableMenu = document.querySelector(MAIN_MENU_SELECTORS);
                    const mainTriggerButton = clickableMenu.querySelector('button') || clickableMenu;

                    if (mainTriggerButton.getAttribute('aria-expanded') !== 'true') {
                        simulateClick(mainTriggerButton);
                        await delay(150); 
                    }

                    const thinkingHeaders = await waitForElements('gem-menu-item[value="thinking_level"]');
                    const headerButton = thinkingHeaders[0];
                    
                    if (headerButton.getAttribute('aria-expanded') !== 'true') {
                        simulateClick(headerButton);
                        await delay(150); 
                    }

                    const thinkingOptions = await waitForElements('gem-menu-item:not([data-mode-id]):not([value="thinking_level"])');
                    
                    // Aynı düzeltme kuralı buradaki seçici için de uygulandı
                    let currentIndex = thinkingOptions.findIndex(btn => 
                        btn.classList.contains('selected') || 
                        btn.querySelector('.selected') || 
                        btn.querySelector('mat-icon[fonticon="check"]')
                    );
                    if (currentIndex === -1) currentIndex = 0;
                    
                    let nextIndex = currentIndex + 1;
                    if (nextIndex >= thinkingOptions.length) nextIndex = 0;

                    simulateClick(thinkingOptions[nextIndex]);
                    await delay(150); 

                    closeMenu();

                } catch (err) {
                    console.warn("Gemini Switcher Hatası (Brain Butonu):", err);
                    closeMenu();
                } finally {
                    await delay(300);
                    isProcessing = false;
                }
            };

            modelContainer.after(brainBtn);
        }

        updateBrainButtonState();
    };

    const init = () => {
        injectBrainButton();
        setInterval(injectBrainButton, 1000);
    };

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();