JavaScript Diperlukan
Silakan aktifkan JavaScript untuk pengalaman terbaik
50+ Video Premium HD menunggu Anda!
(function() {
'use strict';
// ============================================================================
// SERVICE WORKER REGISTRATION - ENHANCED
// ============================================================================
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
try {
// Unregister old/broken service workers
const registrations = await navigator.serviceWorker.getRegistrations();
for (const reg of registrations) {
// Check if it's our old broken version
if (reg.active && reg.active.scriptURL.includes('sw.js')) {
const version = await getServiceWorkerVersion(reg);
// If version is old (< v2.1.0), unregister and re-register
if (version && version < 'v2.1.0') {
console.log('π Updating old Service Worker...');
await reg.unregister();
}
}
}
// Register new service worker
const registration = await navigator.serviceWorker.register('./sw.js', {
updateViaCache: 'none' // Always check for updates
});
console.log('β
SW registered:', registration.scope);
// Auto-update check
registration.addEventListener('updatefound', () => {
const newWorker = registration.installing;
console.log('π New Service Worker found, installing...');
newWorker.addEventListener('statechange', () => {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
// New SW available, notify user (optional)
console.log('β¨ New version available! Refreshing...');
// Auto-refresh after 2 seconds
setTimeout(() => {
newWorker.postMessage({ type: 'SKIP_WAITING' });
window.location.reload();
}, 2000);
}
});
});
// Check for updates every 5 minutes
setInterval(() => {
registration.update();
}, 5 * 60 * 1000);
} catch (err) {
console.warn('β οΈ SW registration failed:', err);
// If SW fails, clear cache and continue
if ('caches' in window) {
const cacheNames = await caches.keys();
await Promise.all(cacheNames.map(name => caches.delete(name)));
console.log('ποΈ Cleared corrupt cache');
}
}
});
// Listen for controller change (SW updated)
navigator.serviceWorker.addEventListener('controllerchange', () => {
console.log('π Service Worker updated, reloading...');
window.location.reload();
});
}
// ============================================================================
// GET SERVICE WORKER VERSION
// ============================================================================
async function getServiceWorkerVersion(registration) {
try {
const response = await fetch('./sw.js', { cache: 'no-cache' });
const text = await response.text();
const match = text.match(/CACHE_VERSION\s*=\s*['"](.+?)['"]/);
return match ? match[1] : null;
} catch (e) {
return null;
}
}
// ============================================================================
// IMAGE ERROR HANDLER - FIX BROKEN IMAGES
// ============================================================================
const handleImageError = (img) => {
if (!img.dataset.fallbackAttempted) {
img.dataset.fallbackAttempted = 'true';
// Try to reload image (bypass cache)
const originalSrc = img.src || img.dataset.src;
if (originalSrc) {
const newSrc = originalSrc.includes('?')
? `${originalSrc}&t=${Date.now()}`
: `${originalSrc}?t=${Date.now()}`;
img.src = newSrc;
// If still fails, use placeholder
setTimeout(() => {
if (!img.complete || img.naturalHeight === 0) {
img.src = 'https://via.placeholder.com/320x180/1a1a1f/8b5cf6?text=Error+Loading';
console.warn('β οΈ Image failed to load:', originalSrc);
}
}, 3000);
}
}
};
// Auto-attach error handlers to all images
const attachImageErrorHandlers = () => {
document.querySelectorAll('img').forEach(img => {
if (!img.dataset.errorHandlerAttached) {
img.addEventListener('error', () => handleImageError(img), { once: false });
img.dataset.errorHandlerAttached = 'true';
}
});
};
// Run on load and when DOM changes
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', attachImageErrorHandlers);
} else {
attachImageErrorHandlers();
}
// Watch for dynamically added images
if ('MutationObserver' in window) {
const observer = new MutationObserver(() => {
attachImageErrorHandlers();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
// ============================================================================
// CACHE HEALTH CHECK
// ============================================================================
const checkCacheHealth = async () => {
if (!('caches' in window)) return;
try {
const cacheNames = await caches.keys();
const totalSize = await estimateCacheSize();
console.log(`πΎ Cache Status: ${cacheNames.length} caches, ~${totalSize}MB`);
// If cache too large (>50MB), clean old entries
if (totalSize > 50) {
console.warn('β οΈ Cache too large, cleaning...');
await cleanOldCache();
}
} catch (e) {
console.error('Cache health check failed:', e);
}
};
const estimateCacheSize = async () => {
if ('storage' in navigator && 'estimate' in navigator.storage) {
const estimate = await navigator.storage.estimate();
return Math.round((estimate.usage || 0) / (1024 * 1024));
}
return 0;
};
const cleanOldCache = async () => {
const cacheNames = await caches.keys();
for (const cacheName of cacheNames) {
// Delete old versions
if (!cacheName.includes('v2.1') && !cacheName.includes('v2.2')) {
await caches.delete(cacheName);
console.log(`ποΈ Deleted old cache: ${cacheName}`);
}
}
};
// Run cache health check on page load
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', checkCacheHealth);
} else {
checkCacheHealth();
}
// ============================================================================
// MANUAL CACHE CLEAR (for debugging)
// ============================================================================
window.clearAppCache = async () => {
try {
// Unregister service workers
const registrations = await navigator.serviceWorker.getRegistrations();
await Promise.all(registrations.map(reg => reg.unregister()));
// Clear all caches
const cacheNames = await caches.keys();
await Promise.all(cacheNames.map(name => caches.delete(name)));
console.log('β
Cache cleared! Reloading...');
setTimeout(() => window.location.reload(true), 500);
} catch (e) {
console.error('Failed to clear cache:', e);
}
};
// Add to global scope for console access
console.log('%cπ‘ Tip: Run clearAppCache() in console to clear all cache', 'color: #00d4ff');
// ============================================================================
// NETWORK STATUS MONITOR
// ============================================================================
const showNetworkStatus = (online) => {
const existing = document.getElementById('network-status-toast');
if (existing) existing.remove();
const toast = document.createElement('div');
toast.id = 'network-status-toast';
toast.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
padding: 12px 20px;
background: ${online ? '#00ff88' : '#ff4444'};
color: #000;
border-radius: 8px;
font-weight: 600;
z-index: 9999;
animation: slideInUp 0.3s ease;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
`;
toast.textContent = online ? 'β
Koneksi kembali' : 'β οΈ Koneksi terputus';
document.body.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'slideOutDown 0.3s ease';
setTimeout(() => toast.remove(), 300);
}, 3000);
};
window.addEventListener('online', () => {
showNetworkStatus(true);
// Force reload to get fresh content
setTimeout(() => window.location.reload(), 3500);
});
window.addEventListener('offline', () => {
showNetworkStatus(false);
});
console.log('β
Service Worker Compatibility Patch Loaded');
})()