Instagram Image Context Menu

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

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==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';
        }
    });

})();