summaryrefslogtreecommitdiff
path: root/web/js/dom.js
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-06 23:59:40 +0300
committerPaul Buetow <paul@buetow.org>2026-05-06 23:59:40 +0300
commit1f162963c0950cdf08858940cf43e21e5741937d (patch)
treece85baec410c10fa8cfcf99e8ea9f3b8a0b4e746 /web/js/dom.js
parent0a5ae3daf7103bb319b7861253c64a4da899b48a (diff)
Split app.js into view modules for task 71
Diffstat (limited to 'web/js/dom.js')
-rw-r--r--web/js/dom.js47
1 files changed, 47 insertions, 0 deletions
diff --git a/web/js/dom.js b/web/js/dom.js
new file mode 100644
index 0000000..3d78bb4
--- /dev/null
+++ b/web/js/dom.js
@@ -0,0 +1,47 @@
+export function fmtDate(d) {
+ if (!d) return '';
+ const dt = typeof d === 'string' ? new Date(d) : d;
+ return dt.toLocaleDateString();
+}
+
+export function fmtDateTime(d) {
+ if (!d) return '';
+ const dt = typeof d === 'string' ? new Date(d) : d;
+ if (Number.isNaN(dt.getTime())) return '';
+ return dt.toLocaleString();
+}
+
+export function fmtDur(s) {
+ if (!s || s < 0) return '0:00';
+ const h = Math.floor(s / 3600);
+ const m = Math.floor((s % 3600) / 60);
+ const sec = Math.floor(s % 60);
+ const mm = String(m).padStart(2, '0');
+ const ss = String(sec).padStart(2, '0');
+ return h > 0 ? `${h}:${mm}:${ss}` : `${mm}:${ss}`;
+}
+
+export function fmtSize(bytes) {
+ if (!bytes || bytes <= 0) return '';
+ const kb = bytes / 1024;
+ if (kb < 1024) return Math.round(kb) + ' KB';
+ const mb = kb / 1024;
+ if (mb < 1024) return Math.round(mb * 10) / 10 + ' MB';
+ return Math.round((mb / 1024) * 10) / 10 + ' GB';
+}
+
+export function escapeHtml(s) {
+ return (s ?? '').replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
+}
+
+export function toast(msg, type = 'info') {
+ const t = document.getElementById('toast');
+ if (!t) return;
+ t.textContent = msg;
+ t.className = 'toast show ' + type;
+ setTimeout(() => t.classList.remove('show'), 2800);
+}
+
+export function closeAllModals() {
+ document.querySelectorAll('.modal-overlay.open').forEach((m) => m.classList.remove('open'));
+}