This commit is contained in:
John Varghese
2025-06-03 21:33:52 +05:30
committed by GitHub
parent 741ab31d0a
commit 0070b1f4c7

112
ESP32CAM-ONVIF/data/app.js Normal file
View File

@@ -0,0 +1,112 @@
// --- Login Overlay Logic ---
let authHeader = "";
document.addEventListener("DOMContentLoaded", function() {
if (localStorage.getItem("auth")) {
authHeader = localStorage.getItem("auth");
document.getElementById("login-overlay").style.display = "none";
updateStatus();
}
});
function login(e) {
e.preventDefault();
const user = document.getElementById("username").value;
const pass = document.getElementById("password").value;
authHeader = "Basic " + btoa(user + ":" + pass);
fetch("/api/status", {headers: {"Authorization": authHeader}})
.then(r => {
if (r.status === 401) throw new Error("Unauthorized");
return r.json();
})
.then(() => {
document.getElementById("login-overlay").style.display = "none";
localStorage.setItem("auth", authHeader);
updateStatus();
})
.catch(() => {
document.getElementById("login-error").textContent = "Invalid credentials!";
authHeader = "";
localStorage.removeItem("auth");
});
return false;
}
// --- API Helpers ---
function api(url, opts={}) {
opts.headers = opts.headers || {};
opts.headers["Authorization"] = authHeader;
return fetch(url, opts);
}
// --- Tab Navigation ---
function showPanel(panel) {
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
document.querySelectorAll('.panel').forEach(sec => sec.style.display = 'none');
document.querySelector('.tab-btn[onclick="showPanel(\''+panel+'\')"]').classList.add('active');
document.getElementById('panel-' + panel).style.display = '';
if (panel === 'sd') refreshSD();
}
// --- SD Card Management ---
function refreshSD() {
api('/api/sd/list').then(r => r.json()).then(files => {
const tbody = document.querySelector('#sd-table tbody');
tbody.innerHTML = '';
files.forEach(file => {
const tr = document.createElement('tr');
tr.innerHTML = `<td>${file.name}</td>
<td>${(file.size/1024).toFixed(1)} KB</td>
<td>
<a href="/api/sd/download?file=${encodeURIComponent(file.name)}" class="btn" target="_blank">Download</a>
<button class="btn" onclick="deleteSD('${file.name}')">Delete</button>
</td>`;
tbody.appendChild(tr);
});
});
}
function deleteSD(filename) {
if (!confirm('Delete ' + filename + '?')) return;
api('/api/sd/delete', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({file: filename})
}).then(refreshSD);
}
// --- UI Logic ---
function updateStatus() {
api('/api/status').then(r => r.json()).then(data => {
document.getElementById('status').textContent = data.status || 'Online';
document.getElementById('rtspUrl').textContent = data.rtsp || '';
document.getElementById('onvifUrl').textContent = data.onvif || '';
document.getElementById('motionStatus').textContent = "Motion: " + (data.motion ? "Detected" : "None");
}).catch(() => {
document.getElementById('status').textContent = 'Offline';
if (!document.getElementById("login-overlay").style.display || document.getElementById("login-overlay").style.display === "none") {
document.getElementById("login-overlay").style.display = "flex";
}
localStorage.removeItem("auth");
});
}
function setConfig(key, value) {
api('/api/config', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({[key]: value})
}).then(updateStatus);
}
function snapshot() {
window.open('/snapshot', '_blank');
}
function toggleRecording() {
api('/api/record', {method: 'POST'}).then(updateStatus);
}
function reboot() {
api('/api/reboot', {method: 'POST'});
alert("Rebooting...");
}
function factoryReset() {
api('/api/factory_reset', {method: 'POST'});
alert("Factory reset initiated.");
}
setInterval(updateStatus, 2000);
updateStatus();