added data saving feature

This commit is contained in:
Ayzen
2026-06-23 12:19:31 +03:00
parent 716fd0b07a
commit 8db14b9482
20 changed files with 1192 additions and 63 deletions
+48 -2
View File
@@ -22,6 +22,9 @@ const configActiveEl = document.getElementById("config-active");
const savePathInput = document.getElementById("save-path");
const saveNameInput = document.getElementById("save-name");
const btnSaveDataset = document.getElementById("btn-save-dataset");
const recordCountInput = document.getElementById("record-count");
const btnStartRecording = document.getElementById("btn-start-recording");
const recordingStatusEl = document.getElementById("recording-status");
const settingsToggle = document.getElementById("settings-toggle");
const sidePanel = document.querySelector(".side-panel");
@@ -40,6 +43,7 @@ let pendingPng = null; // newest PNG (base64), shown on the next animation
let lastFrameTs = 0; // performance.now() of the last received frame
let pipelineRunning = false; // gates the config loader (loading requires a stopped pipeline)
let saveFieldsPrefilled = false; // seed the save path/name fields once, then leave the operator's edits
let recordCountPrefilled = false; // seed the record-count field once from the desktop default
/* ---- helpers ----------------------------------------------------- */
function toast(message, isError) {
@@ -305,14 +309,44 @@ btnSaveDataset.addEventListener("click", async () => {
path: savePathInput.value.trim(),
name: saveNameInput.value.trim(),
});
toast("Save requested"); // a radar-config prefix is prepended to the name server-side
toast("Dataset saved"); // a radar-config prefix is prepended to the name server-side
} catch (err) {
toast(err.message, true);
toast(err.message, true); // e.g. the destination directory already exists
} finally {
btnSaveDataset.disabled = false;
}
});
// Start (if stopped) and record the next N measurements to disk, then stop writing.
// While a recording is in progress the button stays disabled (driven by status), so a
// second recording can't be armed over the first.
let recordingActive = false;
function updateRecordButtonState() {
btnStartRecording.disabled = recordingActive;
}
btnStartRecording.addEventListener("click", async () => {
const count = parseInt(recordCountInput.value, 10);
if (!Number.isFinite(count) || count < 1) {
toast("Enter how many sweeps to record (>= 1)", true);
return;
}
btnStartRecording.disabled = true; // optimistic; status keeps it disabled while recording
try {
await api("/api/start_recording", {
path: savePathInput.value.trim(),
name: saveNameInput.value.trim(),
count,
});
toast(`Recording armed: next ${count} sweep(s)`);
} catch (err) {
toast(err.message, true); // e.g. the destination directory already exists
} finally {
updateRecordButtonState(); // re-enable only if not actually recording
}
});
/* ---- status ------------------------------------------------------ */
function setStat(el, label, value, cls) {
el.className = "stat" + (cls ? " " + cls : "");
@@ -333,6 +367,18 @@ function applyStatus(s) {
saveNameInput.value = s.save_name || "";
saveFieldsPrefilled = true;
}
if ("record_count" in s && !recordCountPrefilled && document.activeElement !== recordCountInput) {
recordCountInput.value = s.record_count; // seed once; don't clobber later edits
recordCountPrefilled = true;
}
if (s.recording) {
const r = s.recording;
recordingActive = !!r.active;
updateRecordButtonState();
recordingStatusEl.textContent = r.active
? `recording ${r.collected} / ${r.target} sweep(s)…`
: "";
}
if ("processor_running" in s)
setStat(processorEl, "processor", s.processor_running ? "yes" : "no",
s.processor_running ? "ok" : "off");
+7 -1
View File
@@ -39,7 +39,7 @@
</div>
<div class="config-section">
<div class="config-title">Save dataset</div>
<div class="config-title">Save / record dataset</div>
<div class="config-row">
<input id="save-path" class="config-control" type="text" placeholder="Save path" aria-label="Save path" />
</div>
@@ -47,6 +47,12 @@
<input id="save-name" class="config-control" type="text" placeholder="Name (optional)" aria-label="Save name" />
<button id="btn-save-dataset" class="btn">Save</button>
</div>
<div class="config-row">
<input id="record-count" class="config-control" type="number" min="1" step="1"
placeholder="Sweeps to record" aria-label="Number of sweeps to record" />
<button id="btn-start-recording" class="btn">Start + Record</button>
</div>
<div class="config-active" id="recording-status"></div>
</div>
<div class="panel-head" id="settings-toggle">