Enhance editor UI and user content management
Introduced significant updates to the user interface for editing VR scenes, adding new CSS styles for a coherent and modern look. Implemented data tables for robust content management in the user area, now users can easily navigate through scenes and media with DataTables integration. Expanded the API with category retrieval capabilities, enabling dynamic content categorization. The editor now seamlessly integrates into the UI with a sidebar for properties editing, improving usability. The teleportation element creation and modification logic has been significantly refined, including a search-enabled dropdown for destination selection, making it more user-friendly. Added thumbnail display for scenes and media in the user area, enhancing content overview. This update also introduced user area templates and routes, providing a foundational structure for user content management functionality, including categories and individual category views. Refactored JavaScript imports to align with the new editor CSS and adjusted scene loading to support embedded scenes, improving the flexibility and usability of scene components.
This commit is contained in:
parent
06a00262a0
commit
013d02a15c
22 changed files with 780 additions and 77 deletions
|
@ -1,9 +1,9 @@
|
|||
import { getScene, getSceneElement } from "./api";
|
||||
import { getScene, getSceneElement, getCategory } from "./api";
|
||||
import { populateDestinationDropdown } from "./editor/teleport";
|
||||
|
||||
import { Modal } from "bootstrap";
|
||||
import "../css/editor.css";
|
||||
|
||||
let clickTimestamp = 0;
|
||||
var editModal = null;
|
||||
|
||||
// Find parent quackscape-scene for ID
|
||||
function findParentScene(element) {
|
||||
|
@ -16,10 +16,6 @@ function findParentScene(element) {
|
|||
return parent;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
editModal = new Modal("#editModal");
|
||||
});
|
||||
|
||||
// Distinguishing clicks from drags based on duration.
|
||||
// TODO: Find a better way to distinguish these.
|
||||
function addEventListeners(element) {
|
||||
|
@ -44,11 +40,11 @@ function addEventListeners(element) {
|
|||
}
|
||||
|
||||
// Open a modal for creating a new Element
|
||||
function startCreateModal(event) {
|
||||
var modalLabel = document.getElementById("editModalLabel");
|
||||
function startCreateElement(event) {
|
||||
var propertiesTitle = document.getElementById("propertiesTitle");
|
||||
modalLabel.textContent = "Create Element";
|
||||
|
||||
var modalContent = document.getElementById("editModalContent");
|
||||
var propertiesContent = document.getElementById("propertiesContent");
|
||||
|
||||
var thetaStart = cartesianToTheta(
|
||||
event.detail.intersection.point.x,
|
||||
|
@ -65,21 +61,20 @@ function startCreateModal(event) {
|
|||
<hr/>
|
||||
|
||||
<form id="newElementForm">
|
||||
<select class="form-select" aria-label="Default select example">
|
||||
<option selected>Select Element Type</option>
|
||||
<option value="1">Marker</option>
|
||||
<option value="2">Image</option>
|
||||
<option value="3">Teleport</option>
|
||||
</select>
|
||||
<label for="resourcetype" class="form-label">Element Type</label>
|
||||
<select class="form-control" aria-label="Element Type" id="resourcetype">
|
||||
<option selected>Select Element Type</option>
|
||||
<option value="MarkerElement">Marker</option>
|
||||
<option value="ImageElement">Image</option>
|
||||
<option value="ImageElement">Teleport</option>
|
||||
</select>
|
||||
</form>
|
||||
`;
|
||||
|
||||
editModal.show();
|
||||
}
|
||||
|
||||
function startModifyModal(event) {
|
||||
var modalLabel = document.getElementById("editModalLabel");
|
||||
modalLabel.textContent = "Modify Element";
|
||||
function startModifyElement(event) {
|
||||
var propertiesTitle = document.getElementById("propertiesTitle");
|
||||
propertiesTitle.textContent = "Modify Element";
|
||||
|
||||
// Get element from API
|
||||
var scene = findParentScene(event.target);
|
||||
|
@ -90,21 +85,93 @@ function startModifyModal(event) {
|
|||
);
|
||||
|
||||
element_data_request.then((element_data) => {
|
||||
console.log(element_data);
|
||||
var propertiesContent = document.getElementById("propertiesContent");
|
||||
|
||||
var modalContent = document.getElementById("editModalContent");
|
||||
|
||||
modalContent.innerHTML = `<b>Modifying element:</b><br/>
|
||||
propertiesContent.innerHTML = `<b>Modifying element:</b><br/>
|
||||
Element Type: ${event.srcElement.tagName}<br/>
|
||||
Element ID: ${event.target.getAttribute("id")}<br/>
|
||||
Element data: ${JSON.stringify(element_data.obj)}<br/>
|
||||
<hr/>
|
||||
|
||||
<form id="modifyElementForm">
|
||||
<input type="hidden" id="id" value="${event.target.getAttribute("id")}">
|
||||
<div class="dropdown mb-2">
|
||||
<label for="destinationDropdownSearch" class="form-label">Teleport Destination</label>
|
||||
<input class="form-control" autocomplete="off" id="destinationDropdownSearch" type="text" placeholder="Search...">
|
||||
<input type="hidden" id="destination">
|
||||
<div class="dropdown-menu" id="destinationDropdownMenu">
|
||||
<!-- Dropdown items will be populated here by JavaScript -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label for="destination_x" class="form-label">Destination X/Y/Z Rotation</label>
|
||||
<div class="row g-2">
|
||||
<div class="col">
|
||||
<input type="number" class="form-control" id="destination_x" name="input1" min="0" max="360" placeholder="X">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="number" class="form-control" id="destination_y" name="input2" min="0" max="360" placeholder="Y">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="number" class="form-control" id="destination_z" name="input3" min="0" max="360" placeholder="Z">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label for="elementUpload" class="form-label">Marker image</label>
|
||||
<input id="elementUpload" type="file" class="form-control">
|
||||
</div>
|
||||
|
||||
</form>
|
||||
`;
|
||||
|
||||
editModal.show();
|
||||
var scene_data_request = getScene(scene.getAttribute("id"));
|
||||
scene_data_request.then((scene_data) => {
|
||||
var category_data_request = getCategory(scene_data.obj.category);
|
||||
|
||||
category_data_request.then((category_data) => {
|
||||
populateDestinationDropdown(
|
||||
element_data.obj.destination,
|
||||
category_data
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
document
|
||||
.getElementById("elementUpload")
|
||||
.addEventListener("change", function () {
|
||||
if (this.files && this.files[0]) {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onload = function (e) {
|
||||
// Set the image to the file contents
|
||||
if (event.target.getAttribute("data-original-src") == undefined) {
|
||||
event.target.setAttribute("data-original-src", event.target.getAttribute("src"));
|
||||
}
|
||||
event.target.setAttribute("src", e.target.result);
|
||||
};
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
}
|
||||
});
|
||||
|
||||
if (element_data.obj.destination_x != -1) {
|
||||
document.getElementById("destination_x").value =
|
||||
element_data.obj.destination_x;
|
||||
}
|
||||
if (element_data.obj.destination_y != -1) {
|
||||
document.getElementById("destination_y").value =
|
||||
element_data.obj.destination_y;
|
||||
}
|
||||
if (element_data.obj.destination_z != -1) {
|
||||
document.getElementById("destination_z").value =
|
||||
element_data.obj.destination_z;
|
||||
}
|
||||
|
||||
document.getElementById("resetButton").style = "display: inline;";
|
||||
document.getElementById("buttons").style = "display: block;";
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -138,12 +205,12 @@ function latLonToXYZ(lat, lon, radius = 5) {
|
|||
}
|
||||
|
||||
function handleClick(event) {
|
||||
console.log(event);
|
||||
|
||||
// If clicked on the sky, start creating a new element
|
||||
if (event.target.tagName == "A-SKY") {
|
||||
startCreateModal(event);
|
||||
startCreateElement(event);
|
||||
} else {
|
||||
startModifyModal(event);
|
||||
// Else we are modifying an existing element
|
||||
startModifyElement(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue