diff --git a/superchat/include/script.js b/superchat/include/script.js index 35894b2..c1c54c2 100644 --- a/superchat/include/script.js +++ b/superchat/include/script.js @@ -25,6 +25,7 @@ let showChanlist = true; let showNicklist = true; let notificationsEnabled = false; + let fontSize = 14; let reconnectTimer = null; // --- Notification sound (short beep generated via AudioContext) --- @@ -109,6 +110,8 @@ const inputNickEl = document.getElementById('input-nick'); const toggleChanBtn = document.getElementById('toggle-chanlist'); const toggleNickBtn = document.getElementById('toggle-nicklist'); + const fontDecBtn = document.getElementById('font-decrease'); + const fontIncBtn = document.getElementById('font-increase'); // --- Nick colors (LRU cache, 1000 max) --- function hashStr(s) { @@ -268,7 +271,10 @@ updateInputNick(); updateTopicBar(); updateStatusBar(); - inputEl.focus(); + // Don't auto-focus input on mobile + if (window.innerWidth > 600) { + inputEl.focus(); + } } function addMessage(windowName, html, timestamp) { @@ -671,7 +677,7 @@ if (fromNick === nick) { createWindow(chan); - switchWindow(chan); + // Don't auto-switch to prevent force-join spam attacks } else if (windows[chan]) { if (windows[chan].nicks.indexOf(fromNick) === -1) { windows[chan].nicks.push(fromNick); @@ -866,6 +872,30 @@ break; } + case '321': { + // RPL_LISTSTART + addMessage('Status', chatNick('***', '#888') + 'Channel list:', timestamp); + break; + } + + case '322': { + // RPL_LIST - channel info + const chan = p[1]; + const userCount = p[2] || '0'; + const topic = p[3] || ''; + addMessage('Status', chatNick('***', '#888') + + '' + esc(chan) + ' ' + + '(' + esc(userCount) + ') ' + + (topic ? formatIRC(topic) : ''), timestamp); + break; + } + + case '323': { + // RPL_LISTEND + addMessage('Status', chatNick('***', '#888') + 'End of channel list', timestamp); + break; + } + case 'ERROR': addMessage('Status', chatNick('!!!', '#f00') + '' + formatIRC(p[0] || '') + '', timestamp); break; @@ -955,7 +985,15 @@ // Login // ============================================================ function doLogin() { - let n = loginNickEl.value.trim().replace(/[^a-zA-Z0-9_\-\[\]\\^{}|`]/g, '').substring(0, 16); + let n = loginNickEl.value.trim(); + // Remove invalid chars: only alphanumeric, -, _, [, ] + n = n.replace(/[^a-zA-Z0-9_\-\[\]]/g, ''); + // Can't start with a number + if (n && /^[0-9]/.test(n)) { + n = 'Guest' + n; + } + // Limit to 20 chars + n = n.substring(0, 20); if (!n) n = 'WebUser' + Math.floor(Math.random() * 99999); nick = n; loginEl.classList.add('hidden'); @@ -968,7 +1006,13 @@ const params = new URLSearchParams(window.location.search); const urlNick = params.get('nick'); if (urlNick && urlNick.trim()) { - nick = urlNick.trim().replace(/[^a-zA-Z0-9_\-\[\]\\^{}|`]/g, '').substring(0, 16); + let n = urlNick.trim(); + n = n.replace(/[^a-zA-Z0-9_\-\[\]]/g, ''); + if (n && /^[0-9]/.test(n)) { + n = 'Guest' + n; + } + n = n.substring(0, 20); + nick = n; if (nick) { loginEl.classList.add('hidden'); appEl.classList.remove('hidden'); @@ -1001,6 +1045,25 @@ updateNicklistVisibility(); }); + // Font size adjustment + function updateFontSize() { + messagesEl.style.fontSize = fontSize + 'px'; + } + + fontDecBtn.addEventListener('click', function () { + if (fontSize > 10) { + fontSize--; + updateFontSize(); + } + }); + + fontIncBtn.addEventListener('click', function () { + if (fontSize < 24) { + fontSize++; + updateFontSize(); + } + }); + // ============================================================ // Input handling // ============================================================ @@ -1131,6 +1194,10 @@ if (argStr) send(argStr); break; + case 'list': + send('LIST' + (argStr ? ' ' + argStr : '')); + break; + default: send(text.substring(1)); break; diff --git a/superchat/include/style.css b/superchat/include/style.css index 32d8a26..c90072e 100644 --- a/superchat/include/style.css +++ b/superchat/include/style.css @@ -279,6 +279,25 @@ body { display: block; } +.mobile-only { + display: none; +} + +#font-decrease, #font-increase { + color: #555; + cursor: pointer; + -webkit-tap-highlight-color: transparent; + flex-shrink: 0; + padding: 2px 4px; + font-size: 12px; + font-weight: bold; + user-select: none; +} + +#font-decrease:hover, #font-increase:hover { + color: #fff; +} + /* --- Input row --- */ #input-row { display: flex; @@ -402,4 +421,8 @@ body { .timestamp { display: none; } + + .mobile-only { + display: block; + } } diff --git a/superchat/index.html b/superchat/index.html index 2555e2d..568337c 100644 --- a/superchat/index.html +++ b/superchat/index.html @@ -12,7 +12,7 @@