From 41fd167d507258e3ec36fef5c36fa41e1be8054d Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Mon, 17 Nov 2025 10:16:01 -0300 Subject: [PATCH] feat(layout): add section caching with dynamic container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor `layout.js` to improve section loading performance: - Removed unused sections from the `sections` map. - Introduced `sectionCache` to store loaded sections. - Created a reusable `#section-container` element for managing section DOM nodes. - Implemented lazy loading with a loading placeholder and show/hide logic for cached sections. - Optimized CSS handling by reusing existing stylesheet links instead of removing and recreating them. - Added safeguards to avoid reloading already‑loaded JS modules. --- web/desktop/js/layout.js | 84 +++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/web/desktop/js/layout.js b/web/desktop/js/layout.js index 286448da3..d8b160c19 100644 --- a/web/desktop/js/layout.js +++ b/web/desktop/js/layout.js @@ -3,14 +3,8 @@ const sections = { tasks: 'tasks/tasks.html', mail: 'mail/mail.html', chat: 'chat/chat.html', - dashboard: 'dashboard/dashboard.html', - editor: 'editor/editor.html', - player: 'player/player.html', - paper: 'paper/paper.html', - settings: 'settings/settings.html', - tables: 'tables/tables.html', - news: 'news/news.html' }; +const sectionCache = {}; async function loadSectionHTML(path) { const response = await fetch(path); @@ -20,28 +14,74 @@ async function loadSectionHTML(path) { async function switchSection(section) { const mainContent = document.getElementById('main-content'); - + try { const htmlPath = sections[section]; console.log('Loading section:', section, 'from', htmlPath); - const cssPath = - htmlPath.replace('.html', '.css'); - + const cssPath = htmlPath.replace('.html', '.css'); + // Remove any existing section CSS document.querySelectorAll('link[data-section-css]').forEach(link => link.remove()); - - // Load CSS first - const cssLink = document.createElement('link'); - cssLink.rel = 'stylesheet'; - cssLink.href = cssPath; - cssLink.setAttribute('data-section-css', 'true'); - document.head.appendChild(cssLink); - // First load HTML - const html = await loadSectionHTML(htmlPath); - mainContent.innerHTML = html; + // Load CSS first (skip if already loaded) + let cssLink = document.querySelector(`link[href="${cssPath}"]`); + if (!cssLink) { + cssLink = document.createElement('link'); + cssLink.rel = 'stylesheet'; + cssLink.href = cssPath; + cssLink.setAttribute('data-section-css', 'true'); + document.head.appendChild(cssLink); + } - // Then load JS after HTML is inserted + // Hide previously loaded sections and show the requested one + // Ensure a container exists for sections + let container = document.getElementById('section-container'); + if (!container) { + container = document.createElement('div'); + container.id = 'section-container'; + mainContent.appendChild(container); + } + + const targetDiv = document.getElementById(`section-${section}`); + + if (targetDiv) { + // Section already loaded: hide others, show this one + container.querySelectorAll('.section').forEach(div => { + div.style.display = 'none'; + }); + targetDiv.style.display = 'block'; + } else { + // Show loading placeholder inside the container + const loadingDiv = document.createElement('div'); + loadingDiv.className = 'loading'; + loadingDiv.textContent = 'Loading…'; + container.appendChild(loadingDiv); + + // Load HTML + const html = await loadSectionHTML(htmlPath); + // Create wrapper for the new section + const wrapper = document.createElement('div'); + wrapper.id = `section-${section}`; + wrapper.className = 'section'; + wrapper.innerHTML = html; + + // Hide any existing sections + container.querySelectorAll('.section').forEach(div => { + div.style.display = 'none'; + }); + + // Remove loading placeholder + container.removeChild(loadingDiv); + + // Add the new section to the container and cache it + container.appendChild(wrapper); + sectionCache[section] = wrapper; + + // Ensure the new section is visible + wrapper.style.display = 'block'; + } + + // Then load JS after HTML is inserted (skip if already loaded) const jsPath = htmlPath.replace('.html', '.js'); const existingScript = document.querySelector(`script[src="${jsPath}"]`); if (!existingScript) {