Files
Varaverk/Plugin/unraid/js/varaverk.js
T
Gmer4Lfe d1deac1bbb Scroll the tab bar instead of the whole page
Reaching the last tab on a phone meant dragging the entire layout sideways,
every card with it.
2026-08-12 20:11:42 -04:00

90 lines
3.7 KiB
JavaScript

// Varaverk — shared JS utilities
// Page-specific JS lives inline in each page partial.
// ── Shared formatters ────────────────────────────────────────────────────────
const _GB = 1073741824, _MB = 1048576, _TB = 1099511627776;
// Relative timestamp → "just now" / "5m ago" / "yesterday" / "3d ago"
function _relTime(ts) {
if (!ts) return '—';
const d = Math.floor(Date.now() / 1000) - ts;
if (d < 60) return 'just now';
if (d < 3600) return Math.floor(d / 60) + 'm ago';
if (d < 86400) return Math.floor(d / 3600) + 'h ago';
if (d < 172800) return 'yesterday';
return Math.floor(d / 86400) + 'd ago';
}
// Bytes → human-readable size (GB / MB / KB)
function _fmtBytes(b) {
if (!b) return '—';
if (b >= _GB) return (b / _GB).toFixed(1) + ' GB';
if (b >= _MB) return (b / _MB).toFixed(0) + ' MB';
return (b / 1024).toFixed(0) + ' KB';
}
// Bytes → auto-scale TB / GB / MB
function _sz(b) {
if (!b) return '—';
if (b >= _TB) return (b / _TB).toFixed(1) + ' TB';
if (b >= _GB) return (b / _GB).toFixed(1) + ' GB';
return (b / _MB).toFixed(0) + ' MB';
}
function _gb(b) { return !b ? '—' : (b / _GB).toFixed(1) + ' GB'; }
function _tb(b) { return !b ? '—' : (b / _TB).toFixed(2) + ' TB'; }
function _n(v) { return v == null ? '—' : Number(v).toLocaleString(); }
// Seconds → uptime string: "2d 3h 5m" / "3h 5m" / "5m"
function _uptime(sec) {
if (!sec) return '—';
const d = Math.floor(sec / 86400), h = Math.floor((sec % 86400) / 3600), m = Math.floor((sec % 3600) / 60);
return d > 0 ? `${d}d ${h}h ${m}m` : h > 0 ? `${h}h ${m}m` : `${m}m`;
}
// Flash a status element briefly then fade
function vvFlashStatus(el, msg, ok) {
el.textContent = msg;
el.style.color = ok ? '#4caf50' : '#f44336';
setTimeout(() => { el.textContent = ''; }, 3000);
}
// ── Fullscreen toggle — hides Unraid header + menu ────────────────────────────
function vvToggleExpand() {
const on = document.body.classList.toggle('vv-fullscreen');
const btn = document.getElementById('vv-expand-btn');
if (btn) { btn.classList.toggle('active', on); btn.title = on ? 'Collapse' : 'Expand'; }
localStorage.setItem('vv-fullscreen', on ? '1' : '');
}
// Restore state on every page load
(function() {
if (localStorage.getItem('vv-fullscreen') !== '1') return;
document.body.classList.add('vv-fullscreen');
// Button may not exist yet if script runs before DOM — wait for it
const apply = () => {
const btn = document.getElementById('vv-expand-btn');
if (btn) { btn.classList.add('active'); btn.title = 'Collapse'; }
};
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', apply);
else apply();
})();
// Bring the current tab into view when the bar is too narrow to show them all. The bar scrolls
// itself now rather than dragging the page sideways, which means the active tab can start off
// screen — and a tab bar whose selected tab is invisible reads as no tab being selected.
//
// inline:'nearest' so a tab already visible is left exactly where it is; only an off-screen one
// moves, and only far enough. Guarded because Unraid swaps tab content by AJAX and this file is
// shared by every page.
(function () {
const show = () => {
const bar = document.getElementById('vv-tabs');
const cur = bar && bar.querySelector('.vv-tab.active');
if (!cur || bar.scrollWidth <= bar.clientWidth) return;
if (cur.scrollIntoView) cur.scrollIntoView({ block: 'nearest', inline: 'nearest' });
};
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', show);
else show();
})();