First commit
This commit is contained in:
66
services/aprelay.js
Normal file
66
services/aprelay.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/* @licstart Copyleft (🄯) 2025 James Osborne — AGPLv3+ @licend */
|
||||
'use strict';
|
||||
|
||||
/* ===== Copy-to-clipboard handler ===== */
|
||||
document.addEventListener('click', (e) => {
|
||||
const el = e.target.closest('.copyable');
|
||||
if (!el) return;
|
||||
|
||||
const text = el.dataset.copy ?? '';
|
||||
const copyPromise =
|
||||
(navigator.clipboard && window.isSecureContext)
|
||||
? navigator.clipboard.writeText(text)
|
||||
: (async () => {
|
||||
const ta = document.createElement('textarea');
|
||||
ta.value = text;
|
||||
ta.style.position = 'fixed';
|
||||
ta.style.opacity = '0';
|
||||
ta.style.left = '-9999px';
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
try { document.execCommand('copy'); } catch {}
|
||||
ta.remove();
|
||||
})();
|
||||
|
||||
Promise.resolve(copyPromise).then(() => {
|
||||
el.dataset._orig ??= el.textContent || '';
|
||||
el.textContent = `${el.dataset._orig} (copied!)`;
|
||||
setTimeout(() => { el.textContent = el.dataset._orig; }, 1500);
|
||||
});
|
||||
});
|
||||
|
||||
/* ===== Stats loader ===== */
|
||||
async function loadStats() {
|
||||
const endpoints = [
|
||||
'/relay-stats.json', // same-origin first (no CORS)
|
||||
'https://relay-us-east.circlewithadot.net/relay-stats.json',
|
||||
];
|
||||
|
||||
for (const url of endpoints) {
|
||||
try {
|
||||
const r = await fetch(url, { cache: 'no-store' });
|
||||
if (!r.ok) continue;
|
||||
|
||||
const d = await r.json();
|
||||
const set = (id, val) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = val;
|
||||
};
|
||||
|
||||
set('instances', d.instances ?? '–');
|
||||
// accept either jobs_5min (new) or jobs_per_min (old)
|
||||
set('jobs', (d.jobs_5min ?? d.jobs_per_min ?? '–'));
|
||||
set('updated', d.updated ? new Date(d.updated).toLocaleString() : '–');
|
||||
return;
|
||||
} catch (e) {
|
||||
console.warn('[relay stats] fetch failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
const box = document.getElementById('relay-stats');
|
||||
if (box) box.textContent = 'Stats unavailable';
|
||||
}
|
||||
|
||||
loadStats();
|
||||
setInterval(loadStats, 300000);
|
||||
|
||||
Reference in New Issue
Block a user