Imgilism - Image Uploader

Right-click image upload to Mobilism image hosting with different size options

// ==UserScript==
// @name         Imgilism - Image Uploader
// @namespace    http://tampermonkey.net/
// @version      1.0.9
// @description  Right-click image upload to Mobilism image hosting with different size options
// @author       EyezOnly (converted to userscript)
// @match        http://*/*
// @match        https://*/*
// @grant        GM_xmlhttpRequest
// @grant        GM_registerMenuCommand
// @grant        GM_notification
// @grant        GM_setClipboard
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';
    
    let contextMenuShown = false;
    let contextMenuDiv = null;
    let currentImageUrl = null;
    
    // Create context menu styles
    const style = document.createElement('style');
    style.textContent = `
        .imgilism-context-menu {
            position: fixed;
            background: #fff;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            z-index: 10000;
            min-width: 150px;
            font-family: Arial, sans-serif;
            font-size: 14px;
        }
        
        .imgilism-menu-item {
            padding: 8px 12px;
            cursor: pointer;
            border-bottom: 1px solid #eee;
            transition: background-color 0.2s;
        }
        
        .imgilism-menu-item:hover {
            background-color: #f0f0f0;
        }
        
        .imgilism-menu-item:last-child {
            border-bottom: none;
        }
        
        .imgilism-menu-header {
            padding: 8px 12px;
            background: #f5f5f5;
            font-weight: bold;
            border-bottom: 1px solid #ddd;
            color: #333;
        }
        
        .imgilism-progress {
            padding: 8px 12px;
            background: #e8f4f8;
            color: #0066cc;
            font-style: italic;
        }
    `;
    document.head.appendChild(style);
    
    // Create context menu
    function createContextMenu() {
        contextMenuDiv = document.createElement('div');
        contextMenuDiv.className = 'imgilism-context-menu';
        contextMenuDiv.innerHTML = `
            <div class="imgilism-menu-header">📸 Imgilism Upload</div>
            <div class="imgilism-menu-item" data-action="single">Single [320x240]</div>
            <div class="imgilism-menu-item" data-action="multiple">Multiple [240x160]</div>
            <div class="imgilism-menu-item" data-action="large">Large [500xAuto]</div>
        `;
        document.body.appendChild(contextMenuDiv);
        
        // Add click handlers
        contextMenuDiv.addEventListener('click', function(e) {
            const action = e.target.dataset.action;
            if (action && currentImageUrl) {
                hideContextMenu();
                uploadImage(currentImageUrl, action);
            }
        });
    }
    
    // Show context menu
    function showContextMenu(x, y, imageUrl) {
        currentImageUrl = imageUrl;
        
        if (!contextMenuDiv) {
            createContextMenu();
        }
        
        contextMenuDiv.style.left = x + 'px';
        contextMenuDiv.style.top = y + 'px';
        contextMenuDiv.style.display = 'block';
        contextMenuShown = true;
    }
    
    // Hide context menu
    function hideContextMenu() {
        if (contextMenuDiv) {
            contextMenuDiv.style.display = 'none';
        }
        contextMenuShown = false;
        currentImageUrl = null;
    }
    
    // Upload image function
    function uploadImage(imageUrl, sizeOption) {
        console.log('Starting image upload for:', imageUrl, 'with size option:', sizeOption);
        
        // Show progress
        if (contextMenuDiv) {
            contextMenuDiv.innerHTML = '<div class="imgilism-progress">Uploading image...</div>';
            contextMenuDiv.style.display = 'block';
        }
        
        // Configure size options
        let height, width, responseId;
        switch(sizeOption) {
            case 'single':
                height = '320';
                width = '';
                responseId = 'codehtml';
                break;
            case 'multiple':
                height = '240';
                width = '160';
                responseId = 'codelbb';
                break;
            case 'large':
                height = '500';
                width = '';
                responseId = 'codehtml';
                break;
        }
        
        console.log('Upload config:', { height, width, responseId });
        
        // Fetch the image
        GM_xmlhttpRequest({
            method: 'GET',
            url: imageUrl,
            responseType: 'blob',
            timeout: 30000, // 30 second timeout
            onload: function(response) {
                console.log('Image fetch response:', response.status, response.statusText);
                
                if (response.status === 200) {
                    const blob = response.response;
                    const fileName = imageUrl.split(/[?#]/)[0].split('/').pop() || 'image.jpg';
                    
                    console.log('Processing blob:', blob.size, 'bytes, filename:', fileName);
                    
                    // Create a proper File object like the Chrome extension does
                    const file = new File([blob], fileName, { type: blob.type });
                    
                    // Create FormData exactly like the Chrome extension
                    const formData = new FormData();
                    formData.append('links', '');
                    formData.append('imgUrl', '');
                    formData.append('fileName[]', fileName);
                    formData.append('Search files', 'Browse');
                    formData.append('file[]', file); // Use File object instead of blob
                    formData.append('alt[]', fileName.replace(/[-_]/g, ' ').replace(/\.[^.]*$/, ''));
                    formData.append('private[0]', '1');
                    formData.append('new_height[]', height);
                    formData.append('new_width[]', width);
                    formData.append('submit', 'Upload');
                    
                    console.log('Uploading to Mobilism...');
                    
                    // Upload to Mobilism
                    GM_xmlhttpRequest({
                        method: 'POST',
                        url: 'https://images.mobilism.org/upload.php',
                        data: formData,
                        timeout: 60000, // 60 second timeout for upload
                        onload: function(uploadResponse) {
                            console.log('Upload response:', uploadResponse.status, uploadResponse.statusText);
                            console.log('Response text length:', uploadResponse.responseText.length);
                            
                            hideContextMenu();
                            
                            if (uploadResponse.status === 200) {
                                try {
                                    // Parse response
                                    const parser = new DOMParser();
                                    const responseDoc = parser.parseFromString(uploadResponse.responseText, 'text/html');
                                    const urlElement = responseDoc.getElementById(responseId);
                                    
                                    console.log('Looking for element with ID:', responseId);
                                    console.log('Found element:', urlElement);
                                    
                                    if (urlElement && urlElement.value && urlElement.value.trim()) {
                                        const uploadedUrl = urlElement.value.trim();
                                        console.log('Extracted URL:', uploadedUrl);
                                        
                                        // Copy to clipboard
                                        GM_setClipboard(uploadedUrl);
                                        
                                        // Show notification
                                        GM_notification({
                                            title: 'Imgilism Upload Success',
                                            text: 'Image uploaded! URL copied to clipboard.',
                                            timeout: 3000
                                        });
                                        
                                        // Also show prompt for backup
                                        setTimeout(() => {
                                            prompt('Image uploaded successfully! URL (also copied to clipboard):', uploadedUrl);
                                        }, 100);
                                    } else {
                                        console.error('Failed to find URL element or empty value');
                                        console.log('Available elements with IDs:', Array.from(responseDoc.querySelectorAll('[id]')).map(el => el.id));
                                        
                                        // Try to find any textarea or input that might contain the URL
                                        const allInputs = responseDoc.querySelectorAll('input, textarea');
                                        console.log('All inputs found:', allInputs.length);
                                        
                                        GM_notification({
                                            title: 'Imgilism Upload Failed',
                                            text: 'Failed to extract image URL from response. Check console for details.',
                                            timeout: 5000
                                        });
                                    }
                                } catch (parseError) {
                                    console.error('Error parsing response:', parseError);
                                    GM_notification({
                                        title: 'Imgilism Upload Failed',
                                        text: 'Error parsing upload response: ' + parseError.message,
                                        timeout: 3000
                                    });
                                }
                            } else {
                                console.error('Upload failed with status:', uploadResponse.status);
                                GM_notification({
                                    title: 'Imgilism Upload Failed',
                                    text: 'Upload request failed with status: ' + uploadResponse.status,
                                    timeout: 3000
                                });
                            }
                        },
                        onerror: function(error) {
                            console.error('Upload error:', error);
                            hideContextMenu();
                            GM_notification({
                                title: 'Imgilism Upload Error',
                                text: 'Upload failed: ' + (error.message || 'Network error'),
                                timeout: 3000
                            });
                        },
                        ontimeout: function() {
                            console.error('Upload timeout');
                            hideContextMenu();
                            GM_notification({
                                title: 'Imgilism Upload Timeout',
                                text: 'Upload request timed out. Please try again.',
                                timeout: 3000
                            });
                        }
                    });
                } else {
                    console.error('Failed to fetch image:', response.status, response.statusText);
                    hideContextMenu();
                    GM_notification({
                        title: 'Imgilism Error',
                        text: 'Failed to fetch image: ' + response.status + ' ' + response.statusText,
                        timeout: 3000
                    });
                }
            },
            onerror: function(error) {
                console.error('Image fetch error:', error);
                hideContextMenu();
                GM_notification({
                    title: 'Imgilism Error',
                    text: 'Failed to fetch image: ' + (error.message || 'Network error'),
                    timeout: 3000
                });
            },
            ontimeout: function() {
                console.error('Image fetch timeout');
                hideContextMenu();
                GM_notification({
                    title: 'Imgilism Error',
                    text: 'Image fetch timed out. Please try again.',
                    timeout: 3000
                });
            }
        });
    }
    
    // Event listeners
    document.addEventListener('contextmenu', function(e) {
        if (e.target.tagName === 'IMG' && e.target.src) {
            e.preventDefault();
            // Skip menu, go straight to Large upload
            uploadImage(e.target.src, 'large');
        } else if (contextMenuShown) {
            hideContextMenu();
        }
    });
    
    document.addEventListener('click', function(e) {
        if (contextMenuShown && !contextMenuDiv.contains(e.target)) {
            hideContextMenu();
        }
    });
    
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape' && contextMenuShown) {
            hideContextMenu();
        }
    });
    
    // Register menu commands for manual access
    GM_registerMenuCommand('Upload Image (Single 320x240)', function() {
        const imageUrl = prompt('Enter image URL:');
        if (imageUrl) {
            uploadImage(imageUrl, 'single');
        }
    });
    
    GM_registerMenuCommand('Upload Image (Multiple 240x160)', function() {
        const imageUrl = prompt('Enter image URL:');
        if (imageUrl) {
            uploadImage(imageUrl, 'multiple');
        }
    });
    
    GM_registerMenuCommand('Upload Image (Large 500xAuto)', function() {
        const imageUrl = prompt('Enter image URL:');
        if (imageUrl) {
            uploadImage(imageUrl, 'large');
        }
    });
    
    console.log('Imgilism userscript loaded successfully!');
})();