<html><head> <link rel="stylesheet" type="text/css" href="style.css"> <script src="list.min.js"></script> <script> var entities = {}; var selectedEntities = []; var currentSortColumn = 'type'; var currentSortOrder = 'asc'; var entityList = null; var refreshEntityListTimer = null; var ASC_STRING = ' ▾'; var DESC_STRING = ' ▴'; function loaded() { entityList = new List('entity-list', { valueNames: ['name', 'type', 'url']}); entityList.clear(); elEntityTable = document.getElementById("entity-table"); elEntityTableBody = document.getElementById("entity-table-body"); elRefresh = document.getElementById("refresh"); elDelete = document.getElementById("delete"); elTeleport = document.getElementById("teleport"); elNoEntitiesMessage = document.getElementById("no-entities"); document.getElementById("entity-name").onclick = function() { setSortColumn('name'); }; document.getElementById("entity-type").onclick = function() { setSortColumn('type'); }; document.getElementById("entity-url").onclick = function() { setSortColumn('url'); }; function onRowClicked(e) { var id = this.dataset.entityId; var selection = [this.dataset.entityId]; if (e.shiftKey) { selection = selection.concat(selectedEntities); } selectedEntities = selection; this.className = 'selected'; EventBridge.emitWebEvent(JSON.stringify({ type: "selectionUpdate", focus: false, entityIds: selection, })); } function onRowDoubleClicked() { EventBridge.emitWebEvent(JSON.stringify({ type: "selectionUpdate", focus: true, entityIds: [this.dataset.entityId], })); } function addEntity(id, name, type, url) { if (entities[id] === undefined) { var urlParts = url.split('/'); var filename = urlParts[urlParts.length - 1]; entityList.add([{ id: id, name: name, type: type, url: filename }], function(items) { var el = items[0].elm; var id = items[0]._values.id; entities[id] = { id: id, name: name, el: el, item: items[0], }; el.setAttribute('id', 'entity_' + id); el.setAttribute('title', url); el.dataset.entityId = id; el.onclick = onRowClicked; el.ondblclick = onRowDoubleClicked; }); if (refreshEntityListTimer) { clearTimeout(refreshEntityListTimer); } refreshEntityListTimer = setTimeout(refreshEntityListObject, 50); } else { var item = entities[id].item; item.values({ name: name, url: url }); } } function clearEntities() { entities = {}; entityList.clear(); } var elSortOrder = { name: document.querySelector('#entity-name .sort-order'), type: document.querySelector('#entity-type .sort-order'), url: document.querySelector('#entity-url .sort-order'), } function setSortColumn(column) { if (currentSortColumn == column) { currentSortOrder = currentSortOrder == "asc" ? "desc" : "asc"; } else { elSortOrder[currentSortColumn].style.display = 'none'; elSortOrder[column].style.display = 'inline'; currentSortColumn = column; currentSortOrder = "asc"; } elSortOrder[column].innerHTML = currentSortOrder == "asc" ? ASC_STRING : DESC_STRING; entityList.sort(currentSortColumn, { order: currentSortOrder }); } function refreshEntities() { clearEntities(); EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' })); } function refreshEntityListObject() { refreshEntityListTimer = null; entityList.sort(currentSortColumn, { order: currentSortOrder }); entityList.search(document.getElementById("filter").value); } function updateSelectedEntities(selectedEntities) { var notFound = false; for (var id in entities) { entities[id].el.className = ''; } for (var i = 0; i < selectedEntities.length; i++) { var id = selectedEntities[i]; if (id in entities) { var entity = entities[id]; entity.el.className = 'selected'; } else { notFound = true; } } return notFound; } elRefresh.onclick = function() { refreshEntities(); } elTeleport.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'teleport' })); } elDelete.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); refreshEntities(); } if (window.EventBridge !== undefined) { EventBridge.scriptEventReceived.connect(function(data) { data = JSON.parse(data); if (data.type == "selectionUpdate") { var notFound = updateSelectedEntities(data.selectedIDs); if (notFound) { refreshEntities(); } } else if (data.type == "update") { var newEntities = data.entities; if (newEntities.length == 0) { elEntityTable.style.display = "none"; elNoEntitiesMessage.style.display = "block"; } else { elEntityTable.style.display = "table"; elNoEntitiesMessage.style.display = "none"; for (var i = 0; i < newEntities.length; i++) { var id = newEntities[i].id; addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url); } updateSelectedEntities(data.selectedIDs); } } }); setTimeout(refreshEntities, 1000); } } </script></head><body onload='loaded();'> <div id="entity-list-header"> <input type="button" id="refresh" value="Refresh"></button> <input type="button" id="teleport" value="Teleport"></button> <input type="button" id="delete" style="background-color: rgb(244, 64, 64); float: right" value="Delete"></button> </div> <div id="entity-list"> <div id="search-area"> <input type="text" class="search" id="filter" placeholder="Filter" /> </div> <table id="entity-table"> <thead> <tr> <th id="entity-type" data-sort="type">Type <span class="sort-order" style="display: inline"> ▾</span></th> <th id="entity-name" data-sort="type">Name <span class="sort-order" style="display: inline"> ▾</span></th> <th id="entity-url" data-sort="url">URL <span class="sort-order" style="display: none"> ▾</span></th> </tr> </thead> <tbody class="list" id="entity-table-body"> <tr> <td class="id" style="display: none">Type</td> <td class="type">Type</td> <td class="name">Name</td> <td class="url"><div class='outer'><div class='inner'>URL</div></div></td> </tr> </tbody> </table> </div> <div id="no-entities"> No entities found within 50 meter radius. Try moving to a different location and refreshing. </div></body></html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="list.min.js"></script>
<script>
var entities = {};
var selectedEntities = [];
var currentSortColumn = 'type';
var currentSortOrder = 'asc';
var entityList = null;
var refreshEntityListTimer = null;
var ASC_STRING = ' ▾';
var DESC_STRING = ' ▴';
function loaded() {
entityList = new List('entity-list', { valueNames: ['name', 'type', 'url']});
entityList.clear();
elEntityTable = document.getElementById("entity-table");
elEntityTableBody = document.getElementById("entity-table-body");
elRefresh = document.getElementById("refresh");
elDelete = document.getElementById("delete");
elTeleport = document.getElementById("teleport");
elNoEntitiesMessage = document.getElementById("no-entities");
document.getElementById("entity-name").onclick = function() {
setSortColumn('name');
};
document.getElementById("entity-type").onclick = function() {
setSortColumn('type');
};
document.getElementById("entity-url").onclick = function() {
setSortColumn('url');
};
function onRowClicked(e) {
var id = this.dataset.entityId;
var selection = [this.dataset.entityId];
if (e.shiftKey) {
selection = selection.concat(selectedEntities);
}
selectedEntities = selection;
this.className = 'selected';
EventBridge.emitWebEvent(JSON.stringify({
type: "selectionUpdate",
focus: false,
entityIds: selection,
}));
}
function onRowDoubleClicked() {
EventBridge.emitWebEvent(JSON.stringify({
type: "selectionUpdate",
focus: true,
entityIds: [this.dataset.entityId],
}));
}
function addEntity(id, name, type, url) {
if (entities[id] === undefined) {
var urlParts = url.split('/');
var filename = urlParts[urlParts.length - 1];
entityList.add([{ id: id, name: name, type: type, url: filename }], function(items) {
var el = items[0].elm;
var id = items[0]._values.id;
entities[id] = {
id: id,
name: name,
el: el,
item: items[0],
};
el.setAttribute('id', 'entity_' + id);
el.setAttribute('title', url);
el.dataset.entityId = id;
el.onclick = onRowClicked;
el.ondblclick = onRowDoubleClicked;
});
if (refreshEntityListTimer) {
clearTimeout(refreshEntityListTimer);
}
refreshEntityListTimer = setTimeout(refreshEntityListObject, 50);
} else {
var item = entities[id].item;
item.values({ name: name, url: url });
}
}
function clearEntities() {
entities = {};
entityList.clear();
}
var elSortOrder = {
name: document.querySelector('#entity-name .sort-order'),
type: document.querySelector('#entity-type .sort-order'),
url: document.querySelector('#entity-url .sort-order'),
}
function setSortColumn(column) {
if (currentSortColumn == column) {
currentSortOrder = currentSortOrder == "asc" ? "desc" : "asc";
} else {
elSortOrder[currentSortColumn].style.display = 'none';
elSortOrder[column].style.display = 'inline';
currentSortColumn = column;
currentSortOrder = "asc";
}
elSortOrder[column].innerHTML = currentSortOrder == "asc" ? ASC_STRING : DESC_STRING;
entityList.sort(currentSortColumn, { order: currentSortOrder });
}
function refreshEntities() {
clearEntities();
EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' }));
}
function refreshEntityListObject() {
refreshEntityListTimer = null;
entityList.sort(currentSortColumn, { order: currentSortOrder });
entityList.search(document.getElementById("filter").value);
}
function updateSelectedEntities(selectedEntities) {
var notFound = false;
for (var id in entities) {
entities[id].el.className = '';
}
for (var i = 0; i < selectedEntities.length; i++) {
var id = selectedEntities[i];
if (id in entities) {
var entity = entities[id];
entity.el.className = 'selected';
} else {
notFound = true;
}
}
return notFound;
}
elRefresh.onclick = function() {
refreshEntities();
}
elTeleport.onclick = function() {
EventBridge.emitWebEvent(JSON.stringify({ type: 'teleport' }));
}
elDelete.onclick = function() {
EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' }));
refreshEntities();
}
if (window.EventBridge !== undefined) {
EventBridge.scriptEventReceived.connect(function(data) {
data = JSON.parse(data);
if (data.type == "selectionUpdate") {
var notFound = updateSelectedEntities(data.selectedIDs);
if (notFound) {
refreshEntities();
}
} else if (data.type == "update") {
var newEntities = data.entities;
if (newEntities.length == 0) {
elEntityTable.style.display = "none";
elNoEntitiesMessage.style.display = "block";
} else {
elEntityTable.style.display = "table";
elNoEntitiesMessage.style.display = "none";
for (var i = 0; i < newEntities.length; i++) {
var id = newEntities[i].id;
addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url);
}
updateSelectedEntities(data.selectedIDs);
}
}
});
setTimeout(refreshEntities, 1000);
}
}
</script>
</head>
<body onload='loaded();'>
<div id="entity-list-header">
<input type="button" id="refresh" value="Refresh"></button>
<input type="button" id="teleport" value="Teleport"></button>
<input type="button" id="delete" style="background-color: rgb(244, 64, 64); float: right" value="Delete"></button>
</div>
<div id="entity-list">
<div id="search-area">
<input type="text" class="search" id="filter" placeholder="Filter" />
</div>
<table id="entity-table">
<thead>
<tr>
<th id="entity-type" data-sort="type">Type <span class="sort-order" style="display: inline"> ▾</span></th>
<th id="entity-name" data-sort="type">Name <span class="sort-order" style="display: inline"> ▾</span></th>
<th id="entity-url" data-sort="url">URL <span class="sort-order" style="display: none"> ▾</span></th>
</tr>
</thead>
<tbody class="list" id="entity-table-body">
<tr>
<td class="id" style="display: none">Type</td>
<td class="type">Type</td>
<td class="name">Name</td>
<td class="url"><div class='outer'><div class='inner'>URL</div></div></td>
</tr>
</tbody>
</table>
</div>
<div id="no-entities">
No entities found within 50 meter radius. Try moving to a different location and refreshing.
</div>
</body>
</html>