diff options
| author | historia <[not public]> | 2026-07-03 18:36:55 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-03 18:36:55 -0400 |
| commit | 0dfd7bf19e800b67e03726c18cfa00e623d6b121 (patch) | |
| tree | 19297eb5cee6b29dd01136f00889a01a99520374 /internal/admin/static | |
| parent | 034187d1c434b6bee32aeb539ea543f6ec537376 (diff) | |
| download | thehouseoficarus-0dfd7bf19e800b67e03726c18cfa00e623d6b121.tar.gz | |
fix: admin gui map screen works with rooms across multiple directories
Diffstat (limited to 'internal/admin/static')
| -rw-r--r-- | internal/admin/static/map.js | 210 |
1 files changed, 124 insertions, 86 deletions
diff --git a/internal/admin/static/map.js b/internal/admin/static/map.js index 95bde7e..6acec47 100644 --- a/internal/admin/static/map.js +++ b/internal/admin/static/map.js @@ -17,8 +17,83 @@ var gridDirs = [ var saveTimer = null; var upTarget = {}, downTarget = {}; +var _mapMouseCleanup = false; + +function onMapMouseMove(e) { + if (!dragging) return; + var moved = Math.abs(e.clientX - startX) >= 4 || Math.abs(e.clientY - startY) >= 4; + + if (delFromId && moved && !delDrag) { delDrag = true; } + if (delDrag && moved) { updateDelDragTarget(e); return; } + + if (!dragRoom && !delDrag && !delFromId) { + panX += e.clientX - prevX; + panY += e.clientY - prevY; + prevX = e.clientX; prevY = e.clientY; + updateView(); + } + + if (linkFromId && moved) { + linkDrag = true; + updateLinkDragTarget(e); + } +} + +function onMapMouseUp(e) { + if (!dragging) return; + document.removeEventListener('mousemove', onMapMouseMove); + document.removeEventListener('mouseup', onMapMouseUp); + _mapMouseCleanup = false; + + var moved = Math.abs(e.clientX - startX) >= 4 || Math.abs(e.clientY - startY) >= 4; + + if (delFromId && !delDrag && !moved) { + showRoomContextMenu(startX, startY, delFromId); + clearDelHighlight(); + dragging = false; dragRoom = false; delFromId = null; delTargetId = null; delDrag = false; + return; + } + + if (delDrag && delFromId && delTargetId) { + deleteLink(delFromId, delTargetId); + clearDelHighlight(); + dragging = false; dragRoom = false; delDrag = false; delFromId = null; delTargetId = null; + return; + } + + if (linkDrag && linkFromId) { + if (linkTargetId) { createLink(linkFromId, linkTargetId); } + else if (linkGhostDir) { createRoom(linkFromId, linkGhostDir); } + } else if (!moved && !delDrag) { + if (e.target.classList.contains('rm')) { + selectRoom(parseInt(e.target.getAttribute('data-id'))); + } else if (e.target.classList.contains('ghost')) { + createRoom(selectedRoom, e.target.getAttribute('data-dir')); + } + } + + clearLinkHighlight(); + clearDelHighlight(); + dragging = false; dragRoom = false; + linkDrag = false; linkFromId = null; linkTargetId = null; linkGhostDir = null; + delDrag = false; delFromId = null; delTargetId = null; +} + +function cancelMapDrag() { + if (!dragging) return; + document.removeEventListener('mousemove', onMapMouseMove); + document.removeEventListener('mouseup', onMapMouseUp); + _mapMouseCleanup = false; + clearLinkHighlight(); + clearDelHighlight(); + dragging = false; dragRoom = false; + linkDrag = false; linkFromId = null; linkTargetId = null; linkGhostDir = null; + delDrag = false; delFromId = null; delTargetId = null; +} + function changeZ(dz) { if (dz === 0) currentZ = 0; else currentZ += dz; + panX = 0; panY = 0; scale = 1; loadMap(); } @@ -26,6 +101,7 @@ function changeDir(dir) { currentDir = dir; dirChangedByUser = true; selectedRoom = null; + panX = 0; panY = 0; scale = 1; loadMap(); } @@ -49,10 +125,14 @@ function loadMap() { dirChangedByUser = false; return API.get(url).then(function(data) { mapData = data; + var dirUpdated = false; if (!currentDir && data.dir) { currentDir = data.dir; + dirUpdated = true; + } + if (dirUpdated || wasDirChange) { + updateDirSelect(); } - updateDirSelect(); renderMap(data); renderDisconnectedList(data); if (wasDirChange && data.seed) { @@ -191,6 +271,9 @@ function renderMap(data) { prevX = e.clientX; prevY = e.clientY; dragRoom = true; linkFromId = null; linkDrag = false; linkTargetId = null; linkGhostDir = null; clearLinkHighlight(); + document.addEventListener('mousemove', onMapMouseMove); + document.addEventListener('mouseup', onMapMouseUp); + _mapMouseCleanup = true; return; } @@ -213,72 +296,9 @@ function renderMap(data) { linkGhostDir = null; delDrag = false; delFromId = null; delTargetId = null; clearLinkHighlight(); - }; - - svg.onmousemove = function(e) { - if (!dragging) return; - var moved = Math.abs(e.clientX - startX) >= 4 || Math.abs(e.clientY - startY) >= 4; - - if (delFromId && moved && !delDrag) { - delDrag = true; - } - if (delDrag && moved) { - updateDelDragTarget(e); - return; - } - - if (!dragRoom && !delDrag && !delFromId) { - panX += e.clientX - prevX; - panY += e.clientY - prevY; - prevX = e.clientX; prevY = e.clientY; - updateView(); - } - - if (linkFromId && moved) { - linkDrag = true; - updateLinkDragTarget(e); - } - }; - - svg.onmouseup = function(e) { - if (!dragging) return; - - var moved = Math.abs(e.clientX - startX) >= 4 || Math.abs(e.clientY - startY) >= 4; - - if (delFromId && !delDrag && !moved) { - showRoomContextMenu(startX, startY, delFromId); - clearDelHighlight(); - dragging = false; dragRoom = false; delFromId = null; delTargetId = null; delDrag = false; - return; - } - - if (delDrag && delFromId && delTargetId) { - deleteLink(delFromId, delTargetId); - clearDelHighlight(); - dragging = false; dragRoom = false; delDrag = false; delFromId = null; delTargetId = null; - return; - } - - if (linkDrag && linkFromId) { - if (linkTargetId) { - createLink(linkFromId, linkTargetId); - } else if (linkGhostDir) { - createRoom(linkFromId, linkGhostDir); - } - } else if (!moved && !delDrag) { - if (e.target.classList.contains('rm')) { - selectRoom(parseInt(e.target.getAttribute('data-id'))); - } else if (e.target.classList.contains('ghost')) { - var dir = e.target.getAttribute('data-dir'); - createRoom(selectedRoom, dir); - } - } - - clearLinkHighlight(); - clearDelHighlight(); - dragging = false; dragRoom = false; - linkDrag = false; linkFromId = null; linkTargetId = null; linkGhostDir = null; - delDrag = false; delFromId = null; delTargetId = null; + document.addEventListener('mousemove', onMapMouseMove); + document.addEventListener('mouseup', onMapMouseUp); + _mapMouseCleanup = true; }; svg.onwheel = function(e) { @@ -337,19 +357,8 @@ function selectRoom(id) { var prev = selectedRoom; selectedRoom = id; - if (mapData && roomMap) { - if (prev && prev !== id) { - var prevEl = document.querySelector('.rm[data-id="'+prev+'"]'); - if (prevEl) { - prevEl.setAttribute('stroke', prevEl.getAttribute('fill') || '#3a3a6a'); - prevEl.setAttribute('stroke-width', '1.5'); - } - } - var el = document.querySelector('.rm[data-id="'+id+'"]'); - if (el) { - el.setAttribute('stroke', '#fff'); - el.setAttribute('stroke-width', '3'); - } + if (mapData && prev !== id) { + renderMap(mapData); } API.get('/api/rooms/' + id).then(function(data) { @@ -360,6 +369,7 @@ function selectRoom(id) { } var currentRoomData = null; +var lastDcDir = null; function renderSidePanel(data) { var panel = $('#panelContent'); @@ -406,9 +416,15 @@ function renderSidePanel(data) { if (ci) ci.addEventListener('input', function() { autoSave(); }); } loadRoomDirs(function(dirs) { + var current = getRoomDirFromFile(file); + var areaSel = $('#dirSelect'); + if (areaSel && current) { + areaSel.value = current; + loadDisconnectedRooms(current); + } + var sel = $('#roomDir'); if (!sel) return; - var current = getRoomDirFromFile(file); sel.innerHTML = ''; dirs.forEach(function(d) { var opt = document.createElement('option'); @@ -1329,7 +1345,8 @@ function mouseToGrid(e) { var rect = svgEl.getBoundingClientRect(); var mx = e.clientX - rect.left; var my = e.clientY - rect.top; - if (mx < 0 || my < 0 || mx > rect.width || my > rect.height) return null; + mx = Math.max(0, Math.min(mx, rect.width - 1)); + my = Math.max(0, Math.min(my, rect.height - 1)); var vb = svgEl.getAttribute('viewBox'); if (!vb) return null; var parts = vb.split(' '); @@ -1461,9 +1478,15 @@ function createLink(fromId, toId) { API.post('/api/rooms/link', {from: fromId, to: toId}).then(function() { notify('Linked rooms #'+fromId+' '+toId, 'success'); updateUndoBar(); - loadMap().then(function() { - if (selectedRoom) selectRoom(selectedRoom); - }); + if (mapData && mapData.rooms) { + var fr = mapData.rooms.find(function(r) { return r.id === fromId; }); + var tr = mapData.rooms.find(function(r) { return r.id === toId; }); + if (fr && tr) { + mapData.links = mapData.links || []; + mapData.links.push({from: fromId, to: toId, dir: gridDeltaToDir(tr.x - fr.x, tr.y - fr.y) || '', bidirectional: true}); + renderMap(mapData); + } + } }).catch(function(e) { notify('Link failed: ' + e.message, 'error'); }); @@ -1554,7 +1577,12 @@ function deleteLink(fromId, toId) { }).then(function() { notify('Removed link #'+fromId+' '+toId, 'success'); updateUndoBar(); - loadMap(); + if (mapData && mapData.links) { + mapData.links = mapData.links.filter(function(l) { + return !((l.from === fromId && l.to === toId) || (l.from === toId && l.to === fromId)); + }); + renderMap(mapData); + } }).catch(function(e) { notify('Delete link failed: ' + e.message, 'error'); }); @@ -1579,6 +1607,16 @@ function renderDisconnectedList(data) { }).join(''); } +function loadDisconnectedRooms(dir) { + if (dir === lastDcDir) return; + lastDcDir = dir; + var url = '/api/map?z=' + currentZ; + if (dir) url += '&dir=' + encodeURIComponent(dir); + API.get(url).then(function(data) { + renderDisconnectedList(data); + }); +} + function showDcContextMenu(e, id) { var overlay = document.createElement('div'); overlay.className = 'cm-overlay'; |
