fix javascript issued

This commit is contained in:
Brendan O'Leary 2025-12-17 20:03:20 -05:00
parent ba96a26b71
commit f3810f3c69
5 changed files with 50 additions and 94 deletions

View File

@ -5,7 +5,7 @@ SRC_DIR = "src"
def minify_html(html: str) -> str: def minify_html(html: str) -> str:
# Tags where whitespace should be preserved # Tags where whitespace should be preserved
preserve_tags = ['pre', 'code', 'textarea'] preserve_tags = ['pre', 'code', 'textarea', 'script', 'style']
preserve_regex = '|'.join(preserve_tags) preserve_regex = '|'.join(preserve_tags)
# Protect preserve blocks with placeholders # Protect preserve blocks with placeholders

View File

@ -273,7 +273,7 @@ void CrossPointWebServer::handleFileList() {
} }
} }
// Page header with inline breadcrumb and +Add dropdown // Page header with inline breadcrumb and action buttons
html += "<div class=\"page-header\">"; html += "<div class=\"page-header\">";
html += "<div class=\"page-header-left\">"; html += "<div class=\"page-header-left\">";
html += "<h1>📁 File Manager</h1>"; html += "<h1>📁 File Manager</h1>";
@ -310,20 +310,14 @@ void CrossPointWebServer::handleFileList() {
html += "</div>"; html += "</div>";
html += "</div>"; html += "</div>";
// +Add dropdown button // Action buttons
html += "<div class=\"add-dropdown\" id=\"addDropdown\">"; html += "<div class=\"action-buttons\">";
html += "<button class=\"add-btn\" onclick=\"toggleDropdown()\">"; html += "<button class=\"action-btn upload-action-btn\" onclick=\"openUploadModal()\">";
html += "+ Add <span class=\"arrow\">▼</span>"; html += "📤 Upload";
html += "</button>"; html += "</button>";
html += "<div class=\"dropdown-menu\">"; html += "<button class=\"action-btn folder-action-btn\" onclick=\"openFolderModal()\">";
html += "<button class=\"dropdown-item\" onclick=\"openUploadModal()\">"; html += "📁 New Folder";
html += "<span class=\"icon\">📤</span> Upload eBook";
html += "</button>"; html += "</button>";
html += "<div class=\"dropdown-divider\"></div>";
html += "<button class=\"dropdown-item\" onclick=\"openFolderModal()\">";
html += "<span class=\"icon\">📁</span> New Folder";
html += "</button>";
html += "</div>";
html += "</div>"; html += "</div>";
html += "</div>"; // end page-header html += "</div>"; // end page-header

View File

@ -2,6 +2,7 @@
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <WiFi.h> #include <WiFi.h>
#include <map>
#include "CrossPointWebServer.h" #include "CrossPointWebServer.h"
#include "WifiCredentialStore.h" #include "WifiCredentialStore.h"
@ -95,18 +96,35 @@ void WifiScreen::processWifiScanResults() {
} }
// Scan complete, process results // Scan complete, process results
networks.clear(); // Use a map to deduplicate networks by SSID, keeping the strongest signal
std::map<std::string, WifiNetworkInfo> uniqueNetworks;
for (int i = 0; i < scanResult; i++) { for (int i = 0; i < scanResult; i++) {
WifiNetworkInfo network; std::string ssid = WiFi.SSID(i).c_str();
network.ssid = WiFi.SSID(i).c_str(); int32_t rssi = WiFi.RSSI(i);
network.rssi = WiFi.RSSI(i);
network.isEncrypted = (WiFi.encryptionType(i) != WIFI_AUTH_OPEN);
network.hasSavedPassword = WIFI_STORE.hasSavedCredential(network.ssid);
// Skip hidden networks (empty SSID) // Skip hidden networks (empty SSID)
if (!network.ssid.empty()) { if (ssid.empty()) {
networks.push_back(network); continue;
} }
// Check if we've already seen this SSID
auto it = uniqueNetworks.find(ssid);
if (it == uniqueNetworks.end() || rssi > it->second.rssi) {
// New network or stronger signal than existing entry
WifiNetworkInfo network;
network.ssid = ssid;
network.rssi = rssi;
network.isEncrypted = (WiFi.encryptionType(i) != WIFI_AUTH_OPEN);
network.hasSavedPassword = WIFI_STORE.hasSavedCredential(network.ssid);
uniqueNetworks[ssid] = network;
}
}
// Convert map to vector
networks.clear();
for (const auto& pair : uniqueNetworks) {
networks.push_back(pair.second);
} }
// Sort by signal strength (strongest first) // Sort by signal strength (strongest first)

View File

@ -52,26 +52,11 @@
</div> </div>
<script> <script>
// Dropdown toggle
function toggleDropdown() {
const dropdown = document.getElementById('addDropdown');
dropdown.classList.toggle('open');
}
// Close dropdown when clicking outside
document.addEventListener('click', function(e) {
const dropdown = document.getElementById('addDropdown');
if (dropdown && !dropdown.contains(e.target)) {
dropdown.classList.remove('open');
}
});
// Modal functions // Modal functions
function openUploadModal() { function openUploadModal() {
const currentPath = document.getElementById('currentPath').value; const currentPath = document.getElementById('currentPath').value;
document.getElementById('uploadPathDisplay').textContent = currentPath === '/' ? '/ 🏠' : currentPath; document.getElementById('uploadPathDisplay').textContent = currentPath === '/' ? '/ 🏠' : currentPath;
document.getElementById('uploadModal').classList.add('open'); document.getElementById('uploadModal').classList.add('open');
document.getElementById('addDropdown').classList.remove('open');
} }
function closeUploadModal() { function closeUploadModal() {
@ -87,7 +72,6 @@
const currentPath = document.getElementById('currentPath').value; const currentPath = document.getElementById('currentPath').value;
document.getElementById('folderPathDisplay').textContent = currentPath === '/' ? '/ 🏠' : currentPath; document.getElementById('folderPathDisplay').textContent = currentPath === '/' ? '/ 🏠' : currentPath;
document.getElementById('folderModal').classList.add('open'); document.getElementById('folderModal').classList.add('open');
document.getElementById('addDropdown').classList.remove('open');
document.getElementById('folderName').value = ''; document.getElementById('folderName').value = '';
} }

View File

@ -79,74 +79,34 @@
.nav-links a:hover { .nav-links a:hover {
background-color: #2980b9; background-color: #2980b9;
} }
/* Add dropdown styles */ /* Action buttons */
.add-dropdown { .action-buttons {
position: relative; display: flex;
display: inline-block; gap: 10px;
} }
.add-btn { .action-btn {
background-color: #e67e22;
color: white; color: white;
padding: 10px 20px; padding: 10px 16px;
border: none; border: none;
border-radius: 4px; border-radius: 4px;
cursor: pointer; cursor: pointer;
font-size: 1em; font-size: 0.95em;
font-weight: 600; font-weight: 600;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
} }
.add-btn:hover { .upload-action-btn {
background-color: #d35400; background-color: #27ae60;
} }
.add-btn .arrow { .upload-action-btn:hover {
font-size: 0.8em; background-color: #219a52;
transition: transform 0.2s;
} }
.add-dropdown.open .add-btn .arrow { .folder-action-btn {
transform: rotate(180deg); background-color: #f39c12;
} }
.dropdown-menu { .folder-action-btn:hover {
display: none; background-color: #d68910;
position: absolute;
right: 0;
top: 100%;
margin-top: 5px;
background: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
min-width: 200px;
z-index: 100;
overflow: hidden;
}
.add-dropdown.open .dropdown-menu {
display: block;
}
.dropdown-item {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 16px;
cursor: pointer;
border: none;
background: none;
width: 100%;
text-align: left;
font-size: 1em;
color: #2c3e50;
transition: background-color 0.15s;
}
.dropdown-item:hover {
background-color: #f8f9fa;
}
.dropdown-item .icon {
font-size: 1.2em;
}
.dropdown-divider {
height: 1px;
background-color: #eee;
margin: 0;
} }
/* Upload modal */ /* Upload modal */
.modal-overlay { .modal-overlay {