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.
86 lines
2.7 KiB
JavaScript
86 lines
2.7 KiB
JavaScript
import { Dropdown } from "bootstrap";
|
|
|
|
function selectDestinationItem(item) {
|
|
// Set the input value to the selected scene's UUID
|
|
const destinationField = document.getElementById("destination");
|
|
destinationField.value = item.id;
|
|
|
|
const dropdownSearch = document.getElementById("destinationDropdownSearch");
|
|
dropdownSearch.value = item.title;
|
|
}
|
|
|
|
function populateDestinationDropdown(initial, category_data) {
|
|
const items = category_data.obj.scenes;
|
|
|
|
const dropdownMenu = document.getElementById("destinationDropdownMenu");
|
|
const dropdownSearch = document.getElementById("destinationDropdownSearch");
|
|
const dropdown = new Dropdown(dropdownSearch);
|
|
|
|
if (initial != null) {
|
|
// Get object from items by id
|
|
const initial_item = items.find((item) => item.id === initial);
|
|
selectDestinationItem(initial_item);
|
|
}
|
|
|
|
document.addEventListener("click", function (event) {
|
|
// Check if the click is outside the dropdownSearch input and dropdownMenu
|
|
if (
|
|
!dropdownSearch.contains(event.target) &&
|
|
!dropdownMenu.contains(event.target)
|
|
) {
|
|
dropdown.hide();
|
|
}
|
|
});
|
|
|
|
items.forEach((item) => {
|
|
// First, order the resolutions by width
|
|
var resolutions = item.base_content.resolutions.sort(
|
|
(a, b) => a.width - b.width
|
|
);
|
|
|
|
// Then take the first object as thumbnail
|
|
item.img = resolutions[0].file;
|
|
|
|
const element = document.createElement("button");
|
|
element.classList.add("dropdown-item");
|
|
element.innerHTML = `<img src="${item.img}" alt="${item.title}"><span class="dropdown-item-text">${item.title}</span>`;
|
|
element.onclick = function () {
|
|
selectDestinationItem(item);
|
|
dropdown.hide();
|
|
};
|
|
dropdownMenu.appendChild(element);
|
|
|
|
dropdownSearch.addEventListener("keyup", function () {
|
|
const searchValue = dropdownSearch.value.toLowerCase();
|
|
const filteredItems = items.filter((item) =>
|
|
item.title.toLowerCase().includes(searchValue)
|
|
);
|
|
|
|
// Clear existing items
|
|
dropdownMenu.innerHTML = "";
|
|
|
|
// Repopulate dropdown with filtered items
|
|
filteredItems.forEach((item) => {
|
|
const element = document.createElement("button");
|
|
element.classList.add("dropdown-item");
|
|
element.innerHTML = `<img src="${item.img}" alt="${item.title}"> ${item.title}`;
|
|
element.onclick = function () {
|
|
selectDestinationItem(item);
|
|
dropdown.hide();
|
|
};
|
|
dropdownMenu.appendChild(element);
|
|
});
|
|
if (filteredItems.length) {
|
|
dropdown.show();
|
|
} else {
|
|
dropdown.hide();
|
|
}
|
|
});
|
|
});
|
|
|
|
dropdownSearch.addEventListener("click", function (event) {
|
|
dropdown.show();
|
|
});
|
|
}
|
|
|
|
export { populateDestinationDropdown };
|