From e3cff5b9b773f12437b8327d756a4e751b020be8 Mon Sep 17 00:00:00 2001 From: Kumi Date: Fri, 15 Mar 2024 16:41:37 +0100 Subject: [PATCH] feat: add dynamic navbar to scenes Introduced a new CSS file for styling a fixed navbar in scenes, enhancing user navigation within the virtual environment. Modified scene.js to include fetching categories and generating a navbar with scene options dynamically based on the category of the current scene. This allows users to switch scenes more intuitively. The `nonavbar` attribute was added for scenes where the navbar should be omitted, providing flexibility in scene presentation. Additionally, streamlined CSS and SCSS imports across JS files for consistency and removed an unnecessary SCSS import from editor.js, optimizing load times and project structure. This update significantly improves user experience by facilitating easier navigation and scene exploration within the application. --- assets/css/scene.css | 5 ++ assets/js/editor.js | 1 - assets/js/scene.js | 72 ++++++++++++++++++- .../tours/templates/tours/scene_edit.html | 1 + 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 assets/css/scene.css diff --git a/assets/css/scene.css b/assets/css/scene.css new file mode 100644 index 0000000..31a8bb3 --- /dev/null +++ b/assets/css/scene.css @@ -0,0 +1,5 @@ +#sceneNavbar { + z-index: 99999; + position: fixed; + width: 100%; +} \ No newline at end of file diff --git a/assets/js/editor.js b/assets/js/editor.js index e66d606..72dae51 100644 --- a/assets/js/editor.js +++ b/assets/js/editor.js @@ -1,7 +1,6 @@ import { getScene, getSceneElement, getCategory } from "./api"; import { populateDestinationDropdown } from "./editor/teleport"; -import "../scss/frontend.scss"; import "../css/editor.css"; let clickTimestamp = 0; diff --git a/assets/js/scene.js b/assets/js/scene.js index c305984..f6e9629 100644 --- a/assets/js/scene.js +++ b/assets/js/scene.js @@ -1,4 +1,8 @@ -import { getScene } from "./api"; +import { getScene, getCategory } from "./api"; +import { Dropdown } from "bootstrap"; + +import "../scss/frontend.scss"; +import "../css/scene.css"; require("aframe"); @@ -16,8 +20,13 @@ 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; loadScene(this.scene, this.x, this.y, this.z, this, this.embedded); + + if (this.navbar) { + loadNavbar(this.scene, this); + } } } @@ -27,6 +36,67 @@ document.addEventListener("contextmenu", function (event) { customElements.define("quackscape-scene", QuackscapeScene); +// 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 diff --git a/quackscape/tours/templates/tours/scene_edit.html b/quackscape/tours/templates/tours/scene_edit.html index 8457479..c688aa4 100644 --- a/quackscape/tours/templates/tours/scene_edit.html +++ b/quackscape/tours/templates/tours/scene_edit.html @@ -30,6 +30,7 @@ y="{{ scene.default_y }}" z="{{ scene.default_z }}" embedded + nonavbar >