Revert optimisations sidebar/fetch qui causaient des blocages navigateur

Retour a l'etat 408ab76. Les tentatives d'optimisation du nombre
de fetch (sidebar unique, config partagee, sequencement) causaient
des blocages sur Chrome/Firefox. On garde les features (forget wifi,
hotspot badge, UI wifi) mais on revient au chargement d'origine.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
PaulVua
2026-03-17 18:48:38 +01:00
parent ffead8597a
commit 8f88eae575
11 changed files with 255 additions and 219 deletions

View File

@@ -412,20 +412,23 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => { document.getElementById('topbar').innerHTML = data; })
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
});
//end document.addEventListener

View File

@@ -5,32 +5,26 @@
* - Shows/Hides "Screen" sidebar tab based on device type
* - Updates sidebar device name
* - Shows hotspot badge in sidebar when in hotspot mode
*
* Fetches config at window.onload (not DOMContentLoaded) to avoid
* saturating the browser's 6-connection-per-domain limit.
*/
(function() {
document.addEventListener('DOMContentLoaded', () => {
let config = null;
// Observe DOM changes to apply config when sidebar/topbar are loaded
const observer = new MutationObserver(() => {
if (config) applyConfig();
});
observer.observe(document.body, { childList: true, subtree: true });
// Fetch config after all initial resources are loaded
window.addEventListener('load', () => {
// Fetch config once
fetch('launcher.php?type=get_config_sqlite')
.then(response => response.json())
.then(data => {
config = data;
window._nebuleairConfig = data;
applyConfig();
document.dispatchEvent(new CustomEvent('nebuleair-config-ready', { detail: data }));
applyConfig(); // Apply immediately if elements are ready
})
.catch(error => console.error('Error loading config:', error));
// Observe DOM changes to handle dynamically loaded elements (sidebar, topbar)
const observer = new MutationObserver(() => {
if (config) applyConfig();
});
observer.observe(document.body, { childList: true, subtree: true });
function applyConfig() {
if (!config) return;
@@ -39,12 +33,13 @@
// 1. Topbar Logo Logic
const logo = document.getElementById('topbar-logo');
if (logo && isModuleAirPro) {
// prevent unnecessary re-assignments
if (!logo.src.includes('logoModuleAir.png')) {
logo.src = 'assets/img/logoModuleAir.png';
}
}
// 2. Sidebar Screen Tab Logic
// 2. Sidebar Screen Tab Logic - Use class since ID might be duplicated (desktop/mobile)
const navScreenElements = document.querySelectorAll('.nav-screen-item');
if (navScreenElements.length > 0) {
navScreenElements.forEach(navScreen => {
@@ -73,4 +68,4 @@
badge.style.display = (config.WIFI_status === 'hotspot') ? '' : 'none';
});
}
})();
});

View File

@@ -181,6 +181,15 @@
document.addEventListener('DOMContentLoaded', function () {
console.log("DOMContentLoaded");
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
let loadedCount = 0;
const totalElements = elementsToLoad.length;
function applyTranslationsWhenReady() {
if (typeof i18n !== 'undefined' && i18n.translations && Object.keys(i18n.translations).length > 0) {
console.log("Applying translations to dynamically loaded content");
@@ -191,28 +200,23 @@
}
}
let loadedCount = 0;
// Load topbar
fetch('topbar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('topbar').innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
loadedCount++;
if (loadedCount === 2) applyTranslationsWhenReady();
})
.catch(e => console.error('Error loading topbar:', e));
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
loadedCount++;
if (loadedCount === 2) applyTranslationsWhenReady();
// Re-apply translations after all dynamic content is loaded
if (loadedCount === totalElements) {
applyTranslationsWhenReady();
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
// Also listen for language change events to re-apply translations
document.addEventListener('languageChanged', function() {

View File

@@ -136,28 +136,27 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => {
document.getElementById('topbar').innerHTML = data;
if (window.i18n && typeof window.i18n.applyTranslations === 'function') {
window.i18n.applyTranslations();
}
})
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
// Apply translations after loading dynamic content
if (window.i18n && typeof window.i18n.applyTranslations === 'function') {
window.i18n.applyTranslations();
}
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
});

View File

@@ -96,20 +96,23 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => { document.getElementById('topbar').innerHTML = data; })
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
const loop_card_content = document.getElementById('card_loop_content');
const boot_card_content = document.getElementById('card_boot_content');

View File

@@ -121,20 +121,23 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => { document.getElementById('topbar').innerHTML = data; })
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});

View File

