diff options
| author | historia <[not public]> | 2026-06-30 04:43:54 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-30 04:43:54 -0400 |
| commit | 98bdef072c843fdd8ccdf85a9b54ab9d32d34187 (patch) | |
| tree | d4c5c4955ba8e02e895ae0713a2c3439bc93868a /internal/admin/static | |
| parent | 712072209ab5e3b3a14ebc0c770b020afe544560 (diff) | |
| download | thehouseoficarus-98bdef072c843fdd8ccdf85a9b54ab9d32d34187.tar.gz | |
slop refactor
Diffstat (limited to 'internal/admin/static')
| -rw-r--r-- | internal/admin/static/map.js | 184 |
1 files changed, 100 insertions, 84 deletions
diff --git a/internal/admin/static/map.js b/internal/admin/static/map.js index cd53bed..85364d5 100644 --- a/internal/admin/static/map.js +++ b/internal/admin/static/map.js @@ -47,7 +47,7 @@ function loadMap() { if (currentDir) url += '&dir=' + encodeURIComponent(currentDir); var wasDirChange = dirChangedByUser; dirChangedByUser = false; - API.get(url).then(function(data) { + return API.get(url).then(function(data) { mapData = data; if (!currentDir && data.dir) { currentDir = data.dir; @@ -64,11 +64,11 @@ function loadMap() { } function blendColors(colorA, colorB) { + if (!colorA && !colorB) return '#666666'; + if (!colorB) return xtermToCss(parseXtermIdx(colorA)); + if (!colorA) return xtermToCss(parseXtermIdx(colorB)); var idxA = parseXtermIdx(colorA); var idxB = parseXtermIdx(colorB); - if (colorA && !colorB) return xtermToCss(idxA); - if (!colorA && colorB) return xtermToCss(idxB); - if (!colorA && !colorB) return '#666666'; var rgbA = xtermToRGB(idxA); var rgbB = xtermToRGB(idxB); var r = Math.round((rgbA[0] + rgbB[0]) / 2); @@ -90,17 +90,21 @@ function renderMap(data) { var W = container.clientWidth; var H = container.clientHeight; - roomMap = {}; - if (data.rooms) data.rooms.forEach(function(r) { roomMap[r.id] = r; }); - - occupied = {}; - if (data.rooms) data.rooms.forEach(function(r) { occupied[r.x+','+r.y] = r.id; }); - + roomMap = {}; occupied = {}; upTarget = {}; downTarget = {}; - if (data.upLinks) data.upLinks.forEach(function(l) { upTarget[l.from] = l.to; }); - if (data.downLinks) data.downLinks.forEach(function(l) { downTarget[l.from] = l.to; }); + var hasUp = {}, hasDown = {}; + + if (data.rooms) data.rooms.forEach(function(r) { + roomMap[r.id] = r; + occupied[r.x+','+r.y] = r.id; + }); + if (data.upLinks) data.upLinks.forEach(function(l) { + upTarget[l.from] = l.to; hasUp[l.from] = true; + }); + if (data.downLinks) data.downLinks.forEach(function(l) { + downTarget[l.from] = l.to; hasDown[l.from] = true; + }); - var svgNS = 'http://www.w3.org/2000/svg'; var g = ''; if (data.links) { @@ -109,16 +113,11 @@ function renderMap(data) { if (!fr || !tr) return; var x1 = fr.x * CELL + CELL/2, y1 = fr.y * CELL + CELL/2; var x2 = tr.x * CELL + CELL/2, y2 = tr.y * CELL + CELL/2; - var c = blendColors(fr.color, tr.color); - c = c.replace('#',''); + var c = blendColors(fr.color, tr.color).replace('#',''); g += '<line x1="'+x1+'" y1="'+y1+'" x2="'+x2+'" y2="'+y2+'" stroke="#'+c+'" stroke-width="6" opacity="0.55"'+ (l.bidirectional ? '' : ' stroke-dasharray="4,3"')+' vector-effect="non-scaling-stroke"/>'; }); } - var hasUp = {}, hasDown = {}; - if (data.upLinks) data.upLinks.forEach(function(l) { hasUp[l.from] = true; }); - if (data.downLinks) data.downLinks.forEach(function(l) { hasDown[l.from] = true; }); - var roomHTML = ''; if (data.rooms) { data.rooms.forEach(function(r) { @@ -126,7 +125,7 @@ function renderMap(data) { var fill = resolveColor(r.color); var txtColor = hexLuminance(fill) > 0.35 ? '#111' : '#fff'; var sel = selectedRoom === r.id; - roomHTML += '<rect class="rm" x="'+x+'" y="'+y+'" width="'+w+'" height="'+h+'" rx="5" fill="'+fill+'" stroke="'+(sel?'#fff':fill)+'" stroke-width="'+(sel?3:1.5)+'" data-id="'+r.id+'" data-name="'+esc(r.name)+'"/>'; + roomHTML += '<rect class="rm" x="'+x+'" y="'+y+'" width="'+w+'" height="'+h+'" rx="5" fill="'+fill+'" stroke="'+(sel?'#fff':fill)+'" stroke-width="'+(sel?3:1.5)+'" data-id="'+r.id+'"/>'; var dimColor = hexLuminance(fill) > 0.35 ? 'rgba(0,0,0,0.45)' : 'rgba(255,255,255,0.4)'; roomHTML += '<text x="'+(x+w/2)+'" y="'+(y+14)+'" text-anchor="middle" font-size="8" fill="'+dimColor+'" font-family="monospace" pointer-events="none">#'+r.id+'</text>'; @@ -167,7 +166,7 @@ function renderMap(data) { svg.setAttribute('height', H); svg.innerHTML = '<g>' + innerHTML + '</g>'; - svg.addEventListener('contextmenu', function(e) { e.preventDefault(); }); + svg.oncontextmenu = function(e) { e.preventDefault(); }; svg.onmousedown = function(e) { var onRoom = e.target.classList.contains('rm'); @@ -180,9 +179,7 @@ function renderMap(data) { var dz = parseInt(e.target.getAttribute('data-dz')); var tid = parseInt(e.target.getAttribute('data-target')); currentZ += dz; - selectedRoom = tid; - loadMap(); - selectRoom(tid); + loadMap().then(function() { selectRoom(tid); }); return; } @@ -292,7 +289,6 @@ function renderMap(data) { if (scale > 5) scale = 5; updateView(); }; - } function wrapText(name, cx, cy, maxWidth, color) { @@ -338,8 +334,24 @@ function updateView() { function selectRoom(id) { if (saveTimer) { clearTimeout(saveTimer); saveTimer = null; } + var prev = selectedRoom; selectedRoom = id; - loadMap(); + + 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'); + } + } + API.get('/api/rooms/' + id).then(function(data) { renderSidePanel(data); }).catch(function(e) { @@ -443,9 +455,7 @@ function renderHazardTab(r) { } function searchHazards(input) { - searchAndShow(input, 'hazards', function(r) { - addHazard(r.id); - }); + searchAndShow(input, 'hazards', function(r) { addHazard(r.id); }); } function addHazard(id) { if (!currentRoomData || !currentRoomData.room) return; @@ -597,7 +607,6 @@ function renderItemsTab(spawns) { function renderExitsSection(r) { var exits = r.exits || {}; var exitDirs = ['north','south','east','west','northeast','northwest','southeast','southwest','up','down']; - var dirAliases = {n:'north',s:'south',e:'east',w:'west',ne:'northeast',nw:'northwest',se:'southeast',sw:'southwest',u:'up',d:'down'}; var h = '<div class="exit-section"><h3>Exits</h3>'; exitDirs.forEach(function(d) { var exit = exits[d]; @@ -676,7 +685,6 @@ function editExitCondition(dir) { menu._condClauses = parsed.clauses; menu._condMode = parsed.mode; - // Fix: mode is always 'all' for our editor, but store what was parsed renderConditionClauses(menu); } @@ -801,7 +809,6 @@ function saveExitCondition() { exit.set_flags = parseFlagInput(flagsStr ? flagsStr.value : ''); exit.set_player_flags = parseFlagInput(pflagsStr ? pflagsStr.value : ''); - // Update clause data from DOM before saving var clauseEls = menu.querySelectorAll('.cond-clause'); clauseEls.forEach(function(el) { updateClauseData(el); }); @@ -868,8 +875,7 @@ function addExit() { API.post('/api/rooms/link', {from: selectedRoom, to: target, dir: dir}).then(function() { notify('Exit added: ' + dir + ' #' + target, 'success'); updateUndoBar(); - loadMap(); - selectRoom(selectedRoom); + loadMap().then(function() { selectRoom(selectedRoom); }); }).catch(function(e) { notify('Add exit failed: ' + extractError(e), 'error'); }); } @@ -887,8 +893,7 @@ function deleteExit(dir, target) { }).then(function() { notify('Removed exit ' + dir + ' to #' + target, 'success'); updateUndoBar(); - loadMap(); - selectRoom(selectedRoom); + loadMap().then(function() { selectRoom(selectedRoom); }); }).catch(function(e) { notify('Delete exit failed: ' + extractError(e), 'error'); }); } @@ -997,9 +1002,7 @@ function addRefObject(id) { } function searchRefObjects(input) { - searchAndShow(input, 'objects', function(r) { - addRefObject(r.id); - }); + searchAndShow(input, 'objects', function(r) { addRefObject(r.id); }); } function removeSpawn(i) { @@ -1029,9 +1032,7 @@ function addSpawn(id) { } function searchItemSpawns(input) { - searchAndShow(input, 'items', function(r) { - addSpawn(r.id); - }); + searchAndShow(input, 'items', function(r) { addSpawn(r.id); }); } function removeMob(i) { @@ -1049,9 +1050,7 @@ function addMob(id) { } function searchMobs(input) { - searchAndShow(input, 'mobs', function(r) { - addMob(r.id); - }); + searchAndShow(input, 'mobs', function(r) { addMob(r.id); }); } function searchAndShow(input, type, onSelect) { @@ -1112,20 +1111,14 @@ function saveNow() { doSavePanel(); } -function doSavePanel() { +async function doSavePanel() { var id = selectedRoom; if (!id) return; - var save = function(r) { - API.put('/api/rooms/' + id, r).then(function() { - notify('Room #' + id + ' saved', 'success'); - updateUndoBar(); - loadMap(); - }).catch(function(e) { notify('Save failed: '+e.message, 'error'); }); - }; - - API.get('/api/rooms/' + id).then(function(data) { + try { + var data = await API.get('/api/rooms/' + id); var r = data.room || {}; r.id = id; + var el = $('#roomName'); if (el) r.name = el.value; el = $('#roomColor'); if (el) r.color = el.value; el = $('#roomDesc'); if (el && el.value) r.description = [{text: el.value}]; @@ -1140,29 +1133,29 @@ function doSavePanel() { if (r.block_transport === undefined) r.block_transport = currentRoomData.room.block_transport; } - var el = $('#roomID'); var newID = el ? parseInt(el.value) || id : id; + el = $('#roomID'); + var newID = el ? parseInt(el.value) || id : id; var dirEl = $('#roomDir'); var newDir = dirEl ? dirEl.value : null; var currentDir = (data.file || '').replace(/^data\/rooms\/?/, '').split('/')[0] || ''; if (dirEl && newDir !== currentDir) { - API.post('/api/rooms/move', {id: id, dir: newDir}).then(function() { - if (newID !== id) { - API.post('/api/rooms/rename', {id: id, new_id: newID}).then(function() { - selectRoom(newID); - }).catch(function(e) { notify('Rename failed: '+e.message, 'error'); save(r); }); - } else { save(r); } - }).catch(function(e) { notify('Move failed: '+e.message, 'error'); save(r); }); - } else if (newID !== id) { - API.post('/api/rooms/rename', {id: id, new_id: newID}).then(function() { - selectRoom(newID); - }).catch(function(e) { - notify('Rename failed: '+e.message, 'error'); - var rid = $('#roomID'); if (rid) rid.value = id; - save(r); - }); - } else { save(r); } - }).catch(function(e) { notify('Save failed: '+e.message, 'error'); }); + await API.post('/api/rooms/move', {id: id, dir: newDir}); + } + if (newID !== id) { + await API.post('/api/rooms/rename', {id: id, new_id: newID}); + selectedRoom = newID; + id = newID; + } + + await API.put('/api/rooms/' + id, r); + notify('Room #' + id + ' saved', 'success'); + updateUndoBar(); + await loadMap(); + selectRoom(id); + } catch (e) { + notify('Save failed: ' + extractError(e), 'error'); + } } function deleteRoom(id) { @@ -1175,6 +1168,18 @@ function deleteRoom(id) { if (l.to === id && l.from !== id) neighbors.push(l.from); }); } + if (mapData.upLinks) { + mapData.upLinks.forEach(function(l) { + if (l.from === id && l.to !== id) neighbors.push(l.to); + if (l.to === id && l.from !== id) neighbors.push(l.from); + }); + } + if (mapData.downLinks) { + mapData.downLinks.forEach(function(l) { + if (l.from === id && l.to !== id) neighbors.push(l.to); + if (l.to === id && l.from !== id) neighbors.push(l.from); + }); + } if (neighbors.length > 1) { var remaining = mapData.rooms.filter(function(r) { return r.id !== id; }); var adj = {}; @@ -1186,6 +1191,20 @@ function deleteRoom(id) { if (adj[l.to]) adj[l.to].push(l.from); }); } + if (mapData.upLinks) { + mapData.upLinks.forEach(function(l) { + if (l.from === id || l.to === id) return; + if (adj[l.from]) adj[l.from].push(l.to); + if (adj[l.to]) adj[l.to].push(l.from); + }); + } + if (mapData.downLinks) { + mapData.downLinks.forEach(function(l) { + if (l.from === id || l.to === id) return; + if (adj[l.from]) adj[l.from].push(l.to); + if (adj[l.to]) adj[l.to].push(l.from); + }); + } if (remaining.length > 0) { var visited = {}, queue = [remaining[0].id]; visited[remaining[0].id] = true; @@ -1219,7 +1238,7 @@ function createRoom(fromID, dir) { var createdId = (resp && resp.room && resp.room.id) || newID; notify('Room #' + createdId + ' created', 'success'); updateUndoBar(); - selectRoom(createdId); + loadMap().then(function() { selectRoom(createdId); }); }).catch(function(e) { notify('Create failed: ' + e.message, 'error'); }); }); } @@ -1323,7 +1342,7 @@ function applyGhostLinkHighlight(fromRoom, gx, gy) { fromEl.setAttribute('stroke', '#0ff'); fromEl.setAttribute('stroke-width', '3'); - var g = document.querySelector('#mapSvg g'); + var g = document.querySelector('#mapSvg g'); if (!g) return; var svgNS = 'http://www.w3.org/2000/svg'; var line = document.createElementNS(svgNS, 'line'); @@ -1353,7 +1372,7 @@ function applyLinkHighlight(fromId, toId) { toEl.setAttribute('stroke', '#f0f'); toEl.setAttribute('stroke-width', '3'); - var g = document.querySelector('#mapSvg g'); + var g = document.querySelector('#mapSvg g'); if (!g) return; var svgNS = 'http://www.w3.org/2000/svg'; var line = document.createElementNS(svgNS, 'line'); @@ -1393,12 +1412,9 @@ function createLink(fromId, toId) { API.post('/api/rooms/link', {from: fromId, to: toId}).then(function() { notify('Linked rooms #'+fromId+' '+toId, 'success'); updateUndoBar(); - loadMap(); - if (selectedRoom) { - API.get('/api/rooms/' + selectedRoom).then(function(data) { - renderSidePanel(data); - }); - } + loadMap().then(function() { + if (selectedRoom) selectRoom(selectedRoom); + }); }).catch(function(e) { notify('Link failed: ' + e.message, 'error'); }); @@ -1441,7 +1457,7 @@ function applyDelHighlight(fromId, toId) { toEl.setAttribute('stroke', '#f55'); toEl.setAttribute('stroke-width', '3'); - var g = document.querySelector('#mapSvg g'); + var g = document.querySelector('#mapSvg g'); if (!g) return; var svgNS = 'http://www.w3.org/2000/svg'; var line = document.createElementNS(svgNS, 'line'); @@ -1587,7 +1603,7 @@ function escAttr(s) { return String(s).replace(/&/g,'&').replace(/"/g,'"'); } -window.refreshPage = function() { loadMap(); if (selectedRoom) selectRoom(selectedRoom); }; +window.refreshPage = function() { loadMap().then(function() { if (selectedRoom) selectRoom(selectedRoom); }); }; function loadRoomDirs(cb) { API.get('/api/room-dirs').then(function(dirs) { |
