Chat window is now movable

This commit is contained in:
erik 2025-05-18 11:14:43 +00:00
parent 0313c2a2ae
commit d396942deb
2 changed files with 83 additions and 2 deletions

View file

@ -338,8 +338,12 @@ function initWebSocket() {
// Display or create a chat window for a character // Display or create a chat window for a character
function showChatWindow(name) { function showChatWindow(name) {
if (chatWindows[name]) { if (chatWindows[name]) {
// Restore flex layout when reopening // Restore flex layout when reopening & bring to front
chatWindows[name].style.display = 'flex'; const existing = chatWindows[name];
existing.style.display = 'flex';
if (!window.__chatZ) window.__chatZ = 10000;
window.__chatZ += 1;
existing.style.zIndex = window.__chatZ;
return; return;
} }
const win = document.createElement('div'); const win = document.createElement('div');
@ -380,6 +384,77 @@ function showChatWindow(name) {
win.appendChild(form); win.appendChild(form);
document.body.appendChild(win); document.body.appendChild(win);
chatWindows[name] = win; chatWindows[name] = win;
/* --------------------------------------------------------- */
/* enable dragging of the chat window via its header element */
/* --------------------------------------------------------- */
// keep a static counter so newer windows can be brought to front
if (!window.__chatZ) window.__chatZ = 10000;
let drag = false;
let startX = 0, startY = 0;
let startLeft = 0, startTop = 0;
header.style.cursor = 'move';
// bring to front when interacting
const bringToFront = () => {
window.__chatZ += 1;
win.style.zIndex = window.__chatZ;
};
header.addEventListener('mousedown', e => {
// don't initiate drag when pressing the close button (or other clickable controls)
if (e.target.closest('button')) return;
e.preventDefault();
drag = true;
bringToFront();
startX = e.clientX;
startY = e.clientY;
// current absolute position
startLeft = win.offsetLeft;
startTop = win.offsetTop;
document.body.classList.add('noselect');
});
window.addEventListener('mousemove', e => {
if (!drag) return;
const dx = e.clientX - startX;
const dy = e.clientY - startY;
win.style.left = `${startLeft + dx}px`;
win.style.top = `${startTop + dy}px`;
});
window.addEventListener('mouseup', () => {
drag = false;
document.body.classList.remove('noselect');
});
/* touch support */
header.addEventListener('touchstart', e => {
if (e.touches.length !== 1 || e.target.closest('button')) return;
drag = true;
bringToFront();
const t = e.touches[0];
startX = t.clientX;
startY = t.clientY;
startLeft = win.offsetLeft;
startTop = win.offsetTop;
});
window.addEventListener('touchmove', e => {
if (!drag || e.touches.length !== 1) return;
const t = e.touches[0];
const dx = t.clientX - startX;
const dy = t.clientY - startY;
win.style.left = `${startLeft + dx}px`;
win.style.top = `${startTop + dy}px`;
});
window.addEventListener('touchend', () => {
drag = false;
});
} }
// Append a chat message to the correct window // Append a chat message to the correct window

View file

@ -253,6 +253,7 @@ body {
background: var(--accent); background: var(--accent);
padding: 4px; padding: 4px;
color: #111; color: #111;
cursor: move; /* indicates the header is draggable */
} }
.chat-close-btn { .chat-close-btn {
@ -293,6 +294,11 @@ body {
color: #fff; color: #fff;
outline: none; outline: none;
} }
/* Prevent text selection while dragging chat windows */
body.noselect, body.noselect * {
user-select: none !important;
}
.stat.onlinetime::before { content: "🕑 "} .stat.onlinetime::before { content: "🕑 "}
.stat.deaths::before { content: "💀 "} .stat.deaths::before { content: "💀 "}