feat(chat): add transient presence flash and 5s reconnect grace period
This commit is contained in:
1 parent
4eb88a4594
commit
cef002862e
19 files changed
+299
-37
No files matched your search
+26
-2
@@ -22,6 +22,8 @@ let usersVisible = true;
|
||||
let typingUser = "";
|
||||
let lastTypingSent = 0;
|
||||
let typingTimeout: number | undefined;
|
||||
let flashTimeout: number | undefined;
|
||||
let flashFadeTimeout: number | undefined;
|
||||
const onlineUsers = new Set<string>();
|
||||
|
||||
// Player error recovery state (STREAMING.md contract)
|
||||
@@ -96,20 +98,25 @@ function connectWebSocket(room: string) {
|
||||
return;
|
||||
}
|
||||
hideTyping(msg.username);
|
||||
addMessage(msg.type || "public", msg.text, msg.username, msg.timestamp);
|
||||
|
||||
// Track presence from system join/leave messages
|
||||
// Presence join/leave announcements become transient flashes, not chat rows.
|
||||
if (msg.type === "system" && msg.username === "system") {
|
||||
const joined = msg.text?.match(/^(\S+) joined /);
|
||||
const left = msg.text?.match(/^(\S+) left /);
|
||||
if (joined) {
|
||||
onlineUsers.add(joined[1]);
|
||||
renderPresence();
|
||||
showFlash(`${joined[1]} joined`);
|
||||
return;
|
||||
} else if (left) {
|
||||
onlineUsers.delete(left[1]);
|
||||
renderPresence();
|
||||
showFlash(`${left[1]} left`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
addMessage(msg.type || "public", msg.text, msg.username, msg.timestamp);
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
@@ -142,6 +149,23 @@ function addMessage(type: string, text: string, sender = "", timestamp = new Dat
|
||||
messages.scrollTop = messages.scrollHeight;
|
||||
}
|
||||
|
||||
function showFlash(text: string) {
|
||||
const el = document.getElementById("chat-flash");
|
||||
if (!el) return;
|
||||
el.textContent = text;
|
||||
el.hidden = false;
|
||||
el.classList.remove("fade-out");
|
||||
window.clearTimeout(flashTimeout);
|
||||
window.clearTimeout(flashFadeTimeout);
|
||||
flashTimeout = window.setTimeout(() => {
|
||||
el.classList.add("fade-out");
|
||||
flashFadeTimeout = window.setTimeout(() => {
|
||||
el.hidden = true;
|
||||
el.classList.remove("fade-out");
|
||||
}, 500);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
function renderPresence() {
|
||||
const list = document.getElementById("presence-list");
|
||||
if (!list) return;
|
||||
|
||||
Reference in new issue
Block a user