170 lines
7.3 KiB
JavaScript
170 lines
7.3 KiB
JavaScript
import { Styles, createElement } from '../ui_styles.js';
|
|
import { WindowManager } from '../overlays/window_manager.js';
|
|
|
|
export const Visualizers = {
|
|
init(container) {
|
|
const MB = window.MagicBot;
|
|
|
|
this.createLogOverlay();
|
|
|
|
const wrapper = createElement('div', 'margin-top: 10px; border-top: 1px solid #444; padding-top: 10px;');
|
|
|
|
// Logs and HUDs
|
|
const btnRow = createElement('div', 'display: flex; gap: 5px; margin-bottom: 5px;');
|
|
|
|
const btnLogs = createElement('button', Styles.button + 'flex: 1; background: #5c6bc0;', {
|
|
textContent: 'Logs',
|
|
onclick: () => {
|
|
const el = document.getElementById('magic-bot-logs');
|
|
if (el) el.style.display = el.style.display === 'none' ? 'flex' : 'none';
|
|
}
|
|
});
|
|
|
|
const btnState = createElement('button', Styles.button + 'flex: 1; background: #ab47bc;', {
|
|
textContent: 'All HUDs',
|
|
onclick: () => {
|
|
if (window.MagicBot_Overlays) {
|
|
window.MagicBot_Overlays.openAll();
|
|
}
|
|
}
|
|
});
|
|
|
|
btnRow.appendChild(btnLogs);
|
|
btnRow.appendChild(btnState);
|
|
wrapper.appendChild(btnRow);
|
|
|
|
// Individual toggles for specific useful overlays
|
|
const extraRow = createElement('div', 'display: flex; gap: 5px;');
|
|
|
|
const btnPets = createElement('button', Styles.button + 'flex: 1; background: #ffa726; color: #222;', {
|
|
textContent: 'Pets',
|
|
onclick: () => {
|
|
if (window.MagicBot_Overlays && window.MagicBot_Overlays.openPets) {
|
|
window.MagicBot_Overlays.openPets();
|
|
}
|
|
}
|
|
});
|
|
|
|
const btnModel = createElement('button', Styles.button + 'flex: 1; background: #26a69a; color: #eee;', {
|
|
textContent: 'Model',
|
|
onclick: () => {
|
|
if (window.MagicBot_Overlays && window.MagicBot_Overlays.openModel) {
|
|
window.MagicBot_Overlays.openModel();
|
|
}
|
|
}
|
|
});
|
|
|
|
extraRow.appendChild(btnPets);
|
|
extraRow.appendChild(btnModel);
|
|
wrapper.appendChild(extraRow);
|
|
|
|
container.appendChild(wrapper);
|
|
|
|
// Bind Status Indicator
|
|
MB.on('socket_connected', (connected) => {
|
|
const el = document.getElementById('mb-status-ind');
|
|
if (el) {
|
|
el.textContent = connected ? '● Connected' : '● Disconnected';
|
|
el.style.color = connected ? Styles.colors.success : Styles.colors.danger;
|
|
}
|
|
});
|
|
|
|
MB.on('log', (msg) => {
|
|
this.logToOverlay(msg.type, msg.data);
|
|
});
|
|
},
|
|
|
|
createLogOverlay() {
|
|
if (document.getElementById('magic-bot-logs')) return;
|
|
|
|
const logOverlay = createElement('div', `
|
|
display: none;
|
|
position: fixed;
|
|
bottom: 20px;
|
|
left: 20px;
|
|
width: 600px;
|
|
height: 300px;
|
|
background: rgba(10, 10, 15, 0.95);
|
|
border: 1px solid #444;
|
|
border-radius: 8px;
|
|
z-index: 9999999;
|
|
font-family: 'Consolas', 'Monaco', monospace;
|
|
font-size: 11px;
|
|
color: #eee;
|
|
flex-direction: column;
|
|
box-shadow: 0 4px 15px rgba(0,0,0,0.6);
|
|
resize: both;
|
|
overflow: hidden;
|
|
`, { id: 'magic-bot-logs' });
|
|
|
|
logOverlay.innerHTML = `
|
|
<div style="padding: 5px 10px; background: #222; border-bottom: 1px solid #444; display: flex; justify-content: space-between; align-items: center; cursor: move;" id="log-header">
|
|
<span style="font-weight: bold; color: #aaa;">Network Logs</span>
|
|
<div style="display:flex; gap:10px; align-items:center;">
|
|
<input id="log-filter-input" type="text" placeholder="Filter..." style="background:#333; border:1px solid #555; color:#eee; padding:2px 5px; border-radius:3px; font-size:10px; width:100px;">
|
|
<button id="btn-clear-logs" style="background: none; border: none; color: #888; cursor: pointer;">Clear</button>
|
|
<button style="background: none; border: none; color: #ff5252; cursor: pointer;" onclick="this.parentElement.parentElement.parentElement.style.display='none'">X</button>
|
|
</div>
|
|
</div>
|
|
<div id="log-content" style="flex: 1; overflow-y: auto; padding: 5px; word-break: break-all;"></div>
|
|
`;
|
|
|
|
document.body.appendChild(logOverlay);
|
|
|
|
const header = logOverlay.querySelector('#log-header');
|
|
let isDragging = false, offX = 0, offY = 0;
|
|
header.onmousedown = (e) => {
|
|
if (e.target.tagName === 'INPUT' || e.target.tagName === 'BUTTON') return;
|
|
isDragging = true; offX = e.clientX - logOverlay.offsetLeft; offY = e.clientY - logOverlay.offsetTop;
|
|
};
|
|
window.addEventListener('mousemove', (e) => { if (isDragging) { logOverlay.style.left = (e.clientX - offX) + 'px'; logOverlay.style.top = (e.clientY - offY) + 'px'; } });
|
|
window.addEventListener('mouseup', () => isDragging = false);
|
|
|
|
document.getElementById('btn-clear-logs').onclick = () => {
|
|
document.getElementById('log-content').innerHTML = '';
|
|
};
|
|
|
|
// Re-filter on input
|
|
document.getElementById('log-filter-input').addEventListener('input', (e) => {
|
|
const term = e.target.value.toLowerCase();
|
|
const lines = document.getElementById('log-content').children;
|
|
for (let line of lines) {
|
|
line.style.display = line.textContent.toLowerCase().includes(term) ? 'block' : 'none';
|
|
}
|
|
});
|
|
},
|
|
|
|
logToOverlay(type, data) {
|
|
const container = document.getElementById('log-content');
|
|
if (!container) return;
|
|
|
|
const filterInput = document.getElementById('log-filter-input');
|
|
const filterTerm = filterInput ? filterInput.value.toLowerCase() : '';
|
|
|
|
const isAtBottom = (container.scrollHeight - container.scrollTop - container.clientHeight) < 50;
|
|
const line = createElement('div', 'border-bottom: 1px solid #222; padding: 2px 0; cursor: pointer;');
|
|
line.title = 'Click to copy';
|
|
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
const color = type === 'TX' ? Styles.colors.success : Styles.colors.primary;
|
|
let content = data;
|
|
try { if (typeof data === 'string' && (data.startsWith('{') || data.startsWith('['))) content = JSON.stringify(JSON.parse(data)); } catch (e) { }
|
|
|
|
line.innerHTML = `<span style="color: #666;">[${timestamp}]</span> <span style="color: ${color}; font-weight: bold;">${type}</span> <span style="color: #ccc;">${content}</span>`;
|
|
|
|
line.onclick = () => {
|
|
navigator.clipboard.writeText(data);
|
|
line.style.background = 'rgba(255,255,255,0.1)';
|
|
setTimeout(() => line.style.background = 'transparent', 200);
|
|
};
|
|
|
|
if (filterTerm && !line.textContent.toLowerCase().includes(filterTerm)) {
|
|
line.style.display = 'none';
|
|
}
|
|
|
|
container.appendChild(line);
|
|
if (isAtBottom) container.scrollTop = container.scrollHeight;
|
|
if (container.children.length > 500) container.removeChild(container.firstChild);
|
|
}
|
|
};
|