Auto Refresh on Network Errors

Automatically refreshes page when network errors occur

נכון ליום 07-10-2025. ראה הגרסה האחרונה.

אין להתקין סקריפט זה ישירות. זוהי ספריה עבור סקריפטים אחרים // @require https://update.greasyfork.org/scripts/551832/1673251/Auto%20Refresh%20on%20Network%20Errors.js

// ==UserScript==
// @name Auto Refresh on Network Errors
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Automatically refreshes page when network errors occur
// @author Assistant Pro
// @match *://*/*
// @grant none
// @run-at document-start
// ==/UserScript==

(function() {
    'use strict';

    const config = {
        enableConsoleLogs: true,
        refreshDelay: 5000, // 5 seconds delay before refresh
        maxRefreshAttempts: 10,
        checkInterval: 3000, // Check every 3 seconds
        retryDelay: 10000, // Wait 10 seconds between retries
        enableSoundAlert: false // Play sound when network recovers
    };

    let state = {
        refreshCount: 0,
        lastRefreshTime: 0,
        isNetworkError: false,
        lastCheckTime: Date.now()
    };

    // Network error patterns to detect
    const networkErrorPatterns = [
        "We're having trouble finding that site",
        "We can't connect to the server",
        "Try again later",
        "Check your network connection",
        "behind a firewall",
        "This site can't be reached",
        "Unable to connect",
        "Server not found",
        "Network Error",
        "ERR_CONNECTION_",
        "ERR_NAME_NOT_RESOLVED",
        "ERR_INTERNET_DISCONNECTED"
    ];

    // Check if current page shows network error
    function isNetworkErrorPage() {
        // Check page title
        const title = document.title.toLowerCase();
        if (title.includes("problem loading") || title.includes("not found") || title.includes("unable to connect")) {
            return true;
        }

        // Check body text content
        const bodyText = document.body.innerText.toLowerCase();
        for (const pattern of networkErrorPatterns) {
            if (bodyText.includes(pattern.toLowerCase())) {
                return true;
            }
        }

        // Check common error elements
        const errorSelectors = [
            '[class*="error"]',
            '[id*="error"]',
            '[class*="offline"]',
            '[id*="offline"]',
            '.network-error',
            '.dns-error',
            '.connection-error'
        ];

        for (const selector of errorSelectors) {
            const elements = document.querySelectorAll(selector);
            for (const element of elements) {
                const text = element.innerText.toLowerCase();
                for (const pattern of networkErrorPatterns) {
                    if (text.includes(pattern.toLowerCase())) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    // Check network connectivity
    function checkNetworkConnectivity() {
        return new Promise((resolve) => {
            // Method 1: Navigator online status
            if (!navigator.onLine) {
                resolve(false);
                return;
            }

            // Method 2: Try to fetch a small resource
            const testUrls = [
                'https://www.google.com/favicon.ico',
                'https://www.cloudflare.com/favicon.ico',
                'https://www.microsoft.com/favicon.ico'
            ];

            let successCount = 0;
            let completed = 0;

            testUrls.forEach(url => {
                fetch(url, { 
                    method: 'HEAD',
                    cache: 'no-cache',
                    mode: 'no-cors'
                })
                .then(() => {
                    successCount++;
                })
                .catch(() => {})
                .finally(() => {
                    completed++;
                    if (completed === testUrls.length) {
                        resolve(successCount > 0);
                    }
                });
            });

            // Timeout after 5 seconds
            setTimeout(() => {
                resolve(successCount > 0);
            }, 5000);
        });
    }

    // Perform smart refresh
    function performSmartRefresh() {
        const now = Date.now();
        const timeSinceLastRefresh = now - state.lastRefreshTime;

        // Don't refresh too frequently
        if (timeSinceLastRefresh < config.retryDelay) {
            if (config.enableConsoleLogs) console.log(`⏳ Too soon to refresh, waiting... (${Math.round((config.retryDelay - timeSinceLastRefresh)/1000)}s)`);
            return;
        }

        // Check if we've exceeded max attempts
        if (state.refreshCount >= config.maxRefreshAttempts) {
            if (config.enableConsoleLogs) console.log("❌ Max refresh attempts reached, stopping...");
            return;
        }

        state.refreshCount++;
        state.lastRefreshTime = now;
        state.isNetworkError = true;

        if (config.enableConsoleLogs) {
            console.log(`🔄 Auto-refresh attempt ${state.refreshCount}/${config.maxRefreshAttempts}`);
            console.log("🌐 Network error detected, refreshing page...");
        }

        // Play sound alert if enabled
        if (config.enableSoundAlert) {
            playNotificationSound();
        }

        // Refresh with a small delay
        setTimeout(() => {
            window.location.reload();
        }, config.refreshDelay);
    }

    // Play notification sound
    function playNotificationSound() {
        try {
            const audioContext = new (window.AudioContext || window.webkitAudioContext)();
            const oscillator = audioContext.createOscillator();
            const gainNode = audioContext.createGain();
            
            oscillator.connect(gainNode);
            gainNode.connect(audioContext.destination);
            
            oscillator.frequency.value = 800;
            oscillator.type = 'sine';
            
            gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
            gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.5);
            
            oscillator.start(audioContext.currentTime);
            oscillator.stop(audioContext.currentTime + 0.5);
        } catch (error) {
            // Sound not supported, continue silently
        }
    }

    // Main monitoring function
    function monitorNetworkStatus() {
        const now = Date.now();

        // Check if we're on a network error page
        if (isNetworkErrorPage()) {
            if (config.enableConsoleLogs && !state.isNetworkError) {
                console.log("🚨 Network error page detected!");
            }
            
            // Check if we actually have network connectivity
            checkNetworkConnectivity().then(isOnline => {
                if (isOnline) {
                    if (config.enableConsoleLogs) console.log("✅ Network is online, but page failed to load - refreshing...");
                    performSmartRefresh();
                } else {
                    if (config.enableConsoleLogs) console.log("🌐 Network is offline, waiting for connection...");
                    // Wait for network to come back online
                    setTimeout(monitorNetworkStatus, config.retryDelay);
                    return;
                }
            });
        } else {
            // Reset counter if page loaded successfully
            if (state.isNetworkError) {
                state.isNetworkError = false;
                if (config.enableConsoleLogs) console.log("✅ Page loaded successfully! Reset refresh counter.");
                state.refreshCount = 0;
            }
        }

        // Continue monitoring
        setTimeout(monitorNetworkStatus, config.checkInterval);
    }

    // Setup event listeners
    function setupEventListeners() {
        // Listen for online/offline events
        window.addEventListener('online', () => {
            if (config.enableConsoleLogs) console.log("🌐 Network connection restored!");
            if (state.isNetworkError) {
                if (config.enableConsoleLogs) console.log("🔄 Network restored, refreshing page...");
                setTimeout(() => {
                    window.location.reload();
                }, 2000);
            }
        });

        window.addEventListener('offline', () => {
            if (config.enableConsoleLogs) console.log("🌐 Network connection lost!");
            state.isNetworkError = true;
        });

        // Listen for page load errors
        window.addEventListener('error', (event) => {
            const error = event.error || event;
            if (error.toString().includes('Loading') || error.toString().includes('Network')) {
                if (config.enableConsoleLogs) console.log("🚨 Page load error detected");
                state.isNetworkError = true;
            }
        });

        // Listen for fetch errors
        const originalFetch = window.fetch;
        window.fetch = function(...args) {
            return originalFetch.apply(this, args)
                .catch(error => {
                    if (config.enableConsoleLogs) console.log("🌐 Fetch error:", error);
                    state.isNetworkError = true;
                    throw error;
                });
        };
    }

    // Initialize
    function init() {
        if (config.enableConsoleLogs) {
            console.log("🔄 Auto Refresh on Network Errors - Started");
            console.log("🔧 Will automatically refresh on network errors");
            console.log("🌐 Current network status:", navigator.onLine ? "ONLINE" : "OFFLINE");
        }

        setupEventListeners();
        
        // Start monitoring
        setTimeout(monitorNetworkStatus, 3000);

        // Add manual refresh button for testing (remove in production)
        if (config.enableConsoleLogs) {
            const button = document.createElement('button');
            button.innerHTML = '🔄 Test Refresh';
            button.style.position = 'fixed';
            button.style.top = '10px';
            button.style.right = '10px';
            button.style.zIndex = '9999';
            button.style.padding = '10px';
            button.style.background = '#007cba';
            button.style.color = 'white';
            button.style.border = 'none';
            button.style.borderRadius = '5px';
            button.style.cursor = 'pointer';
            button.onclick = () => {
                console.log("🧪 Manual refresh triggered");
                window.location.reload();
            };
            document.body.appendChild(button);
        }
    }

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