From bf7c27c2cbf3eb56a0a4c5141e39b152c51614b5 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Wed, 1 Jul 2026 04:53:56 -0400 Subject: feat: admin gui map, item, and objects mostly complete --- internal/admin/static/objecteditor.js | 47 ++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'internal/admin/static/objecteditor.js') diff --git a/internal/admin/static/objecteditor.js b/internal/admin/static/objecteditor.js index 13a983e..56894d2 100644 --- a/internal/admin/static/objecteditor.js +++ b/internal/admin/static/objecteditor.js @@ -103,7 +103,7 @@ var SECTIONS = [ }, { id: 'use_interactions', label: 'Use Interactions', path: 'use_interactions', isArray: true, - detect: function(d) { return d.use_interactions && d.use_interactions.length; }, + detect: function(d) { return d.use_interactions && Array.isArray(d.use_interactions); }, fields: [ ['item_id', 'Item ID', 'text'], ['message', 'Message', 'text'], @@ -150,6 +150,7 @@ window.onTalkTreeChange = function(data) { function loadObject(id) { objectID = id; + currentID = id; window.location.hash = id; renderList(''); API.get('/api/objects/' + encodeURIComponent(id)).then(function(data) { @@ -577,6 +578,12 @@ function addSection() { } else { objectData[sec.path] = {}; } + } else if (id === 'steal') { + objectData.steal_table = ''; + objectData.steal_level = 0; + objectData.steal_xp = 0; + objectData.steal_speed = 0; + objectData.guard_mob = ''; } expandedCards[id] = true; renderCurrent(); @@ -683,7 +690,7 @@ function setupSearchFields() { input.addEventListener('input', function() { var val = input.value.trim(); - if (!val) { results.style.display = 'none'; results.innerHTML = ''; return; } + if (!val) { results.style.display = 'none'; results.innerHTML = ''; results._selectedIndex = -1; return; } API.get('/api/search?q=' + encodeURIComponent(val)).then(function(data) { var items = []; if (entityType === 'items' && data.items) items = data.items; @@ -700,6 +707,7 @@ function setupSearchFields() { return '
' + esc(r.id) + ' ' + esc(r.name || '') + '
'; }).join(''); results._items = items; + results._selectedIndex = -1; }).catch(function() { results.style.display = 'none'; }); @@ -714,6 +722,29 @@ function setupSearchFields() { input.addEventListener('blur', function() { setTimeout(function() { results.style.display = 'none'; }, 200); }); + + input.addEventListener('keydown', function(e) { + if (results.style.display === 'none' || !results.children.length) return; + if (results._selectedIndex === undefined) results._selectedIndex = -1; + + if (e.key === 'ArrowDown') { + e.preventDefault(); + results._selectedIndex = Math.min(results._selectedIndex + 1, results.children.length - 1); + updateSearchHighlight(results); + } else if (e.key === 'ArrowUp') { + e.preventDefault(); + results._selectedIndex = Math.max(results._selectedIndex - 1, 0); + updateSearchHighlight(results); + } else if (e.key === 'Enter') { + if (results._selectedIndex >= 0) { + e.preventDefault(); + selectObjSearchResult(results.children[results._selectedIndex]); + } + } else if (e.key === 'Escape') { + results.style.display = 'none'; + results._selectedIndex = -1; + } + }); }); document.addEventListener('click', function(e) { @@ -734,6 +765,13 @@ function selectObjSearchResult(el) { } } +function updateSearchHighlight(results) { + for (var i = 0; i < results.children.length; i++) { + results.children[i].classList.toggle('active', i === results._selectedIndex); + if (i === results._selectedIndex) results.children[i].scrollIntoView({block: 'nearest'}); + } +} + function validateFields() { var errors = []; document.querySelectorAll('.obj-field-error').forEach(function(field) { @@ -974,16 +1012,13 @@ function deleteObject() { notify('Object ' + objectID + ' deleted', 'success'); updateUndoBar(); objectID = null; + currentID = null; objectData = null; $('#editorMain').innerHTML = '

Deleted

'; loadList(); }).catch(function(e) { notify('Delete failed: ' + e.message, 'error'); }); } -// Re-exports for editor.js compatibility -var currentID = null; -Object.defineProperty(window, 'currentID', { get: function() { return objectID; }, set: function(v) { objectID = v; } }); - function loadItem(id) { loadObject(id); } function createNew() { var name = prompt('Object ID:'); -- cgit v1.2.3