From 4bb6bbf0096db92df3263a25c36f1f8893900c80 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Sat, 6 Jun 2026 15:48:55 -0400 Subject: [PATCH] Rsync page: add live sync activity log card left of settings --- Plugin/unraid/pages/rsync.php | 73 +++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/Plugin/unraid/pages/rsync.php b/Plugin/unraid/pages/rsync.php index 33cf893..ab0a7e0 100644 --- a/Plugin/unraid/pages/rsync.php +++ b/Plugin/unraid/pages/rsync.php @@ -43,6 +43,16 @@ .vv-ry-run-dur { font-size:10px;color:#555;text-align:right; } .vv-ry-run-st { text-align:right; } +/* Sync log card */ +.vv-ry-slog-row { display:grid;grid-template-columns:38px 1fr 70px 50px 46px;gap:6px;align-items:center; + padding:3px 0;border-bottom:1px solid #111; } +.vv-ry-slog-row:last-child { border-bottom:none; } +.vv-ry-slog-name { font-size:11px;color:#888;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; } +.vv-ry-slog-dt { font-size:10px;color:#3a3a3a; } +.vv-ry-slog-dur { font-size:10px;color:#555;text-align:right; } +.vv-ry-slog-byt { font-size:10px;color:#555;text-align:right; } +.vv-ry-slog-scrl { overflow-y:auto;max-height:200px; } + /* Settings */ .vv-ry-set-grid { display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-top:6px; } .vv-ry-toggle { display:inline-flex;align-items:center;gap:8px;cursor:pointer;user-select:none; } @@ -720,6 +730,48 @@ function _bwSection(data) { `; } +// ── Sync log card ───────────────────────────────────────────────────────────── +let _liveTicker = null; +let _fastPollTimer = null; + +function _syncLogCard(data) { + const active = data.active || []; + const history = data.bw_history || []; + const recent = [...history].reverse().slice(0, 14); + const now = Math.floor(Date.now() / 1000); + + const activeRows = active.map(a => { + const startedTs = now - (a.elapsed || 0); + return `
+ LIVE + ${_esc(a.profile)} + ${_dur(a.elapsed || 0)} +
`; + }).join(''); + + const histRows = recent.map(r => { + const cls = r.status === 'success' ? 'on' : 'err'; + const bytes = r.bytes > 0 ? _fmtBytes(r.bytes) : ''; + return `
+ ${r.status === 'success' ? 'ok' : 'fail'} + ${_esc(r.profile)} + ${r.date} ${r.time.slice(0,5)} + ${_dur(r.duration)} + ${bytes} +
`; + }).join(''); + + return `
+
Sync Activity
+ ${activeRows} + ${activeRows && histRows ? '
' : ''} +
+ ${histRows || '
No sync history
'} +
+
`; +} + // ── Settings section ────────────────────────────────────────────────────────── function _toggle(name, currentVal, label) { const id = 'vv-ry-tog-' + name; @@ -800,9 +852,30 @@ function _render(data) { html += _lastSyncCard(data); html += _windowsRow(data); html += _bwSection(data); + html += _syncLogCard(data); html += _settingsSection(data); document.getElementById('vv-ry-grid').innerHTML = html; + // Live elapsed ticker — updates every second without re-fetching + if (_liveTicker) { clearInterval(_liveTicker); _liveTicker = null; } + if ((data.active || []).length) { + _liveTicker = setInterval(() => { + document.querySelectorAll('.vv-ry-elapsed').forEach(el => { + const s = parseInt(el.dataset.started, 10); + if (s) el.textContent = _dur(Math.floor(Date.now() / 1000) - s); + }); + }, 1000); + } + + // Fast-poll (5s) while syncs are active; return to 30s when idle + const hasActive = (data.active || []).length > 0; + if (hasActive && !_fastPollTimer) { + _fastPollTimer = setInterval(vvRyLoad, 5000); + } else if (!hasActive && _fastPollTimer) { + clearInterval(_fastPollTimer); + _fastPollTimer = null; + } + // Restore any window panels that were open before the re-render _vvRyWinOpen.forEach(key => { const card = document.querySelector(`.vv-ry-win[data-win-key="${key}"]`);