31398a7e6b
Implemented a dark mode feature for the website, including a toggle button in the navigation bar that allows users to switch between light and dark themes. To support this feature, centralized common CSS styles (such as body, table, and button stylings) into main.js to ensure consistent application across all HTML pages. This change improves user experience by providing a visually comfortable alternative for low-light environments and centralizes styling rules for easier maintenance. - Added dark mode styles for body, table, buttons, and navigation elements in main.js. - Introduced a toggle mechanism in the navigation bar to switch between light and dark modes. - Utilized JavaScript to detect system theme preference (`prefers-color-scheme`) and persist user's theme choice using localStorage. - Removed duplicate and scattered CSS rules from individual HTML files (add.html, index.html, links.html, log.html) and centralized them in main.js to reduce redundancy and facilitate easier updates in the future. This update enhances accessibility and user preference compliance by allowing users to select their desired theme while simplifying CSS management across the website.
128 lines
3.9 KiB
HTML
128 lines
3.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1">
|
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
|
|
<title>go2rtc</title>
|
|
|
|
<style>
|
|
|
|
table tbody td {
|
|
font-size: 13px;
|
|
}
|
|
|
|
label {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.controls {
|
|
display: flex;
|
|
padding: 5px;
|
|
}
|
|
|
|
.controls > label {
|
|
margin-left: 10px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<script src="main.js"></script>
|
|
<div class="info"></div>
|
|
<div class="controls">
|
|
<button>stream</button>
|
|
<label><input type="checkbox" name="webrtc" checked>webrtc</label>
|
|
<label><input type="checkbox" name="mse" checked>mse</label>
|
|
<label><input type="checkbox" name="hls" checked>hls</label>
|
|
<label><input type="checkbox" name="mjpeg" checked>mjpeg</label>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th><label><input id="selectall" type="checkbox">Name</label></th>
|
|
<th>Online</th>
|
|
<th>Commands</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="streams">
|
|
</tbody>
|
|
</table>
|
|
<script>
|
|
const templates = [
|
|
'<a href="stream.html?src={name}">stream</a>',
|
|
'<a href="links.html?src={name}">links</a>',
|
|
'<a href="#" data-name="{name}">delete</a>',
|
|
];
|
|
|
|
document.querySelector('.controls > button')
|
|
.addEventListener('click', () => {
|
|
const url = new URL('stream.html', location.href);
|
|
|
|
const streams = document.querySelectorAll('#streams input');
|
|
streams.forEach(i => {
|
|
if (i.checked) url.searchParams.append('src', i.name);
|
|
});
|
|
|
|
if (!url.searchParams.has('src')) return;
|
|
|
|
let mode = document.querySelectorAll('.controls input');
|
|
mode = Array.from(mode).filter(i => i.checked).map(i => i.name).join(',');
|
|
|
|
window.location.href = `${url}&mode=${mode}`;
|
|
});
|
|
|
|
const tbody = document.getElementById('streams');
|
|
tbody.addEventListener('click', ev => {
|
|
if (ev.target.innerText !== 'delete') return;
|
|
|
|
ev.preventDefault();
|
|
|
|
const url = new URL('api/streams', location.href);
|
|
const src = decodeURIComponent(ev.target.dataset.name);
|
|
url.searchParams.set('src', src);
|
|
fetch(url, {method: 'DELETE'}).then(reload);
|
|
});
|
|
|
|
document.getElementById('selectall').addEventListener('change', ev => {
|
|
document.querySelectorAll('#streams input').forEach(el => {
|
|
el.checked = ev.target.checked;
|
|
});
|
|
});
|
|
|
|
function reload() {
|
|
const url = new URL('api/streams', location.href);
|
|
fetch(url, {cache: 'no-cache'}).then(r => r.json()).then(data => {
|
|
tbody.innerHTML = '';
|
|
|
|
for (const [key, value] of Object.entries(data)) {
|
|
const name = key.replace(/[<">]/g, ''); // sanitize
|
|
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 tr = document.createElement('tr');
|
|
tr.dataset['id'] = name;
|
|
tr.innerHTML =
|
|
`<td><label><input type="checkbox" name="${name}">${name}</label></td>` +
|
|
`<td><a href="api/streams?src=${src}">${online} / info</a></td>` +
|
|
`<td>${links}</td>`;
|
|
tbody.appendChild(tr);
|
|
}
|
|
});
|
|
}
|
|
|
|
const url = new URL('api', location.href);
|
|
fetch(url, {cache: 'no-cache'}).then(r => r.json()).then(data => {
|
|
const info = document.querySelector('.info');
|
|
info.innerText = `Version: ${data.version}, Config: ${data.config_path}`;
|
|
});
|
|
|
|
reload();
|
|
</script>
|
|
</body>
|
|
</html>
|