diff --git a/src/main.js b/src/main.js index edafc5a0d..a7e9ac81e 100644 --- a/src/main.js +++ b/src/main.js @@ -231,6 +231,9 @@ async function onDeviceReady() { // load plugins try { await loadPlugins(); + // Ensure at least one sidebar app is active after all plugins are loaded + // This handles cases where the stored section was from an uninstalled plugin + sidebarApps.ensureActiveApp(); // Re-emit events for active file after plugins are loaded const { activeFile } = editorManager; diff --git a/src/sidebarApps/index.js b/src/sidebarApps/index.js index 3cead9b7a..c08636c84 100644 --- a/src/sidebarApps/index.js +++ b/src/sidebarApps/index.js @@ -48,11 +48,14 @@ function add( function remove(id) { const app = apps.find((app) => app.id === id); if (!app) return; + const wasActive = app.active; app.remove(); apps.splice(apps.indexOf(app), 1); - if (app.active) { + if (wasActive && apps.length > 0) { const firstApp = apps[0]; firstApp.active = true; + currentSection = firstApp.id; + localStorage.setItem(SIDEBAR_APPS_LAST_SECTION, firstApp.id); } } @@ -78,6 +81,22 @@ async function loadApps() { $apps.append(); } +/** + * Ensures that at least one app is active. + * Call this AFTER all plugins have been loaded to handle cases where + * the stored section was from an uninstalled plugin. + * @returns {void} + */ +function ensureActiveApp() { + const hasActiveApp = apps.some((app) => app.active); + if (!hasActiveApp && apps.length > 0) { + const firstApp = apps[0]; + firstApp.active = true; + currentSection = firstApp.id; + localStorage.setItem(SIDEBAR_APPS_LAST_SECTION, firstApp.id); + } +} + /** * Gets the container of the app with the given ID. * @param {string} id @@ -101,8 +120,8 @@ function onclick(e) { localStorage.setItem(SIDEBAR_APPS_LAST_SECTION, id); const activeApp = apps.find((app) => app.active); const app = apps.find((app) => app.id === id); - activeApp.active = false; - app.active = true; + if (activeApp) activeApp.active = false; + if (app) app.active = true; } export default { @@ -111,4 +130,5 @@ export default { get, remove, loadApps, + ensureActiveApp, }; diff --git a/src/sidebarApps/sidebarApp.js b/src/sidebarApps/sidebarApp.js index 95409f0e6..df147dcdd 100644 --- a/src/sidebarApps/sidebarApp.js +++ b/src/sidebarApps/sidebarApp.js @@ -89,8 +89,29 @@ export default class SidebarApp { this.#active = !!value; this.#icon.classList.toggle("active", this.#active); if (this.#active) { - const child = getContainer(this.#container); - $sidebar.replaceChild($contaienr, child); + const oldContainer = getContainer(this.#container); + // Try to replace the old container, or append if it's not in the DOM + try { + if (oldContainer && oldContainer.parentNode === $sidebar) { + $sidebar.replaceChild($contaienr, oldContainer); + } else { + // Old container not in sidebar, just append the new one + const existingContainer = $sidebar.get(".container"); + if (existingContainer) { + $sidebar.replaceChild($contaienr, existingContainer); + } else { + $sidebar.appendChild($contaienr); + } + } + } catch (error) { + // Fallback: append the new container + console.warn("Error switching sidebar container:", error); + const existingContainer = $sidebar.get(".container"); + if (existingContainer) { + existingContainer.remove(); + } + $sidebar.appendChild($contaienr); + } this.#onselect(this.#container); } } @@ -111,10 +132,14 @@ export default class SidebarApp { } remove() { - this.#icon.remove(); - this.#container.remove(); - this.#icon = null; - this.#container = null; + if (this.#icon) { + this.#icon.remove(); + this.#icon = null; + } + if (this.#container) { + this.#container.remove(); + this.#container = null; + } } }