ADD peer counter for websocket - simple indicator in green #12

This commit is contained in:
Caffeine Fueled 2026-03-02 22:01:03 +01:00
parent 1d961690ec
commit ab94c23f2d
Signed by: cf7
GPG key ID: CA295D643074C68C

14
app.py
View file

@ -145,6 +145,7 @@ HTML = """<!doctype html>
#status { font-size:.9rem; opacity:.7; margin-left:.5rem; } #status { font-size:.9rem; opacity:.7; margin-left:.5rem; }
#status::before { content: "●"; margin-right: .3rem; color: #ef4444; } #status::before { content: "●"; margin-right: .3rem; color: #ef4444; }
#status.connected::before { color: #22c55e; } #status.connected::before { color: #22c55e; }
#peers { font-size:.95rem; font-weight:bold; margin-left:.5rem; margin-right:.3rem; color:#22c55e; display:none; }
#wrap { display:grid; grid-template-columns: max-content 1fr; border:1px solid #ddd; border-radius:4px; overflow:hidden; #wrap { display:grid; grid-template-columns: max-content 1fr; border:1px solid #ddd; border-radius:4px; overflow:hidden;
flex: 1; } flex: 1; }
#gutter, #t { font: 14px/var(--line-h) ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; } #gutter, #t { font: 14px/var(--line-h) ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }
@ -179,7 +180,7 @@ HTML = """<!doctype html>
</style> </style>
<header> <header>
<div> <div>
<strong id="padname"></strong><span id="status">disconnected</span> <strong id="padname"></strong><span id="peers"></span><span id="status">disconnected</span>
</div> </div>
<div style="position:relative; display:flex; align-items:center; gap:.25rem;"> <div style="position:relative; display:flex; align-items:center; gap:.25rem;">
<button id="copy" onclick="copyToClipboard()">Copy</button> <button id="copy" onclick="copyToClipboard()">Copy</button>
@ -332,6 +333,7 @@ function connect(){
if (msg.type === "init") { if (msg.type === "init") {
isProtected = !!msg.protected; isProtected = !!msg.protected;
updateLockBtn(); updateLockBtn();
if (msg.peers !== undefined) { const el = $("#peers"); el.textContent = msg.peers; el.style.display = "inline"; }
if (isProtected && !isAuthed) { if (isProtected && !isAuthed) {
showOverlay(); showOverlay();
} else { } else {
@ -354,6 +356,10 @@ function connect(){
ta.value = msg.text; ver = msg.ver; updateGutter(); ta.value = msg.text; ver = msg.ver; updateGutter();
ta.selectionStart = Math.min(s, ta.value.length); ta.selectionStart = Math.min(s, ta.value.length);
ta.selectionEnd = Math.min(e, ta.value.length); ta.selectionEnd = Math.min(e, ta.value.length);
} else if (msg.type === "peers_changed") {
const el = $("#peers");
el.textContent = msg.count;
el.style.display = "inline";
} else if (msg.type === "protected_changed") { } else if (msg.type === "protected_changed") {
isProtected = msg.protected; isProtected = msg.protected;
updateLockBtn(); updateLockBtn();
@ -363,6 +369,7 @@ function connect(){
ws.onclose = () => { ws.onclose = () => {
$("#status").textContent = "disconnected"; $("#status").textContent = "disconnected";
$("#status").classList.remove("connected"); $("#status").classList.remove("connected");
$("#peers").style.display = "none";
}; };
} }
$("#newpad").addEventListener("click", (e) => { e.preventDefault(); location.href = "/" + rand() + "/"; }); $("#newpad").addEventListener("click", (e) => { e.preventDefault(); location.href = "/" + rand() + "/"; });
@ -607,6 +614,9 @@ async def ws(doc_id: str, ws: WebSocket):
# Update access time # Update access time
update_room_access_time(doc_id) update_room_access_time(doc_id)
# Notify all peers of updated count
await _broadcast(doc_id, {"type": "peers_changed", "count": len(room["peers"])})
# Per-connection auth state: already authed if pad has no password # Per-connection auth state: already authed if pad has no password
authed = room["pw_hash"] is None authed = room["pw_hash"] is None
@ -616,6 +626,7 @@ async def ws(doc_id: str, ws: WebSocket):
"text": room["text"] if authed else "", "text": room["text"] if authed else "",
"ver": room["ver"], "ver": room["ver"],
"protected": room["pw_hash"] is not None, "protected": room["pw_hash"] is not None,
"peers": len(room["peers"]),
})) }))
try: try:
while True: while True:
@ -685,6 +696,7 @@ async def ws(doc_id: str, ws: WebSocket):
pass pass
finally: finally:
room["peers"].discard(ws) room["peers"].discard(ws)
await _broadcast(doc_id, {"type": "peers_changed", "count": len(room["peers"])})
# Decrement connection count for this IP # Decrement connection count for this IP
connections_per_ip[client_ip] = max(0, connections_per_ip[client_ip] - 1) connections_per_ip[client_ip] = max(0, connections_per_ip[client_ip] - 1)