fuzzyworld

north-star / commit

update ui properly when participants are added and dropped

b6dcc91275e780d1c088e20193644547b519f1ec · Pavel Safronov · 2026-03-15 00:50:42 -0700 · parents 500aec9503f4

update ui properly when participants are added and dropped
 src/app.js | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/app.js b/src/app.js
index 068ad78..3a9c63a 100644
--- a/src/app.js
+++ b/src/app.js
@@ -949,7 +949,9 @@ const participantsRef = ref(db, `rooms/${roomId}/participants`);
 //     // update arrows in your UI here
 // });
 const participants = [];
+let participantsSnapshotVersion = 0;
 onValue(participantsRef, async (snapshot) => {
+    const snapshotVersion = ++participantsSnapshotVersion;
     console.debug('Participants data updated:', snapshot.val());
 
     const participantsData = snapshot.val(); // object of uid → participant
@@ -976,10 +978,13 @@ onValue(participantsRef, async (snapshot) => {
             }
             return p; // plaintext fallback for rooms without a key
         }));
+        if (snapshotVersion !== participantsSnapshotVersion) return;
         participants.length = 0;
         participants.push(...decrypted.filter(Boolean));
     } else {
+        if (snapshotVersion !== participantsSnapshotVersion) return;
         console.warn('No participants data');
+        participants.length = 0;
     }
 
     console.debug('Updated participants array:', participants);
@@ -1098,6 +1103,11 @@ const getParticipantsToRender = () => {
 const render = () => {
     const participantsToRender = getParticipantsToRender();
     const content = document.getElementById('content');
+    const activeArrowIds = new Set(
+        participantsToRender
+            .filter(target => target.id !== selfParticipant.id)
+            .map(target => `arrow-${target.id}`)
+    );
 
     // For each participant, calculate the angle from self to the participant, and rotate the arrow accordingly. Also set the color of the arrow to the participant's color.
     // Skip self participant, we don't want to render an arrow for ourselves.
@@ -1162,6 +1172,13 @@ const render = () => {
         }
     }
 
+    // Remove arrows for participants who are no longer present.
+    content.querySelectorAll('.arrow[id^="arrow-"]').forEach((arrowElement) => {
+        if (!activeArrowIds.has(arrowElement.id)) {
+            arrowElement.remove();
+        }
+    });
+
     // set the background color to self color
     document.body.style.backgroundColor = selfParticipant.color;