Spaces:
Running
Running
Upload 2 files
Browse files- config.js +3 -0
- index.html +21 -6
config.js
CHANGED
|
@@ -28,6 +28,9 @@ window.JM_CONFIG = Object.freeze({
|
|
| 28 |
// Web Push (VAPID) — funguo YA UMMA tu. Private key iwe Supabase secrets pekee.
|
| 29 |
VAPID_PUBLIC_KEY: 'BCgKqA0rqp_xKw90XP0kGwNuTm5nPA1BAOaqiDM3be-lDoeBW7hKRhnEi7sJ8VcCQ5TdJ-6rZ0WVGBGKV7bwfFw',
|
| 30 |
|
|
|
|
|
|
|
|
|
|
| 31 |
// Matangazo (Adsterra). Zima yote kwa kubadilisha kuwa false — hakuna haja ya kugusa index.html.
|
| 32 |
ADS_ENABLED: true,
|
| 33 |
});
|
|
|
|
| 28 |
// Web Push (VAPID) — funguo YA UMMA tu. Private key iwe Supabase secrets pekee.
|
| 29 |
VAPID_PUBLIC_KEY: 'BCgKqA0rqp_xKw90XP0kGwNuTm5nPA1BAOaqiDM3be-lDoeBW7hKRhnEi7sJ8VcCQ5TdJ-6rZ0WVGBGKV7bwfFw',
|
| 30 |
|
| 31 |
+
// Onyesha idadi ya walio online juu ya app (false = ficha). Takwimu zinabaki kwenye admin-online.html
|
| 32 |
+
SHOW_ONLINE: true,
|
| 33 |
+
|
| 34 |
// Matangazo (Adsterra). Zima yote kwa kubadilisha kuwa false — hakuna haja ya kugusa index.html.
|
| 35 |
ADS_ENABLED: true,
|
| 36 |
});
|
index.html
CHANGED
|
@@ -58,6 +58,10 @@
|
|
| 58 |
.brand{font-weight:800; font-size:17px;}
|
| 59 |
.brand span{color:var(--accent);}
|
| 60 |
.top-icons{display:flex; gap:16px; align-items:center;}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
.icon-btn{width:22px;height:22px; display:flex; align-items:center; justify-content:center; cursor:pointer; opacity:0.9;}
|
| 62 |
.search-box{display:none; align-items:center; gap:8px; background:var(--card); border:1px solid var(--border);
|
| 63 |
border-radius:999px; padding:6px 12px; flex:1; margin-right:10px;}
|
|
@@ -1275,6 +1279,7 @@
|
|
| 1275 |
<input id="searchInput" placeholder="Tafuta filamu, series...">
|
| 1276 |
</div>
|
| 1277 |
<div class="top-icons">
|
|
|
|
| 1278 |
<div class="icon-btn" id="dlTopBtn" data-nav="downloads" title="Downloads" data-i18n-title="tip_downloads" style="position:relative"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 3v11"/><path d="M7.5 10.5 12 15l4.5-4.5"/><path d="M3 19h18"/></svg><span class="nav-badge" id="dqNavBadge" style="display:none">0</span></div>
|
| 1279 |
<div class="icon-btn" id="notifBellBtn" title="Notifications" data-i18n-title="tip_notifications" style="position:relative">
|
| 1280 |
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
|
|
@@ -11263,16 +11268,26 @@ Router.sync(); // inafungua tab/ukurasa sahihi kulingana na URL (#/live, #/mat
|
|
| 11263 |
if (!dev) { dev = (crypto.randomUUID && crypto.randomUUID()) || (Date.now() + '-' + Math.random().toString(36).slice(2)); localStorage.setItem('jm_dev', dev); }
|
| 11264 |
} catch (_) { return; }
|
| 11265 |
const platform = ((window.matchMedia && matchMedia('(display-mode: standalone)').matches) || navigator.standalone === true) ? 'pwa' : 'web';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11266 |
const ping = () => {
|
| 11267 |
-
if (document.hidden) return;
|
| 11268 |
-
fetch(C.PROFILE_URL + '/rest/v1/rpc/jm_heartbeat', {
|
| 11269 |
-
method: 'POST', keepalive: true,
|
| 11270 |
-
headers: { apikey: C.PROFILE_KEY, Authorization: 'Bearer ' + C.PROFILE_KEY, 'Content-Type': 'application/json' },
|
| 11271 |
body: JSON.stringify({ p_dev: dev, p_platform: platform })
|
| 11272 |
}).catch(() => {});
|
| 11273 |
};
|
| 11274 |
-
|
| 11275 |
-
|
|
|
|
| 11276 |
} catch (_) {}
|
| 11277 |
})();
|
| 11278 |
</script>
|
|
|
|
| 58 |
.brand{font-weight:800; font-size:17px;}
|
| 59 |
.brand span{color:var(--accent);}
|
| 60 |
.top-icons{display:flex; gap:16px; align-items:center;}
|
| 61 |
+
.online-pill{display:none; align-items:center; gap:5px; font-size:11px; font-weight:700; padding:4px 9px; border-radius:999px; background:rgba(255,255,255,.08); color:var(--text); white-space:nowrap;}
|
| 62 |
+
.online-pill.on{display:inline-flex;}
|
| 63 |
+
.online-pill i{width:7px; height:7px; border-radius:50%; background:#2ee59d; animation:jmOnlinePulse 1.6s infinite;}
|
| 64 |
+
@keyframes jmOnlinePulse{50%{opacity:.3}}
|
| 65 |
.icon-btn{width:22px;height:22px; display:flex; align-items:center; justify-content:center; cursor:pointer; opacity:0.9;}
|
| 66 |
.search-box{display:none; align-items:center; gap:8px; background:var(--card); border:1px solid var(--border);
|
| 67 |
border-radius:999px; padding:6px 12px; flex:1; margin-right:10px;}
|
|
|
|
| 1279 |
<input id="searchInput" placeholder="Tafuta filamu, series...">
|
| 1280 |
</div>
|
| 1281 |
<div class="top-icons">
|
| 1282 |
+
<div class="online-pill" id="onlinePill" title="Online sasa"><i></i><span id="onlineNum">0</span></div>
|
| 1283 |
<div class="icon-btn" id="dlTopBtn" data-nav="downloads" title="Downloads" data-i18n-title="tip_downloads" style="position:relative"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 3v11"/><path d="M7.5 10.5 12 15l4.5-4.5"/><path d="M3 19h18"/></svg><span class="nav-badge" id="dqNavBadge" style="display:none">0</span></div>
|
| 1284 |
<div class="icon-btn" id="notifBellBtn" title="Notifications" data-i18n-title="tip_notifications" style="position:relative">
|
| 1285 |
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
|
|
|
|
| 11268 |
if (!dev) { dev = (crypto.randomUUID && crypto.randomUUID()) || (Date.now() + '-' + Math.random().toString(36).slice(2)); localStorage.setItem('jm_dev', dev); }
|
| 11269 |
} catch (_) { return; }
|
| 11270 |
const platform = ((window.matchMedia && matchMedia('(display-mode: standalone)').matches) || navigator.standalone === true) ? 'pwa' : 'web';
|
| 11271 |
+
const H = { apikey: C.PROFILE_KEY, Authorization: 'Bearer ' + C.PROFILE_KEY, 'Content-Type': 'application/json' };
|
| 11272 |
+
const pill = document.getElementById('onlinePill'), num = document.getElementById('onlineNum');
|
| 11273 |
+
const fmt = n => n >= 1000 ? (n / 1000).toFixed(n >= 10000 ? 0 : 1).replace('.0', '') + 'k' : String(n);
|
| 11274 |
+
const loadOnline = () => {
|
| 11275 |
+
if (C.SHOW_ONLINE === false || !pill || document.hidden) return Promise.resolve();
|
| 11276 |
+
return fetch(C.PROFILE_URL + '/rest/v1/rpc/jm_online_stats', { method: 'POST', headers: H, body: '{}' })
|
| 11277 |
+
.then(r => r.ok ? r.json() : null)
|
| 11278 |
+
.then(d => { if (d && typeof d.online_now === 'number' && d.online_now > 0) { num.textContent = fmt(d.online_now); pill.classList.add('on'); } })
|
| 11279 |
+
.catch(() => {});
|
| 11280 |
+
};
|
| 11281 |
const ping = () => {
|
| 11282 |
+
if (document.hidden) return Promise.resolve();
|
| 11283 |
+
return fetch(C.PROFILE_URL + '/rest/v1/rpc/jm_heartbeat', {
|
| 11284 |
+
method: 'POST', keepalive: true, headers: H,
|
|
|
|
| 11285 |
body: JSON.stringify({ p_dev: dev, p_platform: platform })
|
| 11286 |
}).catch(() => {});
|
| 11287 |
};
|
| 11288 |
+
const tick = () => ping().then(loadOnline);
|
| 11289 |
+
tick(); setInterval(tick, 60000);
|
| 11290 |
+
document.addEventListener('visibilitychange', () => { if (!document.hidden) tick(); });
|
| 11291 |
} catch (_) {}
|
| 11292 |
})();
|
| 11293 |
</script>
|