esp32의 wifi 강도 유지, 복수선택
This commit is contained in:
101
index.h
101
index.h
@@ -377,6 +377,7 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||
}
|
||||
.file-item {
|
||||
background: white;
|
||||
border: 1px solid #e0e0e0;
|
||||
padding: 12px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 8px;
|
||||
@@ -399,6 +400,15 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||
border: 2px solid #11998e;
|
||||
background: linear-gradient(135deg, rgba(17, 153, 142, 0.05) 0%, rgba(56, 239, 125, 0.05) 100%);
|
||||
}
|
||||
.file-item.selected {
|
||||
border: 2px solid #667eea;
|
||||
background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
|
||||
}
|
||||
.file-checkbox {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.file-info {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
@@ -724,6 +734,12 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||
</div>
|
||||
|
||||
<h2>Log Files</h2>
|
||||
<div class="control-row" style="margin-bottom: 10px;">
|
||||
<button onclick="selectAllFiles()" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">Select All</button>
|
||||
<button onclick="deselectAllFiles()" style="background: linear-gradient(135deg, #bdc3c7 0%, #95a5a6 100%);">Deselect All</button>
|
||||
<button onclick="downloadSelectedFiles()" style="background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);">Download Selected</button>
|
||||
<button onclick="deleteSelectedFiles()" style="background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%);">Delete Selected</button>
|
||||
</div>
|
||||
<div class="file-list" id="file-list">
|
||||
<p style="text-align: center; color: #666; font-size: 0.9em;">Loading...</p>
|
||||
</div>
|
||||
@@ -1068,6 +1084,9 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||
}
|
||||
|
||||
fileItem.innerHTML =
|
||||
'<input type="checkbox" class="file-checkbox" data-filename="' + file.name + '" ' +
|
||||
'onchange="toggleFileSelection(this)" ' +
|
||||
(isLogging ? 'disabled' : '') + '>' +
|
||||
'<div class="file-info">' +
|
||||
nameHtml +
|
||||
'<div class="file-size">' + formatBytes(file.size) + '</div>' +
|
||||
@@ -1223,6 +1242,88 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||
}
|
||||
}
|
||||
|
||||
// 파일 선택 관리 함수들
|
||||
function toggleFileSelection(checkbox) {
|
||||
const fileItem = checkbox.closest('.file-item');
|
||||
if (checkbox.checked) {
|
||||
fileItem.classList.add('selected');
|
||||
} else {
|
||||
fileItem.classList.remove('selected');
|
||||
}
|
||||
}
|
||||
|
||||
function selectAllFiles() {
|
||||
const checkboxes = document.querySelectorAll('.file-checkbox:not(:disabled)');
|
||||
checkboxes.forEach(cb => {
|
||||
cb.checked = true;
|
||||
cb.closest('.file-item').classList.add('selected');
|
||||
});
|
||||
}
|
||||
|
||||
function deselectAllFiles() {
|
||||
const checkboxes = document.querySelectorAll('.file-checkbox');
|
||||
checkboxes.forEach(cb => {
|
||||
cb.checked = false;
|
||||
cb.closest('.file-item').classList.remove('selected');
|
||||
});
|
||||
}
|
||||
|
||||
function getSelectedFiles() {
|
||||
const selected = [];
|
||||
const checkboxes = document.querySelectorAll('.file-checkbox:checked');
|
||||
checkboxes.forEach(cb => {
|
||||
selected.push(cb.dataset.filename);
|
||||
});
|
||||
return selected;
|
||||
}
|
||||
|
||||
function downloadSelectedFiles() {
|
||||
const selected = getSelectedFiles();
|
||||
if (selected.length === 0) {
|
||||
alert('Please select files to download.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 각 파일을 순차적으로 다운로드
|
||||
selected.forEach((filename, index) => {
|
||||
setTimeout(() => {
|
||||
downloadFile(filename);
|
||||
}, index * 500); // 500ms 간격으로 다운로드
|
||||
});
|
||||
|
||||
console.log('Downloading files:', selected);
|
||||
}
|
||||
|
||||
function deleteSelectedFiles() {
|
||||
const selected = getSelectedFiles();
|
||||
if (selected.length === 0) {
|
||||
alert('Please select files to delete.');
|
||||
return;
|
||||
}
|
||||
|
||||
const message = 'Are you sure you want to delete ' + selected.length + ' file(s)?\n\n' +
|
||||
'Files:\n' + selected.join('\n') + '\n\n' +
|
||||
'This action cannot be undone.';
|
||||
|
||||
if (!confirm(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 각 파일 삭제
|
||||
selected.forEach(filename => {
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
ws.send(JSON.stringify({cmd: 'deleteFile', filename: filename}));
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Deleting files:', selected);
|
||||
|
||||
// 선택 해제
|
||||
setTimeout(() => {
|
||||
deselectAllFiles();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
loadCanSpeed();
|
||||
loadMcpMode();
|
||||
|
||||
Reference in New Issue
Block a user