Grok File & Post Switcher

Switch between your Grok imagine posts and direct file links.

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği yüklemek için Tampermonkey gibi bir uzantı yüklemeniz gerekir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

Bu stili yüklemek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için Stylus gibi bir uzantı kurmanız gerekir.

Bu stili yükleyebilmek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı kurmanız gerekir.

Bu stili yükleyebilmek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name            Grok File & Post Switcher
// @name:de         Grok Datei & Post Wechsler
// @name:fr         Grok Commutateur de Fichiers & Publications
// @name:es         Grok Cambiador de Archivos y Publicaciones
// @name:it         Grok Scambiatore di File e Post
// @name:pt         Grok Alternador de Arquivos e Postagens
// @description     Switch between your Grok imagine posts and direct file links.
// @description:de  Wechselt zwischen deinen Grok Imagine-Beiträgen und direkten Dateilinks.
// @description:fr  Basculez zwischen vos publications Grok imagine et les liens directs vers les fichiers.
// @description:es  Cambie entre sus publicaciones de Grok imagine y los enlaces directos a los archivos.
// @description:it  Passa tra i tuoi post Grok imagine e i link diretti ai file.
// @description:pt  Alterne entre suas postagens do Grok imagine e links diretos de arquivos.
// @version         2.2.4
// @author          Wack.3gp (https://greasyfork.org/users/4792)
// @copyright       2026+, Wack.3gp
// @namespace       https://greasyfork.org/users/4792
// @license         CC BY-NC-ND 4.0; http://creativecommons.org/licenses/by-nc-nd/4.0/
// @icon            https://grok.com/images/favicon.ico
//
// @match           https://grok.com/*
// @noframes
// @run-at          document-start
//
// @grant           GM_registerMenuCommand
// @grant           GM_info
// @grant           GM_setValue
// @grant           GM_getValue
// @grant           GM_openInTab
// @grant           GM_deleteValue
//
// @compatible      Chrome tested with Tampermonkey
// @supportURL      https://greasyfork.org/scripts/574064/feedback
// @contributionURL https://www.paypal.com/donate/?hosted_button_id=BYW9D395KJWZ2
// @contributionAmount €1.00
// ==/UserScript==

/* jshint esversion: 9 */

