v10: /color command to reshuffle user colors (web + terminal)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
38
chat.py
38
chat.py
@@ -25,7 +25,7 @@ import html
|
||||
import urllib.parse
|
||||
|
||||
PORT = 9999
|
||||
VERSION = "9"
|
||||
VERSION = "10"
|
||||
TUNNEL_TARGETS = {
|
||||
"parspack": ("185.208.174.152", 22),
|
||||
"mequ": ("188.213.68.133", 2022),
|
||||
@@ -149,13 +149,23 @@ const USER_COLORS = [
|
||||
'#ffb74d', '#aed581', '#f06292', '#4dd0e1'
|
||||
];
|
||||
|
||||
let colorSeed = 0; // bump this to rearrange colors
|
||||
|
||||
function userColor(name) {
|
||||
if (name === $name.value.trim()) return '#4ade80';
|
||||
let h = 0;
|
||||
let h = colorSeed;
|
||||
for (let i = 0; i < name.length; i++) h = ((h << 5) - h + name.charCodeAt(i)) | 0;
|
||||
return USER_COLORS[Math.abs(h) % USER_COLORS.length];
|
||||
}
|
||||
|
||||
function reshuffleColors() {
|
||||
colorSeed = Math.floor(Math.random() * 100000);
|
||||
// re-render all messages
|
||||
const msgs = document.querySelectorAll('.msg');
|
||||
// can't easily re-render, so just note it applies to new messages
|
||||
addMsg({ts: Date.now()/1000, user: '***', text: 'Colors reshuffled!'});
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
const d = document.createElement('div');
|
||||
d.textContent = s;
|
||||
@@ -217,6 +227,13 @@ function send() {
|
||||
const text = $input.value.trimEnd();
|
||||
const name = $name.value.trim() || 'anon';
|
||||
if (!text) return;
|
||||
// Local commands
|
||||
if (text === '/colors' || text === '/color') {
|
||||
reshuffleColors();
|
||||
$input.value = '';
|
||||
$input.style.height = 'auto';
|
||||
return;
|
||||
}
|
||||
fetch('/chat/send', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
@@ -723,6 +740,18 @@ class ChatClient:
|
||||
self.reader: asyncio.StreamReader | None = None
|
||||
self.writer: asyncio.StreamWriter | None = None
|
||||
self.running = True
|
||||
self.color_seed = 0
|
||||
|
||||
def get_color(self, username: str) -> int:
|
||||
"""Color pair for username, affected by color_seed."""
|
||||
if username == "***":
|
||||
return CP_SYSTEM
|
||||
if username == self.name:
|
||||
return CP_MY_NAME
|
||||
h = self.color_seed
|
||||
for c in username:
|
||||
h = ((h << 5) - h + ord(c)) & 0xFFFFFFFF
|
||||
return 10 + (h % len(OTHER_CURSES_COLORS))
|
||||
|
||||
def notify(self, msg: dict):
|
||||
"""Send terminal bell + update title for messages from others."""
|
||||
@@ -742,7 +771,7 @@ class ChatClient:
|
||||
|
||||
def add_message(self, msg: dict):
|
||||
t = time.strftime("%H:%M", time.localtime(msg["ts"]))
|
||||
cp = user_color_pair(msg["user"], self.name)
|
||||
cp = self.get_color(msg["user"])
|
||||
if msg["user"] == "***":
|
||||
self.messages.append((f" {t} {msg['text']}", CP_SYSTEM))
|
||||
elif msg.get("file_id"):
|
||||
@@ -850,6 +879,9 @@ class ChatClient:
|
||||
cmd = self.input_buf.strip()
|
||||
if cmd == "/quit":
|
||||
break
|
||||
elif cmd in ("/color", "/colors"):
|
||||
self.color_seed += 1
|
||||
self.messages.append((" *** Colors reshuffled!", CP_SYSTEM))
|
||||
elif cmd.startswith("/file "):
|
||||
await self.send_file(cmd[6:].strip())
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user