From 85c44f985d0751b87c4d0fe1898941971951bc7e Mon Sep 17 00:00:00 2001 From: Kumi Date: Sat, 16 Mar 2024 11:16:26 +0100 Subject: [PATCH] refactor(scene): modularize sidebar and navbar loading Refactored the scene script to extract the logic for loading sidebars and navbars into separate, modular files. This change enhances code maintainability and readability by compartmentalizing responsibilities and clarifying function boundaries. Now, `navbar.js` and `sidebar.js` handle the UI component rendering, allowing for easier updates and potential reuse. Adjusted conditional rendering logic to ensure exclusive navbar or sidebar presence, aligning UI behavior with design expectations. This commit signifies a step towards modular architecture in the frontend codebase, facilitating future expansion and modification. --- assets/js/scene.js | 144 ++----------------------------------- assets/js/scene/navbar.js | 64 +++++++++++++++++ assets/js/scene/sidebar.js | 81 +++++++++++++++++++++ 3 files changed, 149 insertions(+), 140 deletions(-) create mode 100644 assets/js/scene/navbar.js create mode 100644 assets/js/scene/sidebar.js diff --git a/assets/js/scene.js b/assets/js/scene.js index c0a6f48..ab63817 100644 --- a/assets/js/scene.js +++ b/assets/js/scene.js @@ -1,4 +1,7 @@ import { getScene, getCategory } from "./api"; +import { loadSidebar } from "./scene/sidebar"; +import { loadNavbar } from "./scene/navbar"; + import { Dropdown, Collapse } from "bootstrap"; import "../scss/frontend.scss"; @@ -29,7 +32,7 @@ class QuackscapeScene extends HTMLElement { loadNavbar(this.scene, this); } - if (this.sidebar) { + else if (this.sidebar) { loadSidebar(this.scene, this); } } @@ -41,132 +44,6 @@ document.addEventListener("contextmenu", function (event) { customElements.define("quackscape-scene", QuackscapeScene); -// Function to add a sidebar to the destination object - -async function loadSidebar(scene_id, destination) { - getScene(scene_id).then((scene) => { - getCategory(scene.obj.category).then((category) => { - var sidebar = document.createElement("div"); - sidebar.setAttribute("class", "collapse show"); - sidebar.setAttribute("id", "sceneSidebar"); - - var p = document.createElement("div"); - p.setAttribute("class", "p-4"); - - var h5 = document.createElement("h5"); - h5.setAttribute("class", "font-weight-bold"); - h5.textContent = "Scenes"; - - var ul = document.createElement("ul"); - ul.setAttribute("class", "nav flex-column"); - - category.obj.scenes.forEach((scene) => { - var li = document.createElement("li"); - li.setAttribute("class", "nav-item"); - - var a = document.createElement("a"); - a.setAttribute("href", "#"); - a.setAttribute("class", "nav-link"); - a.textContent = scene.title; - a.addEventListener("click", function () { - loadScene(scene.id, -1, -1, -1, destination); - }); - - li.appendChild(a); - ul.appendChild(li); - }); - - p.appendChild(h5); - p.appendChild(ul); - - var button = document.createElement("button"); - button.setAttribute("class", "btn-close-sidebar"); - button.setAttribute("type", "button"); - button.setAttribute("id", "btnCloseSidebar"); - button.textContent = "Close Sidebar"; - - button.addEventListener("click", function () { - toggleSidebar(); - }); - - sidebar.appendChild(button); // TODO: Make it prettier before enabling. - sidebar.appendChild(p); - - var reopenButton = document.createElement("button"); - reopenButton.setAttribute("class", "btn-open-sidebar hide"); - reopenButton.textContent = "Open Sidebar"; - reopenButton.addEventListener("click", function () { - toggleSidebar(); - }); - - destination.prepend(reopenButton); - - destination.prepend(sidebar); - }); - }); -} - -// Function to add a navbar to the destination object - -async function loadNavbar(scene_id, destination) { - getScene(scene_id).then((scene) => { - getCategory(scene.obj.category).then((category) => { - var nav = document.createElement("nav"); - nav.setAttribute("class", "navbar navbar-expand-lg navbar-dark bg-dark"); - nav.setAttribute("id", "sceneNavbar"); - - var container = document.createElement("div"); - container.setAttribute("class", "container-fluid"); - - var dropdown = document.createElement("div"); - dropdown.setAttribute("class", "dropdown"); - - var sceneSelector = document.createElement("button"); - sceneSelector.setAttribute("class", "btn btn-secondary dropdown-toggle"); - sceneSelector.setAttribute("type", "button"); - sceneSelector.setAttribute("id", "sceneSelector"); - sceneSelector.setAttribute("data-bs-toggle", "dropdown"); - sceneSelector.setAttribute("aria-expanded", "true"); - sceneSelector.textContent = "Select Scene"; - - var dropdownMenu = document.createElement("ul"); - dropdownMenu.setAttribute("class", "dropdown-menu show"); - dropdownMenu.setAttribute("aria-labelledby", "sceneSelector"); - console.log(dropdownMenu); - - category.obj.scenes.forEach((scene) => { - console.log(scene); - var sceneLink = document.createElement("a"); - sceneLink.setAttribute("class", "dropdown-item"); - sceneLink.setAttribute("href", "#"); - sceneLink.textContent = scene.title; - sceneLink.addEventListener("click", function () { - loadScene(scene.id, -1, -1, -1, destination); - }); - - dropdownMenu.appendChild(sceneLink); - }); - - var sceneTitle = document.createElement("a"); - sceneTitle.setAttribute("class", "navbar-brand"); - sceneTitle.setAttribute("href", "#"); - sceneTitle.setAttribute("id", "sceneTitle"); - sceneTitle.textContent = scene.obj.title; - - dropdown.appendChild(sceneSelector); - dropdown.appendChild(dropdownMenu); - console.log(dropdownMenu); - - container.appendChild(dropdown); - container.appendChild(sceneTitle); - - nav.appendChild(container); - - destination.prepend(nav); - }); - }); -} - // Function to load a scene into a destination object // x and y signify the initial looking direction, -1 for the scene's default @@ -280,19 +157,6 @@ async function loadScene( }); } -function toggleSidebar() { - const sidebar = document.getElementById("sceneSidebar"); - const reopenButton = document.querySelector(".btn-open-sidebar"); - - if (!sidebar.classList.contains("show")) { - sidebar.classList.add("show"); - reopenButton.classList.add("hide"); - } else { - sidebar.classList.remove("show"); - reopenButton.classList.remove("hide"); - } -} - window.loadScene = loadScene; diff --git a/assets/js/scene/navbar.js b/assets/js/scene/navbar.js new file mode 100644 index 0000000..d29dc99 --- /dev/null +++ b/assets/js/scene/navbar.js @@ -0,0 +1,64 @@ +import { getScene, getCategory } from "../api"; + +// Function to add a navbar to the destination object + +async function loadNavbar(scene_id, destination) { + getScene(scene_id).then((scene) => { + getCategory(scene.obj.category).then((category) => { + var nav = document.createElement("nav"); + nav.setAttribute("class", "navbar navbar-expand-lg navbar-dark bg-dark"); + nav.setAttribute("id", "sceneNavbar"); + + var container = document.createElement("div"); + container.setAttribute("class", "container-fluid"); + + var dropdown = document.createElement("div"); + dropdown.setAttribute("class", "dropdown"); + + var sceneSelector = document.createElement("button"); + sceneSelector.setAttribute("class", "btn btn-secondary dropdown-toggle"); + sceneSelector.setAttribute("type", "button"); + sceneSelector.setAttribute("id", "sceneSelector"); + sceneSelector.setAttribute("data-bs-toggle", "dropdown"); + sceneSelector.setAttribute("aria-expanded", "true"); + sceneSelector.textContent = "Select Scene"; + + var dropdownMenu = document.createElement("ul"); + dropdownMenu.setAttribute("class", "dropdown-menu show"); + dropdownMenu.setAttribute("aria-labelledby", "sceneSelector"); + console.log(dropdownMenu); + + category.obj.scenes.forEach((scene) => { + console.log(scene); + var sceneLink = document.createElement("a"); + sceneLink.setAttribute("class", "dropdown-item"); + sceneLink.setAttribute("href", "#"); + sceneLink.textContent = scene.title; + sceneLink.addEventListener("click", function () { + loadScene(scene.id, -1, -1, -1, destination); + }); + + dropdownMenu.appendChild(sceneLink); + }); + + var sceneTitle = document.createElement("a"); + sceneTitle.setAttribute("class", "navbar-brand"); + sceneTitle.setAttribute("href", "#"); + sceneTitle.setAttribute("id", "sceneTitle"); + sceneTitle.textContent = scene.obj.title; + + dropdown.appendChild(sceneSelector); + dropdown.appendChild(dropdownMenu); + console.log(dropdownMenu); + + container.appendChild(dropdown); + container.appendChild(sceneTitle); + + nav.appendChild(container); + + destination.prepend(nav); + }); + }); + } + + export { loadNavbar }; \ No newline at end of file diff --git a/assets/js/scene/sidebar.js b/assets/js/scene/sidebar.js new file mode 100644 index 0000000..62087e6 --- /dev/null +++ b/assets/js/scene/sidebar.js @@ -0,0 +1,81 @@ +import { getScene, getCategory } from "../api"; + +// Function to add a sidebar to the destination object + +async function loadSidebar(scene_id, destination) { + getScene(scene_id).then((scene) => { + getCategory(scene.obj.category).then((category) => { + var sidebar = document.createElement("div"); + sidebar.setAttribute("class", "collapse show"); + sidebar.setAttribute("id", "sceneSidebar"); + + var p = document.createElement("div"); + p.setAttribute("class", "p-4"); + + var h5 = document.createElement("h5"); + h5.setAttribute("class", "font-weight-bold"); + h5.textContent = "Scenes"; + + var ul = document.createElement("ul"); + ul.setAttribute("class", "nav flex-column"); + + category.obj.scenes.forEach((scene) => { + var li = document.createElement("li"); + li.setAttribute("class", "nav-item"); + + var a = document.createElement("a"); + a.setAttribute("href", "#"); + a.setAttribute("class", "nav-link"); + a.textContent = scene.title; + a.addEventListener("click", function () { + loadScene(scene.id, -1, -1, -1, destination); + }); + + li.appendChild(a); + ul.appendChild(li); + }); + + p.appendChild(h5); + p.appendChild(ul); + + var button = document.createElement("button"); + button.setAttribute("class", "btn-close-sidebar"); + button.setAttribute("type", "button"); + button.setAttribute("id", "btnCloseSidebar"); + button.textContent = "Close Sidebar"; + + button.addEventListener("click", function () { + toggleSidebar(); + }); + + sidebar.appendChild(button); // TODO: Make it prettier before enabling. + sidebar.appendChild(p); + + var reopenButton = document.createElement("button"); + reopenButton.setAttribute("class", "btn-open-sidebar hide"); + reopenButton.textContent = "Open Sidebar"; + reopenButton.addEventListener("click", function () { + toggleSidebar(); + }); + + destination.prepend(reopenButton); + + destination.prepend(sidebar); + }); + }); +} + +function toggleSidebar() { + const sidebar = document.getElementById("sceneSidebar"); + const reopenButton = document.querySelector(".btn-open-sidebar"); + + if (!sidebar.classList.contains("show")) { + sidebar.classList.add("show"); + reopenButton.classList.add("hide"); + } else { + sidebar.classList.remove("show"); + reopenButton.classList.remove("hide"); + } +} + +export { loadSidebar, toggleSidebar }; \ No newline at end of file