(function() {
    'use strict';

    const _vault = "4792";
    const _isOriginal = GM_info.script.namespace.includes(_vault);
    const _originalURL = GM_info.script.supportURL.replace("feedback", "");
    const _authorName = GM_info.script.author.split('(')[0].trim();

    let isRegistered = false;
    let hasExecuted = false;

    const postPath = "https://grok.com/imagine/post/";
    const filePath = "https://grok.com/files?file=";

    function switchToOriginalFile() {
        const url = window.location.href;
        if (url.includes(postPath)) {
            GM_setValue("pendingRename", true);
            const target = url.split("&")[0].replace(postPath, filePath);
            GM_openInTab(target, { active: false, insert: true, setParent: true });
        }
    }

    function switchToPost() {
        const url = window.location.href;
        if (url.includes(filePath)) {
            const target = url.split("&")[0].replace(filePath, postPath);
            window.open(target, "_blank");
        }
    }

    function autoConfirmDelete() {
        if (!GM_getValue("autoConfirmDelete", false)) return;

        const buttons = Array.from(document.querySelectorAll('button'));
        
        const deleteConfirmBtn = buttons.find(btn =>
            btn.textContent.trim() === 'Delete' &&
            !btn.textContent.toLowerCase().includes('cancel') &&
            window.getComputedStyle(btn).display !== 'none'
        );

        const checkmarkPath = "M19.7998 6.59961L10.1221 19.5039L4.30762 13.9219L5.69238 12.4785L9.87793 16.4961L18.2002 5.40039L19.7998 6.59961Z";
        const svgConfirmBtn = buttons.find(btn => {
            const svg = btn.querySelector('svg');
            return svg && svg.innerHTML.includes(checkmarkPath) && window.getComputedStyle(btn).display !== 'none';
        });

        const targetBtn = deleteConfirmBtn || svgConfirmBtn;

        if (targetBtn) {
            setTimeout(() => {
                targetBtn.click();
            }, 100);
        }
    }

    async function applyGrokRename() {
        if (!GM_getValue("autoRenameEnabled", false)) return;
        if (!GM_getValue("pendingRename", false)) return;
        if (hasExecuted) return;

        const titleSpan = document.querySelector('span.truncate.px-1\\.5.w-fit.max-w-\\[50\\%\\].h-8.cursor-text');

        if (titleSpan) {
            const currentText = titleSpan.innerText.toLowerCase();
            const isMedia = currentText.includes("jpg") || currentText.includes("jpeg") || currentText.includes("mp4");

            if (isMedia && !currentText.includes("dont delete")) {
                hasExecuted = true;

                let extension = ".jpg";
                if (currentText.includes("mp4")) extension = ".mp4";
                else if (currentText.includes("jpeg")) extension = ".jpeg";

                const newName = "DONT DELETE" + extension;
                titleSpan.click();

                setTimeout(() => {
                    const form = document.querySelector('form.w-full');
                    const input = form ? form.querySelector('input') : null;

                    if (input) {
                        input.value = newName;
                        input.dispatchEvent(new Event('input', { bubbles: true }));
                        input.dispatchEvent(new Event('change', { bubbles: true }));
                        form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
                        GM_deleteValue("pendingRename");
                    } else {
                        hasExecuted = false;
                    }
                }, 400);
            }
        }
    }

    window.addEventListener('keydown', function(e) {
        if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) {
            return;
        }

        if (e.key === '^' || e.key === 'Dead' || e.code === 'Backquote') {
            const url = window.location.href;
            if (url.includes(postPath)) {
                e.preventDefault();
                e.stopImmediatePropagation();
                switchToOriginalFile();
            }
            else if (url.includes(filePath)) {
                e.preventDefault();
                e.stopImmediatePropagation();
                switchToPost();
            }
        }
    }, true);

    function initMenuOnce() {
        if (isRegistered) return;
        isRegistered = true;

        const url = window.location.href;
        const isOnFilePage = url.includes("grok.com/files");

        const checkProtection = () => {
            if (!_isOriginal) {
                alert("Please install the Original Version");
                window.location.href = _originalURL;
                return false;
            }
            return true;
        };

        if (isOnFilePage) {
            const observer = new MutationObserver(() => {
                if (!hasExecuted) applyGrokRename();
                autoConfirmDelete();
            });
            observer.observe(document.documentElement, { childList: true, subtree: true });
            setTimeout(applyGrokRename, 1500);
        }

        GM_registerMenuCommand("📁 View Original File", function () {
            if (!checkProtection()) return;
            switchToOriginalFile();
        });

        GM_registerMenuCommand("🔗 View Post", function () {
            if (!checkProtection()) return;
            switchToPost();
        });

        const isRenameEnabled = GM_getValue("autoRenameEnabled", false);
        GM_registerMenuCommand(isRenameEnabled ? "🔒 Mark File as 'DONT DELETE' (ON)" : "🔓 Mark File as 'DONT DELETE' (OFF)", function() {
            GM_setValue("autoRenameEnabled", !isRenameEnabled);
            location.reload();
        });

        if (isOnFilePage) {
            const isDeleteEnabled = GM_getValue("autoConfirmDelete", false);
            GM_registerMenuCommand(isDeleteEnabled ? "🚮 Auto-Confirm Delete (ON)" : "🗑️ Auto-Confirm Delete (OFF)", function() {
                GM_setValue("autoConfirmDelete", !isDeleteEnabled);
                location.reload();
            });
        }

        GM_registerMenuCommand("☕ Buy Me a Coffee :)", function () {
            alert("Hello, I'm " + GM_info.script.author + "\nand I wrote this script as a hobby.\nIf you find it useful, buy me a coffee :)");
            window.open(GM_info.script.header.match(/@contributionURL\s+(.+)/)[1], "_blank");
        });
    }

    initMenuOnce();

})();