From 0999d2f16e15ced4b4947d662abf5a46edd7d2d7 Mon Sep 17 00:00:00 2001 From: Kumi Date: Fri, 15 Mar 2024 19:27:19 +0100 Subject: [PATCH] feat: add dynamic sidebar for scenes Introduce a new sidebar in the UI for enhanced navigation through scenes. This feature includes CSS modifications for styling, updates in JavaScript to dynamically load sidebar content based on scene categories, and template adjustments to include the sidebar option. By leveraging the Collapse component from Bootstrap alongside existing infrastructure, this addition enriches user interaction by providing a convenient and visually appealing method to explore different scenes within the application. The sidebar's design and functionality are thoughtfully integrated to ensure a cohesive and user-friendly experience. The decision to implement a sidebar stemmed from the need to improve navigational efficiency and user engagement with the content. This change is part of a broader effort to enhance the UI/UX of the application, aiming to make the exploration of scenes more intuitive and accessible. --- assets/css/scene.css | 11 +++- assets/js/scene.js | 65 ++++++++++++++++++- quackscape/tours/templates/tours/scene.html | 3 +- .../tours/templates/tours/scene_edit.html | 1 - 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/assets/css/scene.css b/assets/css/scene.css index 31a8bb3..5d188d9 100644 --- a/assets/css/scene.css +++ b/assets/css/scene.css @@ -2,4 +2,13 @@ z-index: 99999; position: fixed; width: 100%; -} \ No newline at end of file +} + +#sceneSidebar { + z-index: 99999; + position: fixed; + width: 250px; + height: 100%; + background-color: #f8f9fa; + opacity: 0.7; +} diff --git a/assets/js/scene.js b/assets/js/scene.js index f6e9629..3f40ef9 100644 --- a/assets/js/scene.js +++ b/assets/js/scene.js @@ -1,5 +1,5 @@ import { getScene, getCategory } from "./api"; -import { Dropdown } from "bootstrap"; +import { Dropdown, Collapse } from "bootstrap"; import "../scss/frontend.scss"; import "../css/scene.css"; @@ -20,13 +20,18 @@ class QuackscapeScene extends HTMLElement { this.x = this.getAttribute("x") | 0; this.y = this.getAttribute("y") | 0; this.z = this.getAttribute("z") | 0; - this.navbar = this.getAttribute("nonavbar") == undefined; + this.navbar = this.getAttribute("navbar") != undefined; + this.sidebar = this.getAttribute("sidebar") != undefined; loadScene(this.scene, this.x, this.y, this.z, this, this.embedded); if (this.navbar) { loadNavbar(this.scene, this); } + + if (this.sidebar) { + loadSidebar(this.scene, this); + } } } @@ -36,6 +41,62 @@ 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 btn-primary"); + button.setAttribute("type", "button"); + button.setAttribute("data-bs-toggle", "collapse"); + button.setAttribute("data-bs-target", "#sceneSidebar"); + button.setAttribute("aria-expanded", false); + button.setAttribute("aria-controls", "sceneSidebar"); + button.textContent = "<"; + + //p.appendChild(button); // TODO: Make it prettier before enabling. + + sidebar.appendChild(p); + + destination.prepend(sidebar); + }); + }); +} + // Function to add a navbar to the destination object async function loadNavbar(scene_id, destination) { diff --git a/quackscape/tours/templates/tours/scene.html b/quackscape/tours/templates/tours/scene.html index f57dfc7..07d9c7d 100644 --- a/quackscape/tours/templates/tours/scene.html +++ b/quackscape/tours/templates/tours/scene.html @@ -14,12 +14,13 @@ src="{% static 'js/scene.bundle.js' %}" > - + diff --git a/quackscape/tours/templates/tours/scene_edit.html b/quackscape/tours/templates/tours/scene_edit.html index c688aa4..8457479 100644 --- a/quackscape/tours/templates/tours/scene_edit.html +++ b/quackscape/tours/templates/tours/scene_edit.html @@ -30,7 +30,6 @@ y="{{ scene.default_y }}" z="{{ scene.default_z }}" embedded - nonavbar >