Instagram Image Context Menu

Custom context menu untuk Open New Tab & Save Image As di IG

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         Instagram Image Context Menu
// @namespace    http://tampermonkey.net/
// @version      4.0
// @description  Custom context menu untuk Open New Tab & Save Image As di IG
// @author       XIREN
// @match        *://*.instagram.com/*
// @grant        GM_download
// @grant        GM_openInTab
// ==/UserScript==

(function() {
    'use strict';

    // 1. Setup UI untuk Custom Context Menu
    const menu = document.createElement('div');
    menu.id = 'ig-custom-context-menu';
    menu.style.position = 'fixed';
    menu.style.backgroundColor = '#262626'; // Warna dark mode IG
    menu.style.border = '1px solid #363636';
    menu.style.borderRadius = '8px';
    menu.style.padding = '5px 0';
    menu.style.zIndex = '9999999';
    menu.style.display = 'none';
    menu.style.boxShadow = '0 4px 12px rgba(0,0,0,0.5)';
    menu.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';

    const createOption = (text) => {
        const opt = document.createElement('div');
        opt.innerText = text;
        opt.style.padding = '10px 20px';
        opt.style.color = '#fff';
        opt.style.cursor = 'pointer';
        opt.style.fontSize = '14px';
        opt.style.fontWeight = '500';
        opt.onmouseover = () => opt.style.backgroundColor = '#363636';
        opt.onmouseout = () => opt.style.backgroundColor = 'transparent';
        return opt;
    };

    const openBtn = createOption('🔎 Fullscreen View');
    const saveBtn = createOption('💾 Unduh Gambar JPG');

    menu.appendChild(openBtn);
    menu.appendChild(saveBtn);
    document.body.appendChild(menu);

    let currentImgUrl = '';

    // 2. Event Listener buat nangkap Klik Kanan (Context Menu)
    document.addEventListener('contextmenu', function(e) {
        let target = e.target;
        let img = null;

        // Cek target yang diklik, cari elemen <img> di level atasnya (buat nembus overlay IG)
        if (target.tagName.toLowerCase() === 'img') {
            img = target;
        } else {
            let parent = target.parentElement;
            // Naik maksimal 4 level DOM buat nyari gambar yang ditamengin
            for (let i = 0; i < 4; i++) {
                if (!parent) break;
                img = parent.querySelector('img');
                if (img) break;
                parent = parent.parentElement;
            }
        }

        // Kalau ketemu gambar dan bukan sekadar icon/foto profil kecil
        if (img && img.src && !img.src.includes('profile_pic')) {
            e.preventDefault(); // Blokir context menu bawaan browser
            currentImgUrl = img.src;

            // Atur posisi menu pas di koordinat mouse
            menu.style.left = `${e.clientX}px`;
            menu.style.top = `${e.clientY}px`;
            menu.style.display = 'block';
        } else {
            menu.style.display = 'none'; // Sembunyiin kalau klik di luar gambar
        }
    });

    // 3. Ilangin menu kalau klik kiri di sembarang tempat
    document.addEventListener('click', function(e) {
        if (e.target !== openBtn && e.target !== saveBtn) {
            menu.style.display = 'none';
        }
    });

    // 4. Aksi: Open in New Tab
    openBtn.addEventListener('click', function() {
        if (currentImgUrl) {
            GM_openInTab(currentImgUrl, { active: true });
            menu.style.display = 'none';
        }
    });

    // 5. Aksi: Save Image As (Otomatis force download)
    saveBtn.addEventListener('click', function() {
        if (currentImgUrl) {
            // Ekstrak ID/Nama file dari URL asli IG
            let rawUrl = currentImgUrl.split('?')[0];
            let fileName = rawUrl.substring(rawUrl.lastIndexOf('/') + 1) || `IG_IMG_${Date.now()}.jpg`;

            // Panggil API Tampermonkey buat maksa buka dialog download
            GM_download({
                url: currentImgUrl,
                name: fileName,
                saveAs: true // Mancing munculnya dialog "Save As..."
            });
            menu.style.display = 'none';
        }
    });

})();