<!DOCTYPE html><!--// more.html//// Created by Keb Helion, February 2020.// Copyright 2020 Vircadia contributors.// Copyright 2022 Overte e.V.//// App maintained in: https://github.com/overte-org/community-apps// App copied to: https://github.com/overte-org/overte////// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html--><html> <head> <meta charset="UTF-8"> <script src="jquery-3.5.1.min.js"></script> <script> //Defaults var NUMBER_OF_RECORDS_PER_LOAD = 20; var loadRecordsUpTo = NUMBER_OF_RECORDS_PER_LOAD; var seachedFieldsFilter = ["name"]; var previousSearch = ""; //Paths var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname; var developmentMode = window.location.toString().split("?")[1]; var rootPath; var metadataScriptSrc = "https://more.overte.org/applications/metadata.js"; if (developmentMode === "dev") { // Development mode loads locally, if not, load from repo. console.info("Setting applications to local.") rootPath = currentPath.replace("more/more.html", "applications/"); console.info("Loading metadata locally."); metadataScriptSrc = "../applications/metadata.js"; } else { console.info("Setting applications to remote URL.") console.info("Loading metadata remotely."); rootPath = "https://more.overte.org/applications/"; } //Search function doSearch() { var keyword = document.getElementById("searchtextbox").value; if (keyword === "") { document.getElementById("clear_search").style.display = "none"; document.getElementById("searchFiltersBar").style.display = "none"; } else { if (document.getElementById("searchFiltersBar").style.display === "none") { seachedFieldsFilter = ["name"]; } document.getElementById("clear_search").style.display = "block"; document.getElementById("searchFiltersBar").style.display = "inline-block"; displaySearchFieldsFilter(); } if (previousSearch !== keyword) { loadRecordsUpTo = NUMBER_OF_RECORDS_PER_LOAD; document.getElementById("list").scrollTop = 0; } listBuilder(keyword, loadRecordsUpTo); previousSearch = keyword; } function clearSearch() { loadRecordsUpTo = NUMBER_OF_RECORDS_PER_LOAD; document.getElementById("searchtextbox").value = ""; doSearch(); } function filterSearchField(targeted) { if (seachedFieldsFilter.indexOf(targeted) === -1) { seachedFieldsFilter.push(targeted); } else { seachedFieldsFilter = removeElementFromArray(seachedFieldsFilter, targeted); } loadRecordsUpTo = NUMBER_OF_RECORDS_PER_LOAD; displaySearchFieldsFilter(); doSearch(); } function removeElementFromArray(arr, value) { return arr.filter(function(ele){ return ele !== value; }); } function displaySearchFieldsFilter() { if (seachedFieldsFilter.indexOf("name") === -1) { document.getElementById("searchFilterName").className = "fieldsSearchFilterOff"; } else { document.getElementById("searchFilterName").className = "fieldsSearchFilterOn"; } if (seachedFieldsFilter.indexOf("description") === -1) { document.getElementById("searchFilterDesc").className = "fieldsSearchFilterOff"; } else { document.getElementById("searchFilterDesc").className = "fieldsSearchFilterOn"; } } //Running scripts var buttonList = []; function requestRunningScriptData() { var readyEvent = { "action": "requestRunningScriptData" }; EventBridge.emitWebEvent(JSON.stringify(readyEvent)); } EventBridge.scriptEventReceived.connect(function(message){ //update the buttons if (message.indexOf("RSL4MOREAPP:") !== -1){ buttonList.forEach(function(item){ var btn = ""; if (message.indexOf(item.url) !== -1) { //Means already running btn = "<button class='uninstall' onclick='uninstall(" + '"' + item.url + '"' + ", " + '"' + item.id + '"' + ");'>Uninstall</button>"; } else { //Means not already installed btn = "<button class='install' onclick='install(" + '"' + item.url + '"' + ", " + '"' + item.id + '"' + ");'>Install</button>"; } document.getElementById(item.id).innerHTML = btn; }); } }); function install(script, btnId){ var btn = "<button class='processing' >Processing...</button>"; document.getElementById(btnId).innerHTML = btn; var readyEvent = { "action": "installScript", "script": script }; EventBridge.emitWebEvent(JSON.stringify(readyEvent)); } function uninstall(script, btnId){ var btn = "<button class='processing' >Processing...</button>"; document.getElementById(btnId).innerHTML = btn; var readyEvent = { "action": "uninstallScript", "script": script }; EventBridge.emitWebEvent(JSON.stringify(readyEvent)); } </script> <link href="css/styles.css" rel="stylesheet"> </head> <body> <div id="header"> <font class="mainTitle">Add more functionalities...</font><br> <div id="search_container"> <input id="searchtextbox" maxlength="40" placeholder = "Search..." onkeyup = "doSearch();"> <span id="clear_search" onclick='clearSearch();'>⮿</span> </div> <div id="searchFiltersBar"> <button title="Name" class='fieldsSearchFilterOn' id='searchFilterName' onClick = 'filterSearchField("name");'>NAME</button> <button title="Description" class='fieldsSearchFilterOff' id='searchFilterDesc' onClick = 'filterSearchField("description");'>DESCRIPTION</button> </div> </div> <div id="list"> <div id="cards"></div> <div id="sidewalk"></div> </div> <div id="footer"> Want to contribute and add your own app?<br> See this repository: <font class="blue">github.com/overte-org/community-apps</font> </div> <script> var pageContent = ""; function displayApp(item) { pageContent = pageContent + "<div class='list_background'></div>"; pageContent = pageContent + "<div class='card'>"; pageContent = pageContent + "<a name = '" + window.btoa(item.directory) + "'><table class='item'><tr class='item'>"; pageContent = pageContent + "<td class='item' style='width: 76px;'><div class='iconContainer'>"; pageContent = pageContent + "<img src='" + rootPath + item.icon + "' style='width:50px;'><br>"; pageContent = pageContent + "<font class = 'caption'>" + item.caption + "</font></div></td>"; var btn = ""; var absoluteJsFile = rootPath + item.jsfile; var btn = "<button class='install' onclick = 'install(" + '"' + absoluteJsFile + " ," + window.btoa(item.directory) + '"' + ");'>Install</button>"; var btndata = { "url": absoluteJsFile, "id": window.btoa(item.directory) }; buttonList.push(btndata); pageContent = pageContent + "<td class='item'><div style='width: 100%; text-align: left; padding: 0px;'><font class='appname'>" + item.name + "<br></font>"; pageContent = pageContent + "<font class = 'appdesc'>" + item.description + "<br></font></div>"; pageContent = pageContent + "<div id = '" + window.btoa(item.directory) + "' align='right'>" + btn + "</div></td>"; pageContent = pageContent + "</tr></table>"; pageContent = pageContent + "</div>"; } function listBuilder(searchKeyword, upTo) { buttonList = []; var counterDisp = 0; var index = 0; var lowItem = ""; var lowDesc = ""; pageContent = ""; var loadMoreRequired = false; for (index = 0; index < metadata.applications.length; index++) { lowItem = metadata.applications[index].name.toLowerCase(); lowDesc = metadata.applications[index].description.toLowerCase(); var query; if (searchKeyword === "") { query = true; } else { query = ((seachedFieldsFilter.indexOf("name") !== -1 && lowItem.indexOf(searchKeyword.toLowerCase()) !== -1)|| (seachedFieldsFilter.indexOf("description") !== -1 && lowDesc.indexOf(searchKeyword.toLowerCase()) !== -1)); } if (query && metadata.applications[index].isActive == true) { displayApp(metadata.applications[index]); counterDisp = counterDisp + 1; if (counterDisp >= upTo) { loadMoreRequired = true; break; } } } if (loadMoreRequired) { pageContent = pageContent + "<div class='list_background'><button id='load_more' onclick = 'loadMore();'>LOAD MORE...</button></div>"; } else { pageContent = pageContent + "<div class='list_background'></div>"; } if (counterDisp > 0 ) { document.getElementById("cards").innerHTML = pageContent; } else { document.getElementById("cards").innerHTML = "<div align='center'><font class='noresult'><br><br><br><br>Sorry, no result found.<br><br><br><br><br><br></font></div>"; } requestRunningScriptData(); } $.getScript(metadataScriptSrc, function(data, textStatus, jqxhr) { doSearch(); }); function loadMore() { loadRecordsUpTo = loadRecordsUpTo + NUMBER_OF_RECORDS_PER_LOAD; doSearch(); } document.getElementById("searchFiltersBar").style.display = "none"; </script> </body></html>
<!DOCTYPE html>
<!--
// more.html
//
// Created by Keb Helion, February 2020.
// Copyright 2020 Vircadia contributors.
// Copyright 2022 Overte e.V.
//
// App maintained in: https://github.com/overte-org/community-apps
// App copied to: https://github.com/overte-org/overte
//
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
-->
<html>
<head>
<meta charset="UTF-8">
<script src="jquery-3.5.1.min.js"></script>
<script>
//Defaults
var NUMBER_OF_RECORDS_PER_LOAD = 20;
var loadRecordsUpTo = NUMBER_OF_RECORDS_PER_LOAD;
var seachedFieldsFilter = ["name"];
var previousSearch = "";
//Paths
var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname;
var developmentMode = window.location.toString().split("?")[1];
var rootPath;
var metadataScriptSrc = "https://more.overte.org/applications/metadata.js";
if (developmentMode === "dev") { // Development mode loads locally, if not, load from repo.
console.info("Setting applications to local.")
rootPath = currentPath.replace("more/more.html", "applications/");
console.info("Loading metadata locally.");
metadataScriptSrc = "../applications/metadata.js";
} else {
console.info("Setting applications to remote URL.")
console.info("Loading metadata remotely.");
rootPath = "https://more.overte.org/applications/";
}
//Search
function doSearch() {
var keyword = document.getElementById("searchtextbox").value;
if (keyword === "") {
document.getElementById("clear_search").style.display = "none";
document.getElementById("searchFiltersBar").style.display = "none";
} else {
if (document.getElementById("searchFiltersBar").style.display === "none") {
seachedFieldsFilter = ["name"];
}
document.getElementById("clear_search").style.display = "block";
document.getElementById("searchFiltersBar").style.display = "inline-block";
displaySearchFieldsFilter();
}
if (previousSearch !== keyword) {
loadRecordsUpTo = NUMBER_OF_RECORDS_PER_LOAD;
document.getElementById("list").scrollTop = 0;
}
listBuilder(keyword, loadRecordsUpTo);
previousSearch = keyword;
}
function clearSearch() {
loadRecordsUpTo = NUMBER_OF_RECORDS_PER_LOAD;
document.getElementById("searchtextbox").value = "";
doSearch();
}
function filterSearchField(targeted) {
if (seachedFieldsFilter.indexOf(targeted) === -1) {
seachedFieldsFilter.push(targeted);
} else {
seachedFieldsFilter = removeElementFromArray(seachedFieldsFilter, targeted);
}
loadRecordsUpTo = NUMBER_OF_RECORDS_PER_LOAD;
displaySearchFieldsFilter();
doSearch();
}
function removeElementFromArray(arr, value) {
return arr.filter(function(ele){
return ele !== value;
});
}
function displaySearchFieldsFilter() {
if (seachedFieldsFilter.indexOf("name") === -1) {
document.getElementById("searchFilterName").className = "fieldsSearchFilterOff";
} else {
document.getElementById("searchFilterName").className = "fieldsSearchFilterOn";
}
if (seachedFieldsFilter.indexOf("description") === -1) {
document.getElementById("searchFilterDesc").className = "fieldsSearchFilterOff";
} else {
document.getElementById("searchFilterDesc").className = "fieldsSearchFilterOn";
}
}
//Running scripts
var buttonList = [];
function requestRunningScriptData() {
var readyEvent = {
"action": "requestRunningScriptData"
};
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
}
EventBridge.scriptEventReceived.connect(function(message){
//update the buttons
if (message.indexOf("RSL4MOREAPP:") !== -1){
buttonList.forEach(function(item){
var btn = "";
if (message.indexOf(item.url) !== -1) {
//Means already running
btn = "<button class='uninstall' onclick='uninstall(" + '"' + item.url + '"' + ", " + '"' + item.id + '"' + ");'>Uninstall</button>";
} else {
//Means not already installed
btn = "<button class='install' onclick='install(" + '"' + item.url + '"' + ", " + '"' + item.id + '"' + ");'>Install</button>";
}
document.getElementById(item.id).innerHTML = btn;
});
}
});
function install(script, btnId){
var btn = "<button class='processing' >Processing...</button>";
document.getElementById(btnId).innerHTML = btn;
var readyEvent = {
"action": "installScript",
"script": script
};
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
}
function uninstall(script, btnId){
var btn = "<button class='processing' >Processing...</button>";
document.getElementById(btnId).innerHTML = btn;
var readyEvent = {
"action": "uninstallScript",
"script": script
};
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
}
</script>
<link href="css/styles.css" rel="stylesheet">
</head>
<body>
<div id="header">
<font class="mainTitle">Add more functionalities...</font><br>
<div id="search_container">
<input id="searchtextbox" maxlength="40" placeholder = "Search..." onkeyup = "doSearch();">
<span id="clear_search" onclick='clearSearch();'>⮿</span>
</div>
<div id="searchFiltersBar">
<button title="Name" class='fieldsSearchFilterOn' id='searchFilterName' onClick = 'filterSearchField("name");'>NAME</button>
<button title="Description" class='fieldsSearchFilterOff' id='searchFilterDesc' onClick = 'filterSearchField("description");'>DESCRIPTION</button>
</div>
</div>
<div id="list">
<div id="cards"></div>
<div id="sidewalk"></div>
</div>
<div id="footer">
Want to contribute and add your own app?<br>
See this repository: <font class="blue">github.com/overte-org/community-apps</font>
</div>
<script>
var pageContent = "";
function displayApp(item) {
pageContent = pageContent + "<div class='list_background'></div>";
pageContent = pageContent + "<div class='card'>";
pageContent = pageContent + "<a name = '" + window.btoa(item.directory) + "'><table class='item'><tr class='item'>";
pageContent = pageContent + "<td class='item' style='width: 76px;'><div class='iconContainer'>";
pageContent = pageContent + "<img src='" + rootPath + item.icon + "' style='width:50px;'><br>";
pageContent = pageContent + "<font class = 'caption'>" + item.caption + "</font></div></td>";
var btn = "";
var absoluteJsFile = rootPath + item.jsfile;
var btn = "<button class='install' onclick = 'install(" + '"' + absoluteJsFile + " ," + window.btoa(item.directory) + '"' + ");'>Install</button>";
var btndata = {
"url": absoluteJsFile,
"id": window.btoa(item.directory)
};
buttonList.push(btndata);
pageContent = pageContent + "<td class='item'><div style='width: 100%; text-align: left; padding: 0px;'><font class='appname'>" + item.name + "<br></font>";
pageContent = pageContent + "<font class = 'appdesc'>" + item.description + "<br></font></div>";
pageContent = pageContent + "<div id = '" + window.btoa(item.directory) + "' align='right'>" + btn + "</div></td>";
pageContent = pageContent + "</tr></table>";
pageContent = pageContent + "</div>";
}
function listBuilder(searchKeyword, upTo) {
buttonList = [];
var counterDisp = 0;
var index = 0;
var lowItem = "";
var lowDesc = "";
pageContent = "";
var loadMoreRequired = false;
for (index = 0; index < metadata.applications.length; index++) {
lowItem = metadata.applications[index].name.toLowerCase();
lowDesc = metadata.applications[index].description.toLowerCase();
var query;
if (searchKeyword === "") {
query = true;
} else {
query = ((seachedFieldsFilter.indexOf("name") !== -1 && lowItem.indexOf(searchKeyword.toLowerCase()) !== -1)||
(seachedFieldsFilter.indexOf("description") !== -1 && lowDesc.indexOf(searchKeyword.toLowerCase()) !== -1));
}
if (query && metadata.applications[index].isActive == true) {
displayApp(metadata.applications[index]);
counterDisp = counterDisp + 1;
if (counterDisp >= upTo) {
loadMoreRequired = true;
break;
}
}
}
if (loadMoreRequired) {
pageContent = pageContent + "<div class='list_background'><button id='load_more' onclick = 'loadMore();'>LOAD MORE...</button></div>";
} else {
pageContent = pageContent + "<div class='list_background'></div>";
}
if (counterDisp > 0 ) {
document.getElementById("cards").innerHTML = pageContent;
} else {
document.getElementById("cards").innerHTML = "<div align='center'><font class='noresult'><br><br><br><br>Sorry, no result found.<br><br><br><br><br><br></font></div>";
}
requestRunningScriptData();
}
$.getScript(metadataScriptSrc, function(data, textStatus, jqxhr) {
doSearch();
});
function loadMore() {
loadRecordsUpTo = loadRecordsUpTo + NUMBER_OF_RECORDS_PER_LOAD;
doSearch();
}
document.getElementById("searchFiltersBar").style.display = "none";
</script>
</body>
</html>