@@ -397,20 +397,23 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => { document.getElementById('topbar').innerHTML = data; })
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
//OLD way to retreive data from JSON
/*

View File

@@ -108,37 +108,34 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => {
document.getElementById('topbar').innerHTML = data;
if (window.i18n && typeof window.i18n.applyTranslations === 'function') {
window.i18n.applyTranslations();
}
})
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
const sidebar = document.getElementById('sidebar');
const sidebarMobile = document.getElementById('sidebar_mobile');
sidebar.innerHTML = data;
sidebarMobile.innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
// Apply translations after loading dynamic content
if (window.i18n && typeof window.i18n.applyTranslations === 'function') {
window.i18n.applyTranslations();
}
// Ensure the screen tab is visible in both sidebars
// Ensure the screen tab is visible here as well
if (id.includes('sidebar')) {
setTimeout(() => {
[sidebar, sidebarMobile].forEach(el => {
const navScreenElements = el.querySelectorAll('.nav-screen-item');
navScreenElements.forEach(item => item.style.display = 'flex');
});
const navScreenElements = element.querySelectorAll('.nav-screen-item');
navScreenElements.forEach(el => el.style.display = 'flex');
}, 100);
}
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
// Translation fallback for now if keys are missing
setTimeout(() => {

View File

@@ -89,28 +89,27 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => {
document.getElementById('topbar').innerHTML = data;
if (window.i18n && typeof window.i18n.applyTranslations === 'function') {
window.i18n.applyTranslations();
}
})
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
// Apply translations after loading dynamic content
if (window.i18n && typeof window.i18n.applyTranslations === 'function') {
window.i18n.applyTranslations();
}
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
});
function getNPM_values(port) {

View File

@@ -179,20 +179,23 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => { document.getElementById('topbar').innerHTML = data; })
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
// Initialize elements
initializeElements();

View File

@@ -215,24 +215,23 @@
document.addEventListener('DOMContentLoaded', function () {
console.log("DOMContentLoaded");
// Load topbar
fetch('topbar.html')
.then(r => r.text())
.then(data => { document.getElementById('topbar').innerHTML = data; })
.catch(e => console.error('Error loading topbar:', e));
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
// Load sidebar once, reuse for desktop + mobile
fetch('sidebar.html')
.then(r => r.text())
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
document.getElementById('sidebar').innerHTML = data;
document.getElementById('sidebar_mobile').innerHTML = data;
// Re-apply translations to dynamically loaded sidebar
if (typeof i18n !== 'undefined' && i18n.translations) {
i18n.applyTranslations();
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
})
.catch(e => console.error('Error loading sidebar:', e));
.catch(error => console.error(`Error loading ${file}:`, error));
});
});
@@ -564,12 +563,16 @@ function get_internet(){
// Wait for config loaded by topbar-logo.js (fires after window.onload)
document.addEventListener('nebuleair-config-ready', function(e) {
const data = e.detail;
console.log("Config loaded (wifi page):");
window.onload = function() {
$.ajax({
url: 'launcher.php?type=get_config_sqlite',
dataType: 'json',
method: 'GET',
success: function(data) {
console.log("Getting SQLite config table (wifi page):");
console.log(data);
// WiFi connection status — toggle cards
const WIFI_statusElement = document.getElementById("wifi-status");
console.log("WIFI is: " + data.WIFI_status);
@@ -580,6 +583,7 @@ function get_internet(){
document.getElementById('card-connection-info').style.display = '';
document.getElementById('card-hotspot-info').style.display = 'none';
document.getElementById('card-wifi-scan').style.display = 'none';
// Auto-load connection details
get_internet();
} else if (data.WIFI_status === "hotspot") {
WIFI_statusElement.textContent = "Hotspot";
@@ -588,6 +592,7 @@ function get_internet(){
document.getElementById('card-connection-info').style.display = 'none';
document.getElementById('card-hotspot-info').style.display = '';
document.getElementById('card-wifi-scan').style.display = '';
// Auto-load cached scan results in hotspot mode
wifi_scan();
} else {
WIFI_statusElement.textContent = "Unknown";
@@ -597,8 +602,30 @@ function get_internet(){
document.getElementById('card-hotspot-info').style.display = 'none';
document.getElementById('card-wifi-scan').style.display = '';
}
// Always load ethernet info
load_ethernet_info();
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
// Load RTC time
$.ajax({
url: 'launcher.php?type=RTC_time',
dataType: 'text',
method: 'GET',
success: function(response) {
const RTC_Element = document.getElementById("RTC_time");
if (RTC_Element) RTC_Element.textContent = response;
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
</script>
</body>