From de7326375dc1de9be797f29214da68c492e573ef Mon Sep 17 00:00:00 2001 From: Sergey Krashevich Date: Thu, 18 Apr 2024 02:41:46 +0300 Subject: [PATCH] feat(index.html): optimize stream list update and preserve checkbox states --- www/index.html | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/www/index.html b/www/index.html index 610f033a..9af39bdf 100644 --- a/www/index.html +++ b/www/index.html @@ -121,33 +121,51 @@ function reload() { const url = new URL('api/streams', location.href); + const checkboxStates = {}; + tbody.querySelectorAll('input[type="checkbox"][name]').forEach(checkbox => { + checkboxStates[checkbox.name] = checkbox.checked; + }); fetch(url, {cache: 'no-cache'}).then(r => r.json()).then(data => { - tbody.innerHTML = ''; + const existingIds = Array.from(tbody.querySelectorAll('tr')).map(tr => tr.dataset['id']); + const fetchedIds = []; for (const [key, value] of Object.entries(data)) { const name = key.replace(/[<">]/g, ''); // sanitize + fetchedIds.push(name); + + let tr = tbody.querySelector(`tr[data-id="${name}"]`); const online = value && value.consumers ? value.consumers.length : 0; const src = encodeURIComponent(name); - const links = templates.map(link => { - return link.replace('{name}', src); - }).join(' '); + const links = templates.map(link => link.replace('{name}', src)).join(' '); - const tr = document.createElement('tr'); - tr.dataset['id'] = name; + if (!tr) { + tr = document.createElement('tr'); + tr.dataset['id'] = name; + tbody.appendChild(tr); + } + + const isChecked = checkboxStates[name] ? 'checked' : ''; tr.innerHTML = - `` + + `` + `${online} / info` + `${links}`; - tbody.appendChild(tr); } + + // Remove old rows + existingIds.forEach(id => { + if (!fetchedIds.includes(id)) { + const trToRemove = tbody.querySelector(`tr[data-id="${id}"]`); + tbody.removeChild(trToRemove); + } + }); }); } // Auto-reload every 5 seconds setInterval(reload, 5000); - const url = new URL('api', location.href); - fetch(url, {cache: 'no-cache'}).then(r => r.json()).then(data => { + const url2 = new URL('api', location.href); + fetch(url2, {cache: 'no-cache'}).then(r => r.json()).then(data => { const info = document.querySelector('.info'); info.innerText = `Version: ${data.version}, Config: ${data.config_path}`; });