feat: enhance download functionality with selectable log types and command history management

This commit is contained in:
roy01
2026-06-04 15:53:42 +08:00
parent 7991f1fcba
commit 750bea70ec
3 changed files with 174 additions and 26 deletions
+81 -7
View File
@@ -24,6 +24,7 @@ const sendBtn = document.getElementById('send-btn');
const clearBtn = document.getElementById('clear-btn');
const addSessionBtn = document.getElementById('add-session-btn');
const sessionListContainer = document.getElementById('session-list');
const downloadTypeSelect = document.getElementById('download-type');
// PortSession Class definition
class PortSession {
@@ -36,7 +37,12 @@ class PortSession {
this.reader = null;
this.writer = null;
this.keepReading = false;
this.receivedLogBuffer = [];
this.rxLogBuffer = [];
this.txLogBuffer = [];
this.combinedLogBuffer = [];
this.downloadType = 'rx_tx';
this.commandHistory = [];
this.historyIndex = -1;
this.isTerminalEmpty = true;
this.deviceInfo = '';
@@ -113,6 +119,10 @@ document.addEventListener('DOMContentLoaded', () => {
if (activeSession) activeSession.sendText = sendInput.value;
});
downloadTypeSelect.addEventListener('change', () => {
if (activeSession) activeSession.downloadType = downloadTypeSelect.value;
});
// Initialize with a default session
addSession();
});
@@ -237,8 +247,9 @@ function selectSession(session) {
sendFormatSelect.value = activeSession.sendFormat;
sendEolSelect.value = activeSession.sendEol;
sendInput.value = activeSession.sendText;
downloadTypeSelect.value = activeSession.downloadType;
downloadBtn.disabled = activeSession.isTerminalEmpty;
downloadBtn.disabled = (activeSession.rxLogBuffer.length === 0 && activeSession.txLogBuffer.length === 0);
// Sync status banner and buttons
const isConnected = activeSession.port !== null && activeSession.port.readable;
@@ -485,7 +496,8 @@ function handleIncomingSessionData(session, uint8Array, decoder) {
formattedText = decoder.decode(uint8Array);
}
session.receivedLogBuffer.push(formattedText);
session.rxLogBuffer.push(formattedText);
session.combinedLogBuffer.push(formattedText);
appendSessionTerminalText(session, formattedText, 'received');
}
@@ -504,6 +516,19 @@ async function sendSessionData() {
const rawInput = sendInput.value;
if (!rawInput) return;
// Add command to history (maximum 10 items)
const trimmed = rawInput.trim();
if (trimmed) {
const history = session.commandHistory;
if (history.length === 0 || history[history.length - 1] !== trimmed) {
history.push(trimmed);
if (history.length > 10) {
history.shift();
}
}
session.historyIndex = history.length;
}
const format = session.sendFormat;
const eol = session.sendEol;
let bytesToSend;
@@ -552,6 +577,11 @@ async function sendSessionData() {
}
appendSessionTerminalText(session, `\n[Sent] ${displaySent}\n`, 'sent');
// Save sent log
session.txLogBuffer.push(`[Sent] ${displaySent}\n`);
session.combinedLogBuffer.push(`\n[Sent] ${displaySent}\n`);
sendInput.value = '';
session.sendText = '';
@@ -614,15 +644,35 @@ function clearTerminal() {
activeSession.terminalOutputElement.innerHTML = 'No data received yet...';
activeSession.terminalOutputElement.classList.add('empty');
activeSession.isTerminalEmpty = true;
activeSession.receivedLogBuffer = [];
activeSession.rxLogBuffer = [];
activeSession.txLogBuffer = [];
activeSession.combinedLogBuffer = [];
downloadBtn.disabled = true;
showToast('Terminal cleared.', 'success');
}
function downloadLog() {
if (!activeSession || activeSession.receivedLogBuffer.length === 0) return;
if (!activeSession) return;
let content = '';
let filenameSuffix = '';
if (activeSession.downloadType === 'rx') {
content = activeSession.rxLogBuffer.join('');
filenameSuffix = 'rx';
} else if (activeSession.downloadType === 'tx') {
content = activeSession.txLogBuffer.join('');
filenameSuffix = 'tx';
} else {
content = activeSession.combinedLogBuffer.join('');
filenameSuffix = 'combined';
}
if (!content) {
showToast('No logs to download for the selected type.', 'error');
return;
}
const content = activeSession.receivedLogBuffer.join('');
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
@@ -630,7 +680,7 @@ function downloadLog() {
const a = document.createElement('a');
a.href = url;
a.download = `uart_log_${activeSession.name.replace(/\s+/g, '_')}_${dateStr}.txt`;
a.download = `uart_log_${activeSession.name.replace(/\s+/g, '_')}_${filenameSuffix}_${dateStr}.txt`;
document.body.appendChild(a);
a.click();
@@ -664,6 +714,30 @@ sendInput.addEventListener('keydown', (e) => {
e.preventDefault();
sendSessionData();
}
if (e.key === 'ArrowUp') {
e.preventDefault();
if (activeSession && activeSession.commandHistory.length > 0) {
if (activeSession.historyIndex > 0) {
activeSession.historyIndex--;
sendInput.value = activeSession.commandHistory[activeSession.historyIndex];
activeSession.sendText = sendInput.value;
}
}
}
if (e.key === 'ArrowDown') {
e.preventDefault();
if (activeSession && activeSession.commandHistory.length > 0) {
if (activeSession.historyIndex < activeSession.commandHistory.length - 1) {
activeSession.historyIndex++;
sendInput.value = activeSession.commandHistory[activeSession.historyIndex];
activeSession.sendText = sendInput.value;
} else {
activeSession.historyIndex = activeSession.commandHistory.length;
sendInput.value = '';
activeSession.sendText = '';
}
}
}
if (e.key === 'Tab' && e.ctrlKey) {
e.preventDefault();
const start = sendInput.selectionStart;