OPEN-ISP v0.5 (pickle-lime) — rilis open-source perdana
Aplikasi billing & manajemen ISP (fiber optic) — PWA pelanggan, portal teknisi & kolektor, admin panel lengkap, multi-vendor OLT, RADIUS, WhatsApp/Telegram, pembayaran QRIS. Kredit & lisensi (ISC): - Base kode & repo: alijayanet/billing-rtrw oleh Alijaya Net — terima kasih banyak atas base kode dan repo yang bermanfaat. - Add-on: GoWA, LibreSpeed/OpenSpeedTest, Uptime Kuma, notification-forwarder. - Dikembangkan menjadi OPEN-ISP oleh oxpoe — https://github.com/oxpoe/open-isp
This commit is contained in:
commit
eaf05f2811
280 files changed
+123975
No files matched your search
+123
@@ -0,0 +1,123 @@
|
||||
/* Service Worker — Portal Pelanggan OPEN-ISP
|
||||
Strategi: HTML & CSS/JS = network-first (selalu ambil terbaru saat online),
|
||||
gambar & manifest & font = cache-first (jarang berubah).
|
||||
Naikkan CACHE_NAME bila perlu purge (v4 → v5 → ...). */
|
||||
const CACHE_NAME = 'customer-pwa-v7';
|
||||
const PRECACHE_URLS = [
|
||||
// Aset inti (network-first tapi disimpan untuk offline)
|
||||
'/css/auth.css',
|
||||
'/css/landing.css',
|
||||
'/css/dashboard.css',
|
||||
'/css/pages.css',
|
||||
'/css/theme-toggle.css',
|
||||
'/js/theme-toggle.js',
|
||||
// Ikon & manifest PWA
|
||||
'/img/icons/icon-192.png',
|
||||
'/img/icons/icon-512.png',
|
||||
'/img/icons/icon-maskable-192.png',
|
||||
'/img/icons/icon-maskable-512.png',
|
||||
'/img/icons/apple-touch-icon.png',
|
||||
'/manifest.webmanifest',
|
||||
'/manifest-landing.webmanifest',
|
||||
// Halaman shell untuk fallback offline
|
||||
'/offline.html',
|
||||
'/customer/login',
|
||||
'/customer/register'
|
||||
];
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
self.skipWaiting();
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME).then((cache) =>
|
||||
// Tambah satu-per-satu agar satu URL gagal tidak membatalkan semuanya
|
||||
Promise.all(
|
||||
PRECACHE_URLS.map((url) =>
|
||||
cache.add(url).catch(() => null)
|
||||
)
|
||||
)
|
||||
).catch(() => {})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(
|
||||
Promise.all([
|
||||
caches.keys().then((keys) =>
|
||||
Promise.all(keys.map((k) => (k === CACHE_NAME ? null : caches.delete(k))))
|
||||
),
|
||||
self.clients.claim()
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
async function cacheFirst(request) {
|
||||
const cached = await caches.match(request);
|
||||
if (cached) return cached;
|
||||
const res = await fetch(request);
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
if (res && res.ok) cache.put(request, res.clone()).catch(() => {});
|
||||
return res;
|
||||
}
|
||||
|
||||
async function networkFirst(request, fallbackUrl) {
|
||||
try {
|
||||
const res = await fetch(request, { cache: 'no-cache' });
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
if (res && res.ok) cache.put(request, res.clone()).catch(() => {});
|
||||
return res;
|
||||
} catch (e) {
|
||||
const cached = await caches.match(request);
|
||||
if (cached) return cached;
|
||||
if (fallbackUrl) {
|
||||
const fallback = await caches.match(fallbackUrl);
|
||||
if (fallback) return fallback;
|
||||
}
|
||||
return new Response('Offline', {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'text/plain; charset=utf-8' }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const req = event.request;
|
||||
if (req.method !== 'GET') return;
|
||||
|
||||
const url = new URL(req.url);
|
||||
if (url.origin !== self.location.origin) return;
|
||||
|
||||
const path = url.pathname;
|
||||
|
||||
// version.txt → selalu network (mekanisme deteksi update)
|
||||
if (path === '/version.txt') return;
|
||||
|
||||
// Navigasi halaman pelanggan → network-first
|
||||
if (req.mode === 'navigate') {
|
||||
if (path.startsWith('/customer/')) event.respondWith(networkFirst(req, '/customer/login'));
|
||||
else event.respondWith(networkFirst(req));
|
||||
return;
|
||||
}
|
||||
|
||||
// CSS & JS → network-first agar perubahan desain langsung terlihat
|
||||
if (path.startsWith('/css/') || path.startsWith('/js/')) {
|
||||
event.respondWith(networkFirst(req));
|
||||
return;
|
||||
}
|
||||
|
||||
// Gambar, ikon, manifest, font → cache-first
|
||||
if (
|
||||
path.startsWith('/img/') ||
|
||||
path.startsWith('/fonts/') ||
|
||||
path === '/manifest.webmanifest' ||
|
||||
path === '/manifest-landing.webmanifest'
|
||||
) {
|
||||
event.respondWith(cacheFirst(req));
|
||||
return;
|
||||
}
|
||||
|
||||
event.respondWith(networkFirst(req));
|
||||
});
|
||||
|
||||
self.addEventListener('message', (event) => {
|
||||
if (event.data === 'SKIP_WAITING') self.skipWaiting();
|
||||
});
|
||||
Reference in new issue
Block